1)传统的JDBC数据库连接使用DriverManager来获取,每次向数据库建立连接都需要将Connection加载到内存中,再验证IP地址、用户名和密码,频繁的进行数据库连接操作将占用非常多的系统资源,容易造成服务器崩溃;
2)数据库连接使用完后都必须断开连接释放资源,如果程序出现异常而未能关闭,将导致数据库内存泄漏,最终导致重启数据库;
3)传统获取连接的方式 不能控制创建的连接数量,如果连接过多也可能导致内存泄漏致使MySQL数据库崩溃;
4)解决传统开发中的数据库连接问题可以采用数据库连接池技术(connection pool)。
1)预先在缓冲池中放入一定数量的链接,当需要建立数据库连接时,只需要从“缓冲池”中取出,使用完毕后再“放回”;
2)数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立;
3)当应用程序向连接池请求的连接数量超过最大连接数量时,这些请求将被加入到等待队列中。
1)从连接池取出连接;
2)使用链接,操作SQL语句;
3)连接放回连接池(程序对连接的引用断开,连接依然可以重复使用)。
如果当前连接都被占用,则新的待连接程序进入等待队列。
1)JDBC的数据库连接池使用 javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由第三方提供实现;
2)C3P0数据库连接池,速度相对较慢但是稳定性比较好(hibernate,spring都采用该连接池);
3)DBCP数据库连接池,速度相对C3P0较快,但稳定性较差;
4)Proxool数据库连接池,有监控链接池状态的功能,稳定性相对于C3P0差一些;
5)BoneCP数据库连接池,速度快;
6)Druid(德鲁伊)是Alibaba提供的数据库连接池,集DBCP、C3P0、Proxool优点于一身的数据库连接池。
- package com.pero.datasource;
-
- import com.mchange.v2.c3p0.ComboPooledDataSource;
- import org.junit.Test;
-
- import java.beans.PropertyVetoException;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.IOException;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.util.Properties;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: C3P0_
- * @date 2022/10/28 22:48
- */
-
- public class C3P0_ {
-
- //使用方法一:在程序中指定相关参数(user、url、password)
- @Test
- public void testC3P0_01() throws IOException, PropertyVetoException, SQLException {
- //1.创建数据源对象
- ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
- //2.通过配置文件mysql.properties获取相关信息
- Properties properties = new Properties();
- properties.load(new FileInputStream("src\\mysql.properties"));
- //3.获取相关属性
- String user = properties.getProperty("user");
- String password = properties.getProperty("password");
- String url = properties.getProperty("url");
- String driver = properties.getProperty("driver");
- //4.给数据源comboPooledDataSource设置相关参数(连接管理交给数据源comboPooledDataSource)
- comboPooledDataSource.setDriverClass(driver); //设置连接数据库驱动
- comboPooledDataSource.setJdbcUrl(url);
- comboPooledDataSource.setUser(user);
- comboPooledDataSource.setPassword(password);
- //5.设置初始化连接数和连接数上限
- comboPooledDataSource.setInitialPoolSize(10); //初始化连接数
- comboPooledDataSource.setMaxPoolSize(50); //连接数上线
- //6.获取链接
- long start = System.currentTimeMillis();
- for (int i = 0; i < 5000; i++) {
- Connection connection = comboPooledDataSource.getConnection();
- connection.close();
- }
- long end = System.currentTimeMillis();
- System.out.println("连接数据库5000次用时:" + (end - start));
- }
-
- //使用方法二:使用配置文件模板来完成
- @Test
- public void testC3P0_02() throws SQLException {
- //1.先导入c3p0-config.xml文件src目录下
- //2.该文件指定了连接数据库和连接池的相关参数
- ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("myc3p0");
- long start = System.currentTimeMillis();
- for (int i = 0; i < 5000; i++) {
- Connection connection = comboPooledDataSource.getConnection();
- connection.close();
- }
- long end = System.currentTimeMillis();
- System.out.println("连接数据库5000次耗时:" + (end - start));
- }
- }
- <c3p0-config>
- <named-config name="myc3p0">
-
-
- <property name="driverClass">com.mysql.jdbc.Driverproperty>
-
- <property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/pero_db01property>
-
- <property name="user">rootproperty>
-
- <property name="password">peroproperty>
-
- <property name="acquireIncrement">5property>
-
- <property name="initialPoolSize">10property>
-
- <property name="minPoolSize">5property>
-
- <property name="maxPoolSize">50property>
-
-
- <property name="maxStatements">5property>
-
-
- <property name="maxStatementsPerConnection">2property>
-
- named-config>
- c3p0-config>
- package com.pero.datasource;
-
- import com.alibaba.druid.pool.DruidDataSourceFactory;
- import org.junit.Test;
- import org.junit.jupiter.api.TestInstance;
-
- import javax.sql.DataSource;
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.IOException;
- import java.sql.Connection;
- import java.util.Properties;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: Druid_
- * @date 2022/10/28 22:57
- */
-
- public class Druid_ {
- //添加Druid的jar包和相关配置文件
- @Test
- public void testDruid() throws Exception {
- //创建properties对象,读取配置文件
- Properties properties = new Properties();
- properties.load(new FileInputStream("src\\druid.properties"));
- //创建指定参数的数据库连接池(德鲁伊连接池)
- DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
- long start = System.currentTimeMillis();
- //建立连接
- for (int i = 0; i < 5000; i++) {
- Connection connection = dataSource.getConnection();
- connection.close();
- }
- long end = System.currentTimeMillis();
- System.out.println("数据库连接耗时:" + (end - start));
- }
- }
- #key=value
- driverClassName=com.mysql.jdbc.Driver
- url=jdbc:mysql://localhost:3306/pero_db01?rewriteBatchedStatements=true
- #url=jdbc:mysql://127.0.0.1:3306/pero_db01
- username=root
- password=pero
- #initial connection size
- initialSize=10
- #min idle connection size
- minIdle=5
- #max active connection size
- maxActive=20
- #max wait time (5000 mil seconds)
- maxWait=5000
- package com.pero.datasource;
-
- import com.alibaba.druid.pool.DruidDataSourceFactory;
- import com.mysql.jdbc.ResultSetRow;
- import com.sun.corba.se.spi.ior.IdentifiableFactory;
-
- import javax.sql.DataSource;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.sql.Connection;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.util.Properties;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: JDBCUtilsByDruid
- * @date 2022/10/29 22:33
- */
-
- public class JDBCUtilsByDruid {
- private static DataSource ds;
-
- //在静态代码块中对ds初始化
- static {
- Properties properties = new Properties();
- try {
- properties.load(new FileInputStream("src\\druid.properties"));
- ds = DruidDataSourceFactory.createDataSource(properties);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- //获取connection
- public static Connection getConnection() throws SQLException {
- return ds.getConnection();
- }
-
- //关闭资源,将连接放回连接池
- public void close(ResultSet resultSet, Statement statement, Connection connection){
- try {
- if (resultSet != null){
- resultSet.close();
- }
- if (statement != null){
- statement.close();
- }
- if (connection != null){
- connection.close();
- }
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
- }
- package com.pero.datasource;
-
- import org.junit.Test;
-
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.Properties;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: JDBCUtilsByDruid_Use
- * @date 2022/10/29 23:30
- */
-
- public class JDBCUtilsByDruid_Use {
- @Test
- public void testUseDruid(){
- Connection connection = null;
- PreparedStatement preparedStatement = null;
- ResultSet resultSet = null;
- String sql = "insert into admin values (?,?)";
-
- try {
- connection = JDBCUtilsByDruid.getConnection(); //com.alibaba.druid.pool.DruidPooledConnection
- preparedStatement = connection.prepareStatement(sql);
- preparedStatement.setString(1,"pero");
- preparedStatement.setInt(2,951357);
- preparedStatement.executeUpdate();
- } catch (SQLException e) {
- throw new RuntimeException(e);
- } finally {
- JDBCUtilsByDruid.close(null,preparedStatement,connection);
- }
- }
-
- @Test
- public void testSelect(){
- Connection connection = null;
- PreparedStatement preparedStatement = null;
- ResultSet resultSet = null;
- String sql = "select * from admin";
-
- try {
- connection = JDBCUtilsByDruid.getConnection();
- preparedStatement = connection.prepareStatement(sql);
- resultSet = preparedStatement.executeQuery();
- while(resultSet.next()){
- String name = resultSet.getString("name");
- int password = resultSet.getInt("password");
- System.out.println(name + "\t" + password);
- }
- } catch (SQLException e) {
- throw new RuntimeException(e);
- } finally {
- JDBCUtilsByDruid.close(resultSet,preparedStatement,connection);
- }
-
- }
- }
1)关闭connection后,resultSet结果集无法使用;
2)resultSet不利于数据管理
3)示意图
MySQL数据库 | ← | java程序 1.得到链接 2.发送SQL指令 | 意义: 相当于将表中的数据信息与ArrayList集合相对应的保存 | |
→ | 返回resultSet 存在问题 1.结果集和connection是关联的,如果关闭连接则不能再使用结果集; 2.结果集不利于数据管理【只能使用一次】; 3.使用返回信息不方便。 | → | 将结果集记录,封装到ArrayList<数据表类名> | |
数据表信息 | ↔ | Java类==>(JavaBean,PoJO,Domain) class Test { //属性 private int id; private String name; ... //无参构造器 //带参构造器 //Getter And Setter } | → | ↑ 一个表数据对象对应一条表记录,表对象放入到ArrayList集合 |
- package com.pero.datasource;
-
- import org.junit.Test;
-
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.ArrayList;
- import java.util.Properties;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: JDBCUtilsByDruid_Use
- * @date 2022/10/29 23:30
- */
-
- public class JDBCUtilsByDruid_Use {
-
- //将ResultSet封装到ArrayList集合中
- @Test
- public void testSelectToArrayList() {
- Connection connection = null;
- PreparedStatement preparedStatement = null;
- ResultSet resultSet = null;
- String sql = "select * from admins";
- ArrayList
adminsArrayList = new ArrayList<>(); - try {
- connection = JDBCUtilsByDruid.getConnection();
- preparedStatement = connection.prepareStatement(sql);
- resultSet = preparedStatement.executeQuery();
- while (resultSet.next()) {
- int id = resultSet.getInt("id");
- String user_name = resultSet.getString("user_name");
- String password = resultSet.getString("password");
- //把得到的resultSet信息封装到Admins对象,然后放入到ArrayList集合中
- Admins admins = new Admins(id, user_name, password);
- adminsArrayList.add(admins);
- }
- for (Admins admins : adminsArrayList) {
- System.out.println(admins.getId() + "\t" + admins.getName() +
- "\t" + admins.getPassword());
- }
- } catch (SQLException e) {
- throw new RuntimeException(e);
- } finally {
- JDBCUtilsByDruid.close(resultSet,preparedStatement,connection);
- }
- //因为ArrayList与connection没有任何关联,该集合可以复用
- //return list;
- }
- }
- package com.pero.datasource;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: Admins
- * @date 2022/10/30 22:02
- */
-
- public class Admins {
- private Integer id;
- private String user_name;
- private String password;
-
- public Admins() { //一定要给一个无参构造器【反射需要】
- }
-
- public Admins(Integer id, String user_name, String password) {
- this.id = id;
- this.user_name = user_name;
- this.password = password;
- }
-
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return user_name;
- }
-
- public void setName(String user_name) {
- this.user_name = user_name;
- }
-
- public String getPassword() {
- return password;
- }
-
- public void setPassword(String password) {
- this.password = password;
- }
-
- @Override
- public String toString() {
- return "Admins{" +
- "id=" + id +
- ", user_name='" + user_name + '\'' +
- ", password='" + password + '\'' +
- '}';
- }
- }
1)commons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的封装,使用dbutils能极大简化jdbc编码的工作量;
1)QueryRunner类:该类封装了SQL的的执行,并且是线程安全的,可实现增删改查、批处理;
2)使用QueryRunner类实现查询;
3)ResultSetHandler接口:该接口用于处理java.sql.ResultSet,将数据按照要求转换为另一种形式。
ArrayHandler: | 把结果集中的第一行数据转换成对象数组; |
ArrayListHandler: | 把结果集中的每一行数据都转成一个数组,再存放到List中; |
BeanHandler: | 将结果集中的第一行数据封装到一个对应的JavaBean实例中; |
BeanListHandler: | 将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List中; |
ColumnListHandler: | 将结果集中某一列的数据存放到List中; |
KeyedHandler(name): | 将结果集中的每一行数据都封装到一个Map里(List |
MapHandler: | 将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值; |
MapListHandler: | 将结果集中的每一行数据都封装到一个Map中,然后再存放到List中; |
ScalarHandler: | 获取结果集中第一行数据指定列的值,常用来进行单值查询。 |
- package com.pero.datasource;
-
- import org.apache.commons.dbutils.QueryRunner;
- import org.apache.commons.dbutils.handlers.BeanHandler;
- import org.apache.commons.dbutils.handlers.BeanListHandler;
- import org.apache.commons.dbutils.handlers.ScalarHandler;
- import org.junit.Test;
-
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.util.List;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: DBUtils_USE
- * @date 2022/10/31 16:52
- */
-
- public class DBUtils_USE {
-
- //使用apache-DBUtils 工具类 + druid完成对表的crud操作
- @Test
- //使用apache-dbUtils + druid查询多条语句
- public void testQueryMany() throws SQLException { //返回结果为多行数据
- //获取链接
- Connection connection = JDBCUtilsByDruid.getConnection();
- String sql = "select * from admins where id >= ?";
- //使用DBUtils类和接口,先引入DBUtils相关jar文件,并导入到该项目中
- //创建QueryRunner
- QueryRunner queryRunner = new QueryRunner();
- //使用queryRunner对象的方法返回ArrayList结果集
- //query()方法通过连接并执行sql语句,得到一个结果集ResultSet并封装到ArrayList集合中,并返回集合
- //connection:连接;
- // sql:执行的sql语句;
- //BeanListHandler查询多条语句
- //new BeanListHandler<>(Admins.class):将ResultSet取出存放到Admins对象中然后封装到ArrayList中
- //Admins.class:底层利用反射机制查看Admins类中有哪些属性,来进行封装操作;
- //1:该位置是可变形参,可以传入多个参数,该参数是给sql语句中的?赋值;
- //ResultSet和PrepareStatement会在query()方法中进行了关闭
- List
query = - queryRunner.query(connection, sql, new BeanListHandler<>(Admins.class), 1);
- for (Admins admins : query) {
- System.out.println(admins);
- }
- //释放资源
- JDBCUtilsByDruid.close(null,null,connection);
- }
-
- @Test
- //使用apache-dbUtils + druid查询一条语句
- public void testQuerySingle() throws SQLException {
- Connection connection = JDBCUtilsByDruid.getConnection();
- String sql = "select * from admins where id = ?";
- QueryRunner queryRunner = new QueryRunner();
- //查询单行记录,返回单个对象,使用的Handler是BeanHandler
- Admins query =
- queryRunner.query(connection, sql, new BeanHandler<>(Admins.class), 1);
- System.out.println(query);
- JDBCUtilsByDruid.close(null,null,connection);
- }
-
- //使用apache-dbUtils + druid 查询单行单列-返回一个Object对象
- @Test
- public void testScalar() throws SQLException {
- Connection connection = JDBCUtilsByDruid.getConnection();
- QueryRunner queryRunner = new QueryRunner();
- String sql = "select user_name from admins where id = ?";
- Object object = queryRunner.query(connection, sql, new ScalarHandler<>(), 3);
- System.out.println(object);
- JDBCUtilsByDruid.close(null,null,connection);
- }
-
- //使用apache-dbUtils + druid 完成DML(delete、insert、update)
- @Test
- public void testDML() throws SQLException {
- Connection connection = JDBCUtilsByDruid.getConnection();
- QueryRunner queryRunner = new QueryRunner();
- String sql_update = "update admins set password = ? where user_name = ?";
- String sql_insert = "insert into admins values (null,?,?)";
- String sql_delete = "delete from admins where id = ?";
- //执行DML操作调用queryRunner的update()方法,返回值为受影响的行数
- //int affectedRow = queryRunner.update(connection, sql_update, 213546, "jack0");
- //int affectedRow01 = queryRunner.update(connection, sql_insert, "lucy", 123456);
- int affectedRow02 = queryRunner.update(connection, sql_delete, 5);
- //System.out.println(affectedRow > 0 ? "成功" : "执行没有影响到表");
- //System.out.println(affectedRow01 > 0 ? "执行成功" : "执行没有影响到表");
- System.out.println(affectedRow02 > 0 ? "执行成功" : "执行结果没有影响到表");
- JDBCUtilsByDruid.close(null,null,connection);
- }
- }
- private
T query(Connection conn/*连接对象*/, boolean closeConn/*是否关闭连接*/, String sql/*sql命令*/, ResultSetHandler rsh/*结果集的对象的集合*/, Object... params/*sql命令中对应?位置的值*/) throws SQLException { -
- if (conn == null) { //判断传入的连接对象是否为null,如果为null抛出Null connection连接异常
- throw new SQLException("Null connection");
- } else if (sql == null) { //判断语句是否为空,如果为空则进行下一组判断
- if (closeConn) { //判断closeConn是否为true,如果为true则关闭连接
- this.close(conn);
- }
-
- throw new SQLException("Null SQL statement"); //抛出Null SQL statement异常
- } else if (rsh == null) { //判断接收的集合对象是否为null
- if (closeConn) { //判断closeConn是否为true,如果为true则关闭连接
- this.close(conn);
- }
-
- throw new SQLException("Null ResultSetHandler"); //抛出Null ResultSetHandler异常
- } else {
- PreparedStatement stmt = null; //定义preparedStatement、ResultSet、T引用
- ResultSet rs = null;
- T result = null;
-
- try {
- stmt = this.prepareStatement(conn, sql); //将preparedStatement对象传给stmt
- this.fillStatement(stmt, params); //将params的值赋值给预处理对象stat中sql语句的问号
- rs = this.wrap(stmt.executeQuery()); //执行sql语句返回结果集,并将结果集resultSet对象经过处理后传给rs
- result = rsh.handle(rs); //将结果集经过处理(使用到了反射机制获取Admins类中的信息对结果集进行封装)传入rsh(ArrayList集合)并指向result引用
- } catch (SQLException var33) {
- this.rethrow(var33, sql, params); //异常抛出
- } finally { //资源关闭
- try {
- this.close(rs);
- } finally {
- this.close(stmt);
- if (closeConn) {
- this.close(conn);
- }
-
- }
- }
-
- return result; //返回结果
- }
- }
int,double等类型在Java中都必须用包装类,因为mysql中的所有类型都可能是null,而Java中只有引用类型才有null值;
表 | JavaBean |
int(11) | Integer |
varchar(32),char(1) | String |
double | Double |
date | Date |
apache-dbutils + Druid 虽然简化了JDBC开发,但依旧存在着不足:
1)SQL语句是固定的,不能通过参数传入,通用性不足,进行改进以便更好执行增删改查命令;
2)对于select操作,如果有返回值,则返回类型不能固定,需要使用泛型;
3)对于众多的数据表和复杂的业务需求,不可能只靠一个Java类来完成;
4)BasicDAO示意图:
TestDAO 1.根据业务需求使用对应的DAO; 2.职能划分各司其职,业务设计清晰。 | ||
调↓用 | ||
AppView 1.界面层; 2.调用service层的相关类,得到结果显示数据。 | ||
调↓用 | ||
ActorService/GoodsService/OrderService 1.业务层; 2.组织sql命令,并调用相应的XxxDAO,完成综合需求。 | ||
调↓用 | ||
DAO BasicDAO 1.将各类DAO共同的代码归类到BasicDAO; 2.简化代码,提高维护性和可读性。 | ||
继↑承 | ||
ActorDAO 完成对actor表的增删改查操作 可以有特有操作 | GoodsDAO 完成对goods表的增删改查操作 可以有特有操作 | OrderDAO 完成对order表的增删改查操作 可以有特有操作 |
操↓作 | 操↓作 | 操↓作 |
MySQL | ||
actor表 | goods表 | order表 |
关↑联 | 关↑联 | 关↑联 |
JavaBean | ||
Actor类 [JavaBean,domain,pojo] | Goods类 [JavaBean,domain,pojo] | Order类 [JavaBean,domain,pojo] |
1)通用类BasicDAO是专门与数据库交互的,用以完成对数据库(表)的增删改查操作;
2)在BasicDAO的基础上实现一张表对应一个DAO,例如Actor表-Actor.java类(JavaBean)-ActorDAO.java。
1)创建com.pero.dao_包;
2)在com.pero.dao_包下创建utils工具包,存放工具类;
JDBCUtilsByDruid类
- package com.pero.dao_.utils;
-
- import com.alibaba.druid.pool.DruidDataSourceFactory;
-
- import javax.sql.DataSource;
- import java.io.FileInputStream;
- import java.sql.Connection;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.util.Properties;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: JDBCUtilsByDruid
- * @date 2022/10/29 22:33
- */
-
- public class JDBCUtilsByDruid {
- private static DataSource ds;
-
- //在静态代码块中对ds初始化
- static {
- Properties properties = new Properties();
- try {
- properties.load(new FileInputStream("src\\druid.properties"));
- ds = DruidDataSourceFactory.createDataSource(properties);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- //获取connection
- public static Connection getConnection() throws SQLException {
- return ds.getConnection();
- }
-
- //关闭资源,将连接放回连接池
- public static void close(ResultSet resultSet, Statement statement, Connection connection){
- try {
- if (resultSet != null){
- resultSet.close();
- }
- if (statement != null){
- statement.close();
- }
- if (connection != null){
- connection.close();
- }
- } catch (SQLException e) {
- throw new RuntimeException(e);
- }
- }
- }
3)在com.pero.dao_包下创建domain包,存放JavaBean文件;
Actor类
- package com.pero.dao_.domain;
-
- import java.util.Date;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: Actor
- * @date 2022/11/5 17:25
- */
-
- public class Actor {
-
- /**
- * 数据库中actor表的列属性
- */
- private Integer id;
- private String name;
- private String sex;
- private Date date;
- private Integer phone;
-
- /**
- * 空构造器,方便反射使用
- */
- public Actor() {
- }
-
- /**
- * 全属性构造器
- */
- public Actor(Integer id, String name, String sex, Date date, Integer phone) {
- this.id = id;
- this.name = name;
- this.sex = sex;
- this.date = date;
- this.phone = phone;
- }
-
- /**
- * Setter and Getter
- */
- public Integer getId() {
- return id;
- }
-
- public void setId(Integer id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getSex() {
- return sex;
- }
-
- public void setSex(String sex) {
- this.sex = sex;
- }
-
- public Date getDate() {
- return date;
- }
-
- public void setDate(Date date) {
- this.date = date;
- }
-
- public Integer getPhone() {
- return phone;
- }
-
- public void setPhone(Integer phone) {
- this.phone = phone;
- }
-
- /**
- * toString
- */
- @Override
- public String toString() {
- return "Actor{" +
- "id=" + id +
- ", name='" + name + '\'' +
- ", sex='" + sex + '\'' +
- ", date=" + date +
- ", phone=" + phone +
- '}';
- }
- }
4)在com.pero.dao_包下创建dao包,存放XxxDAO和BasicDAO类;
BasicDAO类
- package com.pero.dao_.dao;
-
- import com.pero.datasource.JDBCUtilsByDruid;
- import org.apache.commons.dbutils.QueryRunner;
- import org.apache.commons.dbutils.handlers.BeanHandler;
- import org.apache.commons.dbutils.handlers.BeanListHandler;
- import org.apache.commons.dbutils.handlers.ScalarHandler;
-
- import javax.lang.model.element.VariableElement;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.util.List;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: BasicDAO
- * @date 2022/11/5 17:48
- */
-
- public class BasicDAO
{ //指定具体类型 -
- private QueryRunner queryRunner = new QueryRunner();
- Connection connection = null;
-
- /*
- * 功能描述: <增删改操作>
- * <>
- * @Param: [sql,parameters]
- * @Return: int
- * @Author: pero
- * @Date: 2022/11/6 12:41
- */
- public int update(String sql, Object...parameters){
-
- try {
- connection = JDBCUtilsByDruid.getConnection();
- int update = queryRunner.update(connection,sql, parameters);
- return update;
- } catch (SQLException e) {
- throw new RuntimeException(e);
- } finally {
- JDBCUtilsByDruid.close(null,null,connection);
- }
- }
-
- /*
- * 功能描述: <返回多个对象(多行查询结果),针对任意表>
- *
- * @Param: [sql, clazz, parameters]
- * @Return: java.util.List
- * @Author: pero
- * @Date: 2022/11/5 20:27
- */
- public List
queryMultiply(String sql, Class clazz, Object... parameters) { - try {
- connection = JDBCUtilsByDruid.getConnection();
- return queryRunner.query(connection, sql, new BeanListHandler
(clazz), parameters); - } catch (SQLException e) {
- throw new RuntimeException(e);
- } finally {
- JDBCUtilsByDruid.close(null,null,connection);
- }
- }
-
- /*
- * 功能描述: <查询单行结果>
- *
- * @Param: [sql, clazz, parameters]
- * @Return: T
- * @Author: pero
- * @Date: 2022/11/5 20:45
- */
- public T querySingle(String sql, Class
clazz, Object...parameters) { - try {
- connection = JDBCUtilsByDruid.getConnection();
- return queryRunner.query(connection, sql, new BeanHandler
(clazz), parameters); - } catch (SQLException e) {
- throw new RuntimeException(e);
- } finally {
- JDBCUtilsByDruid.close(null,null,connection);
- }
- }
-
- /*
- * 功能描述: <查询单行单列的方法,返回单值>
- * <>
- * @Param: [sql,parameters]
- * @Return: [Object]
- * @Author: pero
- * @Date: 2022/11/5 20:58
- */
- public Object queryScalar(String sql, Object...parameters){
- try {
- connection = JDBCUtilsByDruid.getConnection();
- return queryRunner.query(connection,sql, new ScalarHandler(), parameters);
- } catch (SQLException e) {
- throw new RuntimeException(e);
- } finally {
- JDBCUtilsByDruid.close(null,null,connection);
- }
- }
- }
ActorDAO类
- package com.pero.dao_.dao;
-
- import com.pero.dao_.domain.Actor;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: ActorDAO
- * @date 2022/11/6 12:53
- */
-
- public class ActorDAO extends BasicDAO
{ - //具有BasicDAO所有的方法
- //根据业务需求编写特有方法
-
- }
5)在com.pero.dao_包下创建test包,存放测试类。
- package com.pero.dao_.test;
-
- import com.pero.dao_.dao.ActorDAO;
- import com.pero.dao_.domain.Actor;
- import org.apache.commons.dbutils.QueryRunner;
- import org.junit.Test;
-
- import java.io.FileInputStream;
- import java.io.FileNotFoundException;
- import java.io.FileReader;
- import java.io.IOException;
- import java.util.List;
- import java.util.Properties;
-
- /**
- * @author Pero
- * @version 1.0
- * @title: TestDAO
- * @date 2022/11/6 12:55
- */
-
- public class TestDAO {
-
- //测试actor表的增删改查操作
- @Test
- /*
- * 功能描述: <多行查询>
- * <>
- * @Param: []
- * @Return: void
- * @Author: pero
- * @Date: 2022/11/6 14:18
- */
- public void testActorSelectForMultiply(){
- ActorDAO actorDAO = new ActorDAO();
- List
actors = - actorDAO.queryMultiply("select * from actor where id > ?", Actor.class, 3);
- for (Actor actor : actors) {
- System.out.println(actor);
- }
- }
-
- @Test
- /*
- * 功能描述: <单行查询>
- * <>
- * @Param: []
- * @Return: void
- * @Author: pero
- * @Date: 2022/11/6 14:26
- */
- public void testActorSelectForSingle(){
- ActorDAO actorDAO = new ActorDAO();
- Actor actor =
- actorDAO.querySingle("select * from actor where id = ?", Actor.class, 5);
- System.out.println(actor);
- }
-
- @Test
- /*
- * 功能描述: <单行单列查询>
- * <>
- * @Param: []
- * @Return: void
- * @Author: pero
- * @Date: 2022/11/6 14:32
- */
- public void testActorSelectForScalar(){
- ActorDAO actorDAO = new ActorDAO();
- Object scalar =
- actorDAO.queryScalar("select name from actor where id = ?", 4);
- System.out.println(scalar);
- }
-
- @Test
- /*
- * 功能描述: <添加数据>
- * <>
- * @Param: []
- * @Return: void
- * @Author: pero
- * @Date: 2022/11/6 18:16
- */
- public void testActorInsertForUpdate() throws IOException {
- ActorDAO actorDAO = new ActorDAO();
- Properties properties = new Properties();
- properties.load(new FileInputStream("src\\actorFile.properties"));
- String name = properties.getProperty("name");
- String sex = properties.getProperty("sex");
- String borndate = properties.getProperty("borndate");
- String phone = properties.getProperty("phone");
- int update =
- actorDAO.update("insert into actor values (null,?,?,?,?)",name,sex,borndate,phone);
- System.out.println(update > 0 ? "数据添加成功" : "添加操作未对数据库表产生影响");
- }
-
- @Test
- /*
- * 功能描述: <修改数据>
- * <>
- * @Param: []
- * @Return: void
- * @Author: pero
- * @Date: 2022/11/6 18:57
- */
- public void testActorUpdateForUpdate() throws IOException {
- ActorDAO actorDAO = new ActorDAO();
- Properties properties = new Properties();
- properties.load(new FileInputStream("src\\actorFile.properties"));
- String name = properties.getProperty("name");
- String sex = properties.getProperty("sex");
- String borndate = properties.getProperty("borndate");
- String phone = properties.getProperty("phone");
- int update =
- actorDAO.update("update actor set name = ?, sex = ?, borndate = ?, phone = ? where id = ?", name, sex, borndate, phone, 5);
- System.out.println(update > 0 ? "修改成功" : "操作语句未对表产生影响");
- }
-
- @Test
- /*
- * 功能描述: <删除指定行数据>
- * <>
- * @Param: []
- * @Return: void
- * @Author: pero
- * @Date: 2022/11/6 19:03
- */
- public void testActorDeleteForUpdate(){
- ActorDAO actorDAO = new ActorDAO();
- int update =
- actorDAO.update("delete from actor where id = ?", 6);
- System.out.println(update > 0 ? "删除成功" : "操作语句未对表产生影响");
- }
- }
actorFile.properties
- name=marry
- sex=woman
- borndate=2002-05-31
- phone=136656326