一、封装BaseDao

BaseDao

  1. 对数据里面的数据表有增删改查的操作,现在对其进行封装

因为在使用预处理搬运工PreparedStatement的时候,执行sql语句也有重复的代码。

新建一个project

  1. 1.导包mysql.jar
  2. 2.db.properties 直接赋值粘贴
  3. 3.utils下的JdbcUtil 直接赋值粘贴

BaseDao

  1. package com.qfedu.utils;
  2. import com.qfedu.entity.Work;
  3. import org.apache.commons.beanutils.BeanUtils;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.sql.*;
  6. import java.util.ArrayList;
  7. import java.util.List;
  8. /**
  9. * @author wodexinhuai
  10. * @create 2022-04-28-9:43
  11. */
  12. /*
  13. BaseDao下面的两个方法
  14. 1.增删改
  15. 2.查
  16. */
  17. public class BaseDao {
  18. // update 完成同意的增删改方法
  19. // sql 参数化的sql语句
  20. // parameters 给参数化sql中的?赋值
  21. // return int 返回值 受影响的行数
  22. public int update(String sql,Object[] parameters) throws SQLException {
  23. //1.获取连接数据库的对象
  24. Connection connection = JdbcUtil.getConnection();
  25. //2.获取预处理的搬运工对象
  26. PreparedStatement preparedStatement = connection.prepareStatement(sql);
  27. //3.获取参数化sql中?的个数
  28. ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();
  29. int parameterCount = parameterMetaData.getParameterCount();
  30. //循环对?赋值
  31. //if 让程序更加健壮 数组中有值,且参数个数和数组中的个数相等时,才可以赋值
  32. if(parameters != null && parameterCount == parameters.length){
  33. for (int i = 1; i <= parameterCount; i++) {
  34. preparedStatement.setObject(i,parameters[i - 1]);
  35. }
  36. int i = preparedStatement.executeUpdate();
  37. JdbcUtil.close(connection,preparedStatement);
  38. return i;
  39. }
  40. return 0;
  41. }
  42. //查询
  43. //返回值一个list<T>集合
  44. // 三个参数:sql语句、数组、Class<T>对象
  45. public <T> List<T> query(String sql,Object[] parameters,Class<T> tClass) throws Exception{
  46. Connection connection = JdbcUtil.getConnection();
  47. //1.预处理sql语句
  48. PreparedStatement preparedStatement = connection.prepareStatement(sql);
  49. //2.获取参数个数
  50. int parameterCount = preparedStatement.getParameterMetaData().getParameterCount();
  51. if(parameters != null && parameterCount == parameters.length){
  52. for (int i = 1; i <= parameterCount; i++) {
  53. preparedStatement.setObject(i,parameters[i -1]);
  54. }
  55. }
  56. //3.执行查询的sql语句,将查询出来的数据赋值给对象
  57. ResultSet resultSet = preparedStatement.executeQuery();
  58. //4.准备一个List集合
  59. ArrayList<T> list = new ArrayList<>();
  60. //5.获取元数据对象并获得列的个数(字段数)以及名字
  61. ResultSetMetaData metaData = resultSet.getMetaData();
  62. //6.获取列的个数
  63. int columnCount = metaData.getColumnCount();
  64. //7.遍历结果集数据
  65. while (resultSet.next()){
  66. //8.通过第三个参数 Class对象 实例化当对象
  67. //传Work T就是Work
  68. T t = null;
  69. try {
  70. t = tClass.getConstructor(null).newInstance(null);
  71. } catch (Exception e) {
  72. e.printStackTrace();
  73. }
  74. for (int i = 1; i <= columnCount; i++) {
  75. //9.获取列的名字
  76. String columnName = metaData.getColumnName(i);
  77. // System.out.println(columnName);
  78. //10.通过字段获取字段下面的数据
  79. Object value = resultSet.getObject(columnName);
  80. //11.取出来的数据赋值给一个实体类 (类,字段名,字段所对应的值)
  81. BeanUtils.setProperty(t,columnName,value);
  82. }
  83. list.add(t);
  84. }
  85. JdbcUtil.close(connection,preparedStatement,resultSet);
  86. return list.size() != 0 ? list : null;
  87. }
  88. }

