一、封装BaseDao
BaseDao
对数据里面的数据表有增删改查的操作,现在对其进行封装
因为在使用预处理搬运工PreparedStatement的时候,执行sql语句也有重复的代码。
新建一个project
1.导包mysql.jar2.db.properties 直接赋值粘贴3.utils下的JdbcUtil 直接赋值粘贴
BaseDao
package com.qfedu.utils;import com.qfedu.entity.Work;import org.apache.commons.beanutils.BeanUtils;import java.lang.reflect.InvocationTargetException;import java.sql.*;import java.util.ArrayList;import java.util.List;/*** @author wodexinhuai* @create 2022-04-28-9:43*//*BaseDao下面的两个方法1.增删改2.查*/public class BaseDao {// update 完成同意的增删改方法// sql 参数化的sql语句// parameters 给参数化sql中的?赋值// return int 返回值 受影响的行数public int update(String sql,Object[] parameters) throws SQLException {//1.获取连接数据库的对象Connection connection = JdbcUtil.getConnection();//2.获取预处理的搬运工对象PreparedStatement preparedStatement = connection.prepareStatement(sql);//3.获取参数化sql中?的个数ParameterMetaData parameterMetaData = preparedStatement.getParameterMetaData();int parameterCount = parameterMetaData.getParameterCount();//循环对?赋值//if 让程序更加健壮 数组中有值,且参数个数和数组中的个数相等时,才可以赋值if(parameters != null && parameterCount == parameters.length){for (int i = 1; i <= parameterCount; i++) {preparedStatement.setObject(i,parameters[i - 1]);}int i = preparedStatement.executeUpdate();JdbcUtil.close(connection,preparedStatement);return i;}return 0;}//查询//返回值一个list<T>集合// 三个参数:sql语句、数组、Class<T>对象public <T> List<T> query(String sql,Object[] parameters,Class<T> tClass) throws Exception{Connection connection = JdbcUtil.getConnection();//1.预处理sql语句PreparedStatement preparedStatement = connection.prepareStatement(sql);//2.获取参数个数int parameterCount = preparedStatement.getParameterMetaData().getParameterCount();if(parameters != null && parameterCount == parameters.length){for (int i = 1; i <= parameterCount; i++) {preparedStatement.setObject(i,parameters[i -1]);}}//3.执行查询的sql语句,将查询出来的数据赋值给对象ResultSet resultSet = preparedStatement.executeQuery();//4.准备一个List集合ArrayList<T> list = new ArrayList<>();//5.获取元数据对象并获得列的个数(字段数)以及名字ResultSetMetaData metaData = resultSet.getMetaData();//6.获取列的个数int columnCount = metaData.getColumnCount();//7.遍历结果集数据while (resultSet.next()){//8.通过第三个参数 Class对象 实例化当对象//传Work T就是WorkT t = null;try {t = tClass.getConstructor(null).newInstance(null);} catch (Exception e) {e.printStackTrace();}for (int i = 1; i <= columnCount; i++) {//9.获取列的名字String columnName = metaData.getColumnName(i);// System.out.println(columnName);//10.通过字段获取字段下面的数据Object value = resultSet.getObject(columnName);//11.取出来的数据赋值给一个实体类 (类,字段名,字段所对应的值)BeanUtils.setProperty(t,columnName,value);}list.add(t);}JdbcUtil.close(connection,preparedStatement,resultSet);return list.size() != 0 ? list : null;}}
测试
package com.qfedu.test1basedao;import com.qfedu.entity.Work;import com.qfedu.utils.BaseDao;import org.junit.jupiter.api.Test;import java.sql.SQLException;import java.util.List;/*** @author wodexinhuai* @create 2022-04-28-9:35*/public class Demo1 extends BaseDao {// public static void main(String[] args) {@Testpublic void testUpdate() throws SQLException {String sql = "insert into work(name,age,info) values(?,?,?)";Object[] objects = {"朱航",2,"是火拳艾斯"};super.update(sql,objects);}@Testpublic void testSelect() throws Exception {String sql = "select * from work where id =?";Object[] objects = {2};List<Work> query = super.query(sql, objects, Work.class);for (Work w1:query) {System.out.println(w1);}}}
二、JDBC连接池
2.1为什么要使用连接池
德鲁伊druid 阿里再用的
之前获取connection对象DriverManager.grtrConnection()方法获取
获取玩以后要进行close()关闭connection资源
每一次执行业务(增删改查),每次都要获取连接,然后在关闭,在获取再关闭
这样操作的话,数据库服务器的压力非常大
使用连接池的功能:
把connection连接对象放到一个池子中,这个池子中有很对个连接对象在使用connection的时候,去连接数据库获取连接对象,先不关闭close()存到池子中,等下一个业务老的时候,直接从池子中取,不用在连接数据库了
2.2使用连接池需要考虑那些问题
数据库的连接池是用来管理数据库的连接资源(connection)对象的,没BaseDao没关系
数据库连接的参数:url use password
连接池对于对象(connection)的管理:
1.初始化的容量多大2.最大容量3.等待的时间
常用的连接池有哪些?
1.C3P02.BDCP3.Druid(德鲁伊)
2.3Druid德鲁伊连接池
使用流程
1.导包 druid-1.1.10.jar2.在src下面创建druid.properties配置文件3.书写连接池的核心类
druid.properties配置文件
driverClassName=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/java2204?useSSL=falseusername=rootpassword=123456initialSize=5maxActive=20maxWait=2000
使用连接池案例
package com.qfedu.test2druid;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.sql.Connection;import java.sql.PreparedStatement;import java.util.Properties;/*** @author wodexinhuai* @create 2022-04-28-14:47*/public class Demo1 {public static void main(String[] args) throws Exception {Properties properties = new Properties();properties.load(new FileInputStream("./src/druid.properties"));//druid核心类//1.创建一个druid的数据源对象 pool池DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);//2.使用dataSource对象获取连接对象Connection connection = dataSource.getConnection();//增删改查操作PreparedStatement preparedStatement = connection.prepareStatement("insert into work(name,age,info) values(?,?,?)");Object[] objects = {"狗",1,"dog"};for (int i = 1; i <= preparedStatement.getParameterMetaData().getParameterCount(); i++) {preparedStatement.setObject(i,objects[i -1]);}int i = preparedStatement.executeUpdate();//3.调用close方法,将connection放回连接池connection.close();}}
三、事务的处理
牵涉到数据库的操作
3.2事务的四大特性:ACID
| 事务的特性 | 含义 |
|---|---|
| 原子性(Atomicity) | 事务是一个不可分割的工作单位,事务的操作要么同时发生,要么同时不发生 |
| 一致性(Consistency) | 事务前后数据的完整性,必须保持一致 |
| 隔离性(Isolation) | 是指多用户并发访问数据库的时候,一个用户的一个线程不能被其他用户所干扰,不能相互影响 |
| 持久性(Durability) | 事务一旦被提交,他对数据库里面的数据改变时永久性的,接下来数据库发生故障也不会对提交的数据进行影响 |
