java JDBC 增删改查及封装

亦凉 2022-10-05 14:46 273阅读 0赞

1、插入数据

  1. package com;
  2. import java.sql.*;
  3. public class lxc {
  4. public static void main(String[] args) {
  5. // /useUnicode表示允许使用自定义的Unicode, //characterEncoding是给定自定义的Unicode是什么,解决乱码或问号的问题
  6. String url = "jdbc:mysql://127.0.0.1:3306/java_pro?useUnicode=true&characterEncoding=utf8";
  7. String user = "root";
  8. String password = "lvxingchen@123";
  9. Connection conne = null;
  10. Statement sta = null;
  11. try {
  12. // 注册驱动
  13. Class.forName("com.mysql.jdbc.Driver");
  14. // 获取连接 - 连接mysql数据库
  15. try {
  16. conne = DriverManager.getConnection(url, user, password); // 获取连接对象
  17. sta = conne.createStatement();// createStatement 专门执行sql语句的
  18. String sql = "insert into user(name, age, address) values('吕星辰', 20, '烟台市')";
  19. // 专门执行DML语句的,返回的是影响数据库的数据条数
  20. int count = sta.executeUpdate(sql);
  21. System.out.println(count == 1 ? "插入成功" : "插入失败");
  22. } catch (SQLException throwables) {
  23. throwables.printStackTrace();
  24. } finally {
  25. // 在finally中释放资源,并且按顺序依次关闭
  26. try {
  27. if(sta != null) {
  28. sta.close();
  29. }
  30. } catch (SQLException throwables) {
  31. throwables.printStackTrace();
  32. }
  33. try {
  34. if(conne != null) {
  35. conne.close();
  36. }
  37. } catch (SQLException throwables) {
  38. throwables.printStackTrace();
  39. }
  40. }
  41. } catch (ClassNotFoundException e) {
  42. e.printStackTrace();
  43. }
  44. }
  45. }

2、抽离全局配置

上边我们可以把全局的变量抽离出来,放在properties文件中:

项目目录
db.properties与com同级

2021061008563633.png

db.properties

  1. url=jdbc:mysql://127.0.0.1:3306/java_pro?useUnicode=true&characterEncoding=utf8
  2. user=root
  3. password=lvxingchen@123
  4. driver=com.mysql.jdbc.Driver