测试

  1. package com.qfedu.test1basedao;
  2. import com.qfedu.entity.Work;
  3. import com.qfedu.utils.BaseDao;
  4. import org.junit.jupiter.api.Test;
  5. import java.sql.SQLException;
  6. import java.util.List;
  7. /**
  8. * @author wodexinhuai
  9. * @create 2022-04-28-9:35
  10. */
  11. public class Demo1 extends BaseDao {
  12. // public static void main(String[] args) {
  13. @Test
  14. public void testUpdate() throws SQLException {
  15. String sql = "insert into work(name,age,info) values(?,?,?)";
  16. Object[] objects = {"朱航",2,"是火拳艾斯"};
  17. super.update(sql,objects);
  18. }
  19. @Test
  20. public void testSelect() throws Exception {
  21. String sql = "select * from work where id =?";
  22. Object[] objects = {2};
  23. List<Work> query = super.query(sql, objects, Work.class);
  24. for (Work w1:query
  25. ) {
  26. System.out.println(w1);
  27. }
  28. }
  29. }

二、JDBC连接池

2.1为什么要使用连接池

德鲁伊druid 阿里再用的

之前获取connection对象DriverManager.grtrConnection()方法获取

获取玩以后要进行close()关闭connection资源

每一次执行业务(增删改查),每次都要获取连接,然后在关闭,在获取再关闭

这样操作的话,数据库服务器的压力非常大

使用连接池的功能:

  1. connection连接对象放到一个池子中,这个池子中有很对个连接对象
  2. 在使用connection的时候,去连接数据库获取连接对象,先不关闭close()
  3. 存到池子中,等下一个业务老的时候,直接从池子中取,不用在连接数据库了

2.2使用连接池需要考虑那些问题

数据库的连接池是用来管理数据库的连接资源(connection)对象的,没BaseDao没关系

数据库连接的参数:url use password

连接池对于对象(connection)的管理:

  1. 1.初始化的容量多大
  2. 2.最大容量
  3. 3.等待的时间

常用的连接池有哪些?

  1. 1.C3P0
  2. 2.BDCP
  3. 3.Druid(德鲁伊)

2.3Druid德鲁伊连接池

使用流程

  1. 1.导包 druid-1.1.10.jar
  2. 2.src下面创建druid.properties配置文件
  3. 3.书写连接池的核心类

druid.properties配置文件

  1. driverClassName=com.mysql.jdbc.Driver
  2. url=jdbc:mysql://localhost:3306/java2204?useSSL=false
  3. username=root
  4. password=123456
  5. initialSize=5
  6. maxActive=20
  7. maxWait=2000

使用连接池案例

  1. package com.qfedu.test2druid;
  2. import com.alibaba.druid.pool.DruidDataSourceFactory;
  3. import javax.sql.DataSource;
  4. import java.io.FileInputStream;
  5. import java.io.FileNotFoundException;
  6. import java.sql.Connection;
  7. import java.sql.PreparedStatement;
  8. import java.util.Properties;
  9. /**
  10. * @author wodexinhuai
  11. * @create 2022-04-28-14:47
  12. */
  13. public class Demo1 {
  14. public static void main(String[] args) throws Exception {
  15. Properties properties = new Properties();
  16. properties.load(new FileInputStream("./src/druid.properties"));
  17. //druid核心类
  18. //1.创建一个druid的数据源对象 pool池
  19. DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
  20. //2.使用dataSource对象获取连接对象
  21. Connection connection = dataSource.getConnection();
  22. //增删改查操作
  23. PreparedStatement preparedStatement = connection.prepareStatement("insert into work(name,age,info) values(?,?,?)");
  24. Object[] objects = {"狗",1,"dog"};
  25. for (int i = 1; i <= preparedStatement.getParameterMetaData().getParameterCount(); i++) {
  26. preparedStatement.setObject(i,objects[i -1]);
  27. }
  28. int i = preparedStatement.executeUpdate();
  29. //3.调用close方法,将connection放回连接池
  30. connection.close();
  31. }
  32. }

三、事务的处理

牵涉到数据库的操作

3.2事务的四大特性:ACID

事务的特性 含义
原子性(Atomicity) 事务是一个不可分割的工作单位,事务的操作要么同时发生,要么同时不发生
一致性(Consistency) 事务前后数据的完整性,必须保持一致
隔离性(Isolation) 是指多用户并发访问数据库的时候,一个用户的一个线程不能被其他用户所干扰,不能相互影响
持久性(Durability) 事务一旦被提交,他对数据库里面的数据改变时永久性的,接下来数据库发生故障也不会对提交的数据进行影响