在项目文件中引入通过ResourceBundle加载配置文件

  1. package com;
  2. import java.sql.*;
  3. import java.util.ResourceBundle;
  4. public class lxc {
  5. public static void main(String[] args) {
  6. ResourceBundle resourceBundle = ResourceBundle.getBundle("db");
  7. String driver = resourceBundle.getString("driver");
  8. String url = resourceBundle.getString("url");
  9. String user = resourceBundle.getString("user");
  10. String password = resourceBundle.getString("password");
  11. Connection conne = null;
  12. Statement sta = null;
  13. try {
  14. Class.forName(driver);
  15. try {
  16. conne = DriverManager.getConnection(url, user, password); // 获取连接对象
  17. sta = conne.createStatement();// createStatement 专门执行sql语句的
  18. String sql = "insert into user(name, age, address) values('吕星辰', 20, '烟台市')";
  19. int count = sta.executeUpdate(sql);
  20. System.out.println(count == 1 ? "插入成功" : "插入失败");
  21. } catch (SQLException throwables) {
  22. throwables.printStackTrace();
  23. } finally {
  24. try {
  25. sta.close();
  26. } catch (SQLException throwables) {
  27. throwables.printStackTrace();
  28. }
  29. try {
  30. conne.close();
  31. } catch (SQLException throwables) {
  32. throwables.printStackTrace();
  33. }
  34. }
  35. } catch (ClassNotFoundException e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. }

3、java连接数据库封装(以mysql为例)

db.properties 配置文件

  1. // db.properties
  2. url=jdbc:mysql://127.0.0.1:3306/java_pro?useUnicode=true&characterEncoding=utf8
  3. user=root
  4. password=lvxingchen@123
  5. driver=com.mysql.jdbc.Driver

封装JDBCutil.java文件,下边只是简单的封装,查询结果集直接拼接字符串打印的:

  1. package com;
  2. import java.sql.*;
  3. import java.util.ResourceBundle;
  4. /**
  5. * @对外暴露的方法:
  6. * (1)public void login(String name,String password) 账号密码登录
  7. * (2)public void getAll() 获取数据
  8. * (3)public void insert(String name,int age,String address,String password) 插入数据
  9. */
  10. public class JDBCutil {
  11. private final static String url;
  12. private final static String user;
  13. private final static String password;
  14. public Connection driverManager = null; // 获取数据库连接对象
  15. private static JDBCutil jdbc;
  16. // 静态代码块注册驱动 - 在类加载的时候执行一次。
  17. static {
  18. ResourceBundle resourceBundle = ResourceBundle.getBundle("db");
  19. String driver = resourceBundle.getString("driver");
  20. url = resourceBundle.getString("url");
  21. user = resourceBundle.getString("user");
  22. password = resourceBundle.getString("password");
  23. try {
  24. Class.forName(driver); // 注册驱动
  25. jdbc = new JDBCutil();
  26. // jdbc.getConnection(); // 连接数据库,及获取数据库对象
  27. } catch (ClassNotFoundException e) {
  28. e.printStackTrace();
  29. }
  30. }
  31. // 子类会重写父类的main方法,所以父类main方法不会执行!
  32. // public static void main(String[] args) {
  33. // System.out.println("执行了+++++++++++++++++++++++");
  34. // new com.B.JDBCutil().getConnection(); // 连接数据库
  35. // }
  36. // 获取数据库连接对象
  37. private void getConnection() {
  38. try {
  39. jdbc.driverManager = DriverManager.getConnection(url, user, password);
  40. } catch (SQLException throwables) {
  41. throwables.printStackTrace();
  42. System.out.println("连接失败");
  43. }
  44. System.out.println("****************************连接成功************************");
  45. }
  46. // 账号密码登录,成功返回true,失败返回false
  47. public Boolean getOne(String name, String password) {
  48. // Statement statement = null;
  49. PreparedStatement statement = null; // PreparedStatement:预编译的数据库操作对象,可防止SQL注入
  50. ResultSet resultSet = null;
  51. boolean resStatus = false;
  52. try {
  53. System.out.println("jdbc.driverManager:"+jdbc.driverManager);
  54. // 这地方在加一层判断,因为增删改查完之后,会关闭数据库连接
  55. if(jdbc.driverManager == null) {
  56. jdbc.getConnection();
  57. }
  58. /**
  59. * 使用 Statement
  60. * Statement statement = null; // SQL注入
  61. * statement = jdbc.driverManager.createStatement(String sql)
  62. * resultSet = statement.executeQuery();
  63. */
  64. String sq = "select * from java_pro where name = ? and password = ?"; // 提前定义好SQL语句的框架 ?:表示占位符,单引号不能使用单引号括起来!
  65. // 预编译上边的SQL语句
  66. statement = jdbc.driverManager.prepareStatement(sq);
  67. // 给占位符 ? 传值
  68. // 第一个问号下标为1,第二个问号下标是2,以此类推
  69. statement.setString(1, name);
  70. statement.setString(2, password);
  71. // 专门执行查询语句 executeQuery()
  72. resultSet = statement.executeQuery(); // 返回的是一个查询结果集 - 结果集也需要关闭
  73. // 遍历查询结果集:
  74. // resultSet.next() 方法 - 让光标往下移动一行,如果走到的的这一行有数据,则返回true,
  75. // 则把这一行数据分贝取出来即可;继续往下移动下一行;依次循环,如果没数据next() 方法会返回false,停止循环
  76. boolean status = resultSet.next();
  77. int count = 0;
  78. System.out.println("***********************************************************");
  79. if(status) {
  80. resStatus = true;
  81. }
  82. System.out.println("***********************一共"+count+"条数据!************************");
  83. } catch (SQLException throwables) {
  84. throwables.printStackTrace();
  85. }finally {
  86. if(resultSet != null) {
  87. try {
  88. resultSet.close(); // 关闭结果集
  89. } catch (SQLException throwables) {
  90. throwables.printStackTrace();
  91. }
  92. }
  93. if(statement != null) {
  94. try {
  95. statement.close();
  96. } catch (SQLException throwables) {
  97. throwables.printStackTrace();
  98. }
  99. }
  100. // 关闭数据库连接
  101. jdbc.close();
  102. }
  103. return resStatus;
  104. }
  105. // 查询
  106. public void getAll() {
  107. PreparedStatement statement = null;
  108. ResultSet resultSet = null;
  109. try {
  110. System.out.println("jdbc.driverManager:"+jdbc.driverManager);
  111. // 这地方在加一层判断,因为增删改查完之后,会关闭数据库连接
  112. if(jdbc.driverManager == null) {
  113. jdbc.getConnection();
  114. }
  115. String sql = "select * from java_pro";
  116. // 预编译sql语句,防止SQL注入
  117. statement = jdbc.driverManager.prepareStatement(sql);
  118. // 专门执行查询语句 executeQuery()
  119. resultSet = statement.executeQuery(); // 返回的是一个查询结果集 - 结果集也需要关闭
  120. // 遍历查询结果集:
  121. // resultSet.next() 方法 - 让光标往下移动一行,如果走到的的这一行有数据,则返回true,
  122. // 则把这一行数据分贝取出来即可;继续往下移动下一行;依次循环,如果没数据next() 方法会返回false,停止循环
  123. boolean status = resultSet.next();
  124. int count = 0;
  125. System.out.println("***********************************************************");
  126. while(status) {
  127. count ++;
  128. // 取数据
  129. // .getString() 不管数据库里边的数据类型是什么,都以字符串形式返回!getTnt() 取出的是数字类型,别的类型,请查看文档 ··· ···
  130. // .getString(1): 通过下标取数据(注意下边从1开始);
  131. // .getString("name"): 通过列字段取数据;
  132. String name = resultSet.getString("name");
  133. int age = resultSet.getInt("age");
  134. String address = resultSet.getString("address");
  135. System.out.println("查询出的数据结果为:"+name+"-"+age+"-"+address);
  136. status = resultSet.next();
  137. }
  138. System.out.println("***********************一共"+count+"条数据!************************");
  139. } catch (SQLException throwables) {
  140. throwables.printStackTrace();
  141. }finally {
  142. if(resultSet != null) {
  143. try {
  144. resultSet.close(); // 关闭结果集
  145. } catch (SQLException throwables) {
  146. throwables.printStackTrace();
  147. }
  148. }
  149. if(statement != null) {
  150. try {
  151. statement.close();
  152. } catch (SQLException throwables) {
  153. throwables.printStackTrace();
  154. }
  155. }
  156. // 关闭数据库连接
  157. jdbc.close();
  158. }
  159. }
  160. // 插入sql语句执行,暂时无返回数据
  161. public void insert(String name,int age,String address,String password) {
  162. PreparedStatement statement = null;
  163. try {
  164. // 这地方在加一层判断,因为增删改查完之后,会关闭数据库连接
  165. if(jdbc.driverManager == null) {
  166. jdbc.getConnection();
  167. }
  168. String sql = "insert into java_pro (name, age, address, password) values (?, ?, ?, ?)";
  169. // 预编译sql语句,当值sql注入
  170. statement = jdbc.driverManager.prepareStatement(sql);
  171. // 把?替换为用户传过来的参数
  172. statement.setString(1, name);
  173. statement.setInt(2, age);
  174. statement.setString(3, address);
  175. statement.setString(4, password);
  176. // 执行sql语句
  177. int count = statement.executeUpdate();
  178. System.out.println(count == 1 ? "成功" : "失败");
  179. } catch (SQLException throwables) {
  180. throwables.printStackTrace();
  181. }finally {
  182. if(statement != null) {
  183. try {
  184. statement.close();
  185. } catch (SQLException throwables) {
  186. throwables.printStackTrace();
  187. }
  188. }
  189. // 关闭数据库连接
  190. jdbc.close();
  191. }
  192. }
  193. // 关闭数据库连接
  194. private void close() {
  195. try {
  196. if(jdbc.driverManager != null) {
  197. jdbc.driverManager.close();
  198. jdbc.driverManager = null;
  199. }
  200. } catch (SQLException throwables) {
  201. throwables.printStackTrace();
  202. }
  203. }
  204. }

补充:
解决SQL注入的关键问题

用户提供的信息中,即使含有sql语句的关键字,但是这些关键字并没有参与编译,不起作用。
Statment和PreparedStatment对比?

Statment:存在sql注入的问题,编译一次执行一次。
PreparedStatment:解决了sql注入的问题,执行效率较高,编译一次执行N次,它会在编译阶段做类型检查。

发表评论

表情:
评论列表 (有 0 条评论,273人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JDBC增删案例讲解

    JDBC增删改查案例讲解 简介:这是一个网上非常常见的,JDBC的练习题,系统大家通过本文的讲解,熟悉JDBC的增删改查。 推荐学习路线:[JDBC数据库的连接][JD

    相关 JDBC进行增删

    JDBC进行增删改查 本篇博客较为基础,只作学习记录之用。 本篇分为: 下载JDBC的jar包 导入JDBC的jar包 封装数据库连接和关闭