目录
一.封装JDBCUtiles
二.事务
三.批处理
四.数据库连接池
C3P0
Druidf(德鲁伊)阿里
五.Apache-DBUtiles
六.Apache-DBUtils
七.DAO 和增删改查 通用方法 - BasicDao
一.封装JDBCUtiles
说明:在jdbc操作中,获取连接和释放资源,是经常使用到,可以将其封装JDBC连接的,工具类JDBCUtils
package com.tianedu.jdbc.utils;import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;/*** @author tian* 这是一个工具类 完成MySQL的连接和关闭资源**/
public class JDBCUtils {// 定义相关的属性(4个),因为只需要一份,我们做出Staticprivate static String user; // 用户名private static String password; // 密码private static String url; //urlprivate static String driver; //驱动名称//在static 代码块去初始化static {Properties properties = new Properties();try {properties.load(new FileInputStream("src\\mysql.properties"));//读取相关的属性值user = properties.getProperty("user");password = properties.getProperty("password");url = properties.getProperty("url");driver = properties.getProperty("driver");} catch (IOException e) {//在实际开发中,我们可以这样处理//1.将编译异常转换成 运行异常//2.这里调用者可以选择捕获该异常,也可以选择默认异常,比较方便。throw new RuntimeException(e);
// e.printStackTrace();}}
// 连接数据库 返回一个Connectionpublic static Connection getConnection(){try {return DriverManager.getConnection(url,user,password);} catch (SQLException e) {
// throwables.printStackTrace();//将编译异常转换成 运行异常,调用者可以捕获该异常,也可以选择默认处理该异常,比较方便throw new RuntimeException(e);}}//关闭相关的资源/*1.ResultSet 结果集2.Statement 或者 PreparedStatement3.关闭Connection4.如果需要关闭资源,就传入对象,否则传入null*/public static void close(ResultSet set, Statement statement,Connection connection){//判断是否为nulltry {if(set != null){set.close();}if (statement != null) {statement.close();}if (connection != null){connection.close();}} catch (SQLException e) {//将编译异常转成运行异常抛出throw new RuntimeException(e);}}
}
使用工具类 JDBCUtils
package com.tianedu.jdbc.utils;import org.junit.Test;import java.sql.*;/*** @author tian* 该类演示如何使用JDBCUtile工具类完成DML 和 select***/
public class JDBCUtils_Use {public static void main(String[] args) {//测试}@Testpublic void testSelect(){//1.得到连接Connection connection = null;//2.组织一个sqlString sql = "select * from actor where id = ?";//测试 selectPreparedStatement preparedStatement = null;ResultSet set = null;//3.创建PrepareStatement 对象try {connection = JDBCUtils.getConnection();preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,2); // 给问号赋值//执行 得到结果集set = preparedStatement.executeQuery();//遍历该结果集while(set.next()){int id = set.getInt("id");String name = set.getString("name");String sex = set.getString("sex");Date borndate = set.getDate("borndate");String phone = set.getString("phone");System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone );}} catch (SQLException e) {e.printStackTrace();} finally {//关闭资源JDBCUtils.close(set,preparedStatement,connection);}}@Testpublic void testDML() {// insert update delete//1.得到连接Connection connection = null;//2.组织一个sql语句String sql = "update actor set name = ? where id = ?";PreparedStatement preparedStatement = null;//3.创建一个PreparedStatement 对象try {connection = JDBCUtils.getConnection();preparedStatement = connection.prepareStatement(sql);// 给占位符 赋值preparedStatement.setString(1,"周星驰");preparedStatement.setInt(2,1);//执行preparedStatement.executeUpdate();} catch (SQLException e) {e.printStackTrace();} finally {//关闭资源JDBCUtils.close(null,preparedStatement,connection);}}
}
二.事务
应用实例,模拟经典的转账业务
- 不使用事可能出现的问题模拟,模拟经典的转账业务
package com.tianedu.jdbc.transaction_;import com.tianedu.jdbc.utils.JDBCUtils;
import org.junit.Test;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;/*** @author tian* 演示在JDBC中如何使用事务*/
public class Transaction_ {@Testpublic void noTransaction_(){//操作转账的业务//1.得到连接Connection connection = null;//2.组织一个sql语句String sql = "update account set balance = balance -100 where id = 1";String sql2 = "update account set balance = balance + 100 where id = 2";// 创建 PreparedStatement 对象PreparedStatement preparedStatement = null;try {connection = JDBCUtils.getConnection();preparedStatement = connection.prepareStatement(sql);preparedStatement.executeUpdate(); // 执行第一条sql语句int i = 1/0; // 抛出异常 下面的代码不在执行preparedStatement = connection.prepareStatement(sql2);preparedStatement.executeUpdate(); // 执行第二条 sql2 语句} catch (SQLException e) {e.printStackTrace();} finally {JDBCUtils.close(null,preparedStatement,connection);}}// 事务来解决@Testpublic void useTransaction() {//1. 连接事务Connection connection = null;//2.组织sqlString sql = "update account set balance = balance -100 where id = 1";String sql2 = "update account set balance = balance + 100 where id = 2";//3.创建PrepareStatement 对象PreparedStatement preparedStatement = null;try {connection = JDBCUtils.getConnection();// 将connection 设置为不自动提交connection.setAutoCommit(false); //相当于开始事务preparedStatement = connection.prepareStatement(sql);preparedStatement.executeUpdate(); // 执行sqlpreparedStatement = connection.prepareStatement(sql2);preparedStatement.executeUpdate(); //执行sql2//这里提交事务connection.commit();} catch (SQLException e) {//这里我们可以进行回滚,即撤销执行的sql//默认回滚到事务开始的状态System.out.println("执行发生了异常,撤销执行的sql");try {connection.rollback();} catch (SQLException throwables) {throwables.printStackTrace();} finally {}e.printStackTrace();} finally {//关闭资源JDBCUtils.close(null,preparedStatement,connection);}}
}
三.批处理
- 当需要成批插入或者更新记录时。可以采用java 的批处理更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比较单独提交处理更有效率。
- JDBC的批处理语句包括下面方法:addBatch() 添加需要批处理的sql语句或参数 executeBatch() 执行批批量处理的语句 clearBatch() 清空批处理包的语句
- JDBC连接MySQL时,如果需要使用批处理功能,请在url中加参数? rewriteBatchedStatements = true
- 批处理往往和PreparedStatement 一起搭配使用,可以减少编译次数,有减少运行次数,效率大大提高
- 如果要批量处理 需要修改 配置文件 jdbc.properties url=jdbc:mysql://localhost:3306/数据库? rewriteBatchedStatements = true
package com.tianedu.jdbc.batch_;import com.tianedu.jdbc.utils.JDBCUtils;
import org.junit.Test;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;/*** @author tian* 演示Java的批处理*/
public class Batch_ {@Test//传统的方法添五千条数数据到admin2public void noBatch() throws SQLException {//得到连接Connection connection = JDBCUtils.getConnection();//sqlString sql = "insert into admin2 values(null,?,?)";//使用connect创建一个prepareStatement()PreparedStatement preparedStatement = connection.prepareStatement(sql);System.out.println("开始时间");long start = System.currentTimeMillis(); // 开始时间for (int i = 0; i<= 5000; i++){preparedStatement.setString(1,"jack"+i);preparedStatement.setString(2,"666");preparedStatement.executeUpdate();}long end = System.currentTimeMillis();System.out.println("传统的方式 耗时="+ (end - start));//关闭连接JDBCUtils.close(null,preparedStatement,connection);}//使用批量处理方式添加数据@Testpublic void batch() throws SQLException {//获得连接Connection connection = JDBCUtils.getConnection();//写sql语句String sql = "insert into admin3 values(null,?,?)";//获得preparedStatementPreparedStatement preparedStatement = connection.prepareStatement(sql);System.out.println("开始执行");long start = System.currentTimeMillis();for (int i = 0; i < 5000; i++) {preparedStatement.setString(1,"tom+i");preparedStatement.setString(2,"777");// preparedStatement.executeUpdate(); // 执行//将sql语句加入到批处理包中preparedStatement.addBatch();/*1.第一创建ArrayList —— elementDate => object[]2.elementDate => object[] 就会存放我们预处理的sql语句3.当elementDate满后,就按照1.5扩容4.当添加到指定的值后就执行批量处理5.批量处理会减少发生sql 语句的网络开销,而且减少编码的次数,因此效率高*///当有一千条记录时候在批量执行if ((i+1) % 1000 == 0) { // 说明满一千条 批量执行preparedStatement.executeBatch();//清空一把preparedStatement.clearBatch();}}long end = System.currentTimeMillis();System.out.println("批量执行方式 耗时 = " + (end - start));//关闭连接JDBCUtils.close(null,preparedStatement,connection);}
}
四.数据库连接池
传统获取Connection问题分析
- 传统的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将connection 加载到内存中,在验证ip地址,用户名和密码(0.05s~1s时间)需要数据库连接的时候,就向数据库要求一个,频繁的进行数据库连接操i在将占用很多的数据系统资源,容易造成服务器崩溃。
- 每一次数据库连接,使用完成后都得断开,如果程序出现异常而为关闭,将导致数据库内存泄漏,最终将导致重启数据库
- 传统获取连接的方式,不能控制创建的连接数量,如来连接过多,也可能导致内存泄露,mysql奔溃
- 解决传统数据库中的数据库连接问题,可以采用数据库连接池技术(connection pool)
数据库连接池基本介绍
- 预先在缓冲区中放入一数量的连接,当需要建立数据库连接时,只需从"缓冲池"中取出一个,使用完毕之后在放回去
- 数据库连接池负责分配,管理和释放数据库连接,它允许程序重复使用一个现有的数据库连接,而不是重新建立一个
- 当应用程序向连接池请求将被加入到等待队列中
数据库连接池种类
- JDBC的数据库连接池使用java.x.sql.DataSource 来表示,DataSource只是一个接口,该接口通常由第三方提高实现 会提供相应的jar 包
- C3p0 数据库连接池,速度相对较慢,稳定性不错
- DBCP数据库连接驰,速度相对c3p0较快,但不稳定
- Proxool数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点
- BoneCP 数据库连接池,速度快
- Druid(德鲁伊) 是阿里提供的数据库连接池,集DBCP,C3P0吗,Proxool优点于一深的数据库连接池
C3P0
package com.tianedu.jdbc.datasource;import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;/*** @author tian** 演示c3p0的使用*/
public class C3P0_ {@Test//方式1 相关的参数在程序中指定 user url password 等public void testC3p0_01() throws Exception {//1.创建一个数据源对象ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();//2.通过配置文件获取相关信息 MySQL.properties 获取相关的连接信息Properties properties = new Properties();properties.load(new FileInputStream("src\\mysql.properties"));//获取相关的属性String user = properties.getProperty("user");String password = properties.getProperty("password");String url = properties.getProperty("url");String driver = properties.getProperty("driver");//给数据源 comboPooledDateSource 设置相关的参数//连接的管理是由 comboPooledDataSource帮我们管理的comboPooledDataSource.setDriverClass(driver);comboPooledDataSource.setJdbcUrl(url);comboPooledDataSource.setUser(user);comboPooledDataSource.setPassword(password);// 设置初始化连接数comboPooledDataSource.setInitialPoolSize(10);//最大连接数comboPooledDataSource.setMaxPoolSize(50);//测试连接池的效率long start = System.currentTimeMillis();for (int i = 0; i < 5000; i++) {Connection connection = comboPooledDataSource.getConnection();//这个方法是从 DateSource 接口实现的
// System.out.println("连接成功");connection.close();}long end = System.currentTimeMillis();System.out.println(end - start);}// 方式2 使用配置文件模板来完成// 将c3p0 拷贝到 src 目录下//该文件指定了 连接数据库和连接池的线管参数@Testpublic void testC3PO_02() throws SQLException {//使用配置文件ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("tian");long start = System.currentTimeMillis();for (int i = 0; i < 5000; i++) {Connection connection = comboPooledDataSource.getConnection();connection.close();}long end = System.currentTimeMillis();System.out.println(end -start);}
}
Druidf(德鲁伊)阿里
package com.tianedu.jdbc.datasource;import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.Test;import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;/*** @author tian*/
public class Druid_ {@Test//测试德鲁伊的使用public void testDruid() throws Exception {// 1.加入Druid jar 包// 加入配置文件 将该文件拷贝到src目录下 druid.properties//3.创建一个 properties 对象,用来读取配置文件Properties properties = new Properties();properties.load(new FileInputStream("src\\druid.properties"));//4.创建一个指定参数的数据库连接池,德鲁伊的连接池DataSource dataSource =DruidDataSourceFactory.createDataSource(properties);//拿到连接Connection connection = dataSource.getConnection();System.out.println("连接成功");connection.close();}
}
//创建德鲁伊数据库连接池
package com.tianedu.jdbc.datasource;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 tian* 基于德鲁伊数据库池连接的工具类*/
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) {e.printStackTrace();}}// 编写getConnection方法public static Connection getConnection() throws SQLException {return ds.getConnection();}//关闭连接 是将连接放回到连接池中,close 不是真的断掉连接//而是把使用的Connection对象放回到连接池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);}}
}
package com.tianedu.jdbc.datasource;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 tian* 基于德鲁伊数据库池连接的工具类*/
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) {e.printStackTrace();}}// 编写getConnection方法public static Connection getConnection() throws SQLException {return ds.getConnection();}//关闭连接 是将连接放回到连接池中,close 不是真的断掉连接//而是把使用的Connection对象放回到连接池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);}}
}
package com.tianedu.jdbc.datasource;import org.junit.Test;import java.sql.*;/*** @author tian*/
public class JDBCUtilsByDruid_USE {@Testpublic void testSelect(){System.out.println("使用德鲁伊的方式完成");// 1.得到连接Connection connection = null;//2.组织一个sqlString sql = "select * from actor where id = ?";PreparedStatement preparedStatement = null;ResultSet set = null;//3.创建PreparedStatement 对象try {connection = JDBCUtilsByDruid.getConnection();preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,5);set = preparedStatement.executeQuery();//遍历该结果集while (set.next()){int id = set.getInt("id");String name = set.getString("name");String sex = set.getString("sex");Date borndate = set.getDate("brondate");String phone = set.getString("phone");System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone );}} catch (SQLException e){e.printStackTrace();}finally {//关闭资源JDBCUtilsByDruid.close(set,preparedStatement,connection);}}
}
五.Apache-DBUtiles
- 关闭connection 后,resultSet 结果无法使用
- resultSet 不利于数据的管理
- 示意图
使用土方法来解决 来完成分装
package com.tianedu.jdbc.datasource;import org.junit.Test;import java.sql.*;
import java.util.ArrayList;/*** @author tian*/
@SuppressWarnings({"all"})
public class JDBCUtilsByDruid_USE {@Testpublic void testSelect(){System.out.println("使用德鲁伊的方式完成");// 1.得到连接Connection connection = null;//2.组织一个sqlString sql = "select * from actor where id >= ?";PreparedStatement preparedStatement = null;ResultSet set = null;//3.创建PreparedStatement 对象try {connection = JDBCUtilsByDruid.getConnection();preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,1);set = preparedStatement.executeQuery();// connection.close();//遍历该结果集while (set.next()){int id = set.getInt("id");String name = set.getString("name"); //getName()String sex = set.getString("sex");Date borndate = set.getDate("borndate");String phone = set.getString("phone");System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone );}} catch (SQLException e){e.printStackTrace();}finally {//关闭资源JDBCUtilsByDruid.close(set,preparedStatement,connection);}}//使用土方法来解决 ResultSet => 封装 => ArrayList@Testpublic ArrayList<Actor> testSelectToArrayList(){System.out.println("使用德鲁伊的方式完成");// 1.得到连接Connection connection = null;//2.组织一个sqlString sql = "select * from actor where id >= ?";PreparedStatement preparedStatement = null;ResultSet set = null;//创建一个ArrayListArrayList<Actor> list = new ArrayList<>(); // 创建ArrayList 对象,存放actor 对象//3.创建PreparedStatement 对象try {connection = JDBCUtilsByDruid.getConnection();preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,1);set = preparedStatement.executeQuery();// connection.close();//遍历该结果集while (set.next()){int id = set.getInt("id");String name = set.getString("name"); //getName()String sex = set.getString("sex");Date borndate = set.getDate("borndate");String phone = set.getString("phone");//把得到的resultSet 分装到 Actor对象 放入到List 集合list.add(new Actor(id,name,sex,borndate,phone));}System.out.println("list 集合数据=" + list);} catch (SQLException e){e.printStackTrace();}finally {//关闭资源JDBCUtilsByDruid.close(set,preparedStatement,connection);}//因为ArrayList 和 connection 没有任何关联 所以该集合可以复用return list;}
}
六.Apache-DBUtils
基本介绍
- commons-dbutils 是Apache 组织提供的一个开源JDBC工具类,它是对JDBC的分装,使用dbutils能极大简化jdbc编程的工作量
- DbUtils类
- QueryRunner类:该类封装了sql的执行,是线程安全的。可以实现增,删,改,查,批处理
- 使用QueryRunner类实现查询
- ResultHandler 接口:该接口用于处理 java.sql.ResultSet,将数据按照要求转换成为另外一种形式
ArrayHandler 把结果集中的第一行数据转换成对象数组
ArrayListHandler:把结果集中的每一行数据都转换成一个数组,在存放到List中
BeanHandler: 将结果集中的第一行数据分装到一个对应的JavaBean实例中
BeanListHandler :将结果集中的每一行数据分装到一个对应的JavaBean实例中,存放到List里
ColumnListHandler:将结果就中某一行的数据存放到List中
KeyedHandler(name) 将结果集中的每一行数据都分装到mvp里,在把这些map里,其key为指定的key
Maphandler:将结果集中的第一行数据分装到一个Map里面,key是列名,value就是对应的值
MapListHandler: 将结果集中的每一行数据都分装到一个Map里,然后在存放到List
应用实例
使用DBUtils+ 数据连接池(德鲁伊)方式,完成对表actor的crud
package com.tianedu.jdbc.datasource;import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;/*** @author tian*/
@SuppressWarnings({"all"})
public class DBUtils_USE {@Test//使用apache-DBUtils 工具类 + druid 的方式完成对表的crud操作public void testQueryMany() throws SQLException { //返回结果是多行的情况//1. 得到连接Connection connection = JDBCUtilsByDruid.getConnection();//2.使用DBUtiles 类和接口 先引入德鲁伊的jar文件,加入到本project//3.创建一个 QueryRunnerQueryRunner queryRunner = new QueryRunner();//4.就可以执行相关的方法,返回ArrayList 结果集//String sql = "select * from actor where id >= ?";//注意 sql 语句也可以查询部分列String sql = "select id,name from actor where id >= ?";//1.query 方法就是执行一个sql语句得到一个resultset -- 分装到 --》 ArrayList 集合中然后返回//2.返回集合//3.connection: 连接//4.sql 执行sql语句//5.ew BeanListHandler<>(Actor.class) 再将resultset -》 actor 对象分装到 ArrayList//底层 使用反射机制 去获取actor 类的属性,然后进行封装//6. 1 是传递给sql 的? 的 可以有多个值,因为它是一个可变参数 Object... parames//7.底层 得到的resultSet 会在query 关闭,关闭PrepareStatmentList<Actor> list =queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);System.out.println("输出集合的信息");for (Actor actor : list){System.out.print(actor);}// 释放资源JDBCUtilsByDruid.close(null,null,connection);}}
package com.tianedu.jdbc.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 tian*/
@SuppressWarnings({"all"})
public class DBUtils_USE {@Test//使用apache-DBUtils 工具类 + druid 的方式完成对表的crud操作public void testQueryMany() throws SQLException { //返回结果是多行的情况//1. 得到连接Connection connection = JDBCUtilsByDruid.getConnection();//2.使用DBUtiles 类和接口 先引入德鲁伊的jar文件,加入到本project//3.创建一个 QueryRunnerQueryRunner queryRunner = new QueryRunner();//4.就可以执行相关的方法,返回ArrayList 结果集//String sql = "select * from actor where id >= ?";//注意 sql 语句也可以查询部分列String sql = "select id,name from actor where id >= ?";//1.query 方法就是执行一个sql语句得到一个resultset -- 分装到 --》 ArrayList 集合中然后返回//2.返回集合//3.connection: 连接//4.sql 执行sql语句//5.ew BeanListHandler<>(Actor.class) 再将resultset -》 actor 对象分装到 ArrayList//底层 使用反射机制 去获取actor 类的属性,然后进行封装//6. 1 是传递给sql 的? 的 可以有多个值,因为它是一个可变参数 Object... parames//7.底层 得到的resultSet 会在query 关闭,关闭PrepareStatmentList<Actor> list =queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);System.out.println("输出集合的信息");for (Actor actor : list){System.out.print(actor);}// 释放资源JDBCUtilsByDruid.close(null,null,connection);}// 演示 apache - dubtlis + druid 完成 返回的结果 是单行记录(单个对象)@Testpublic void testQuerySingle() throws SQLException {//1.得到连接Connection connection = JDBCUtilsByDruid.getConnection();//2.创建QueryRunnerQueryRunner queryRunner = new QueryRunner();//3.sql 语句 执行相关方法,返回单个对象String sql = "select * from actor where id = ?";//因为我们知道返回的是单行记录 单个记录,使用Hander 是 BeanHandlerActor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 2);System.out.println(actor);JDBCUtilsByDruid.close(null,null,connection);}// 演示apache-dubtils + druid 完成查询结果是单行单列 - 返回的就是一个Object// Scalar 胆量@Testpublic void testScalar() throws SQLException {Connection connection = JDBCUtilsByDruid.getConnection();QueryRunner queryRunner = new QueryRunner();//执行相关方法,返回单行单列,返回的就是ObejectString sql = "select name from actor where id = ?";//因为返回的是单行单列,返回的是ScalarHandlerObject obj= queryRunner.query(connection, sql, new ScalarHandler(), 2);System.out.println(obj);JDBCUtilsByDruid.close(null,null,connection);}//演示 apache-dbutils + druid 完成 dml(update insert delect)@Testpublic void testDML() throws SQLException {//得到连接Connection connection = JDBCUtilsByDruid.getConnection();//创建queryRunnerQueryRunner queryRunner = new QueryRunner();//4.这里我们可以组织sql语句来完成 update insert delect//String sql = "update actor set name = ? where id = ?";//String sql = "insert into actor values(null,?,?,?,?)";String sql =" delete from actor where id = ?";// 1.我们执行dml 操作使用 方法是 queryRunner.update()//2.返回值是受影响的行数 affectedRow 受影响的行//int affectedRow = queryRunner.update(connection, sql, "林青霞","女","1917-10-10","116");int affectedRow = queryRunner.update(connection,sql,100 );System.out.println(affectedRow > 0 ? "执行成功":"执行没有影响数据库·");//释放资源JDBCUtilsByDruid.close(null,null,connection);}
}
七.DAO 和增删改查 通用方法 - BasicDao
基本说明:
- DAO: data access object 数据访问对象
- 这样的通用类,称为BasicDao 是专门和数据库交互的,及完成对数据库(表)的crud操作
- 在BaiscDao 的基础上,实现一张表 对应一个Dao 更好的完成功能,比如 Customer 表,Customer.java类(javabean)-CustomerDao.java
完成一个简单的设计
com.tianedu.dao_
- com.tainedu.dao_utils //工具类
- com.tainedu.da0_.domain //javabean
- com.tainedu.dao_.dao //存放XXXDAO和BasicDAO
- com.tianedu.dao_.test //写测试类
package com.tianedu.dao_.test;import com.tianedu.dao_.dao.ActorDAO;
import com.tianedu.dao_.domain.Actor;
import org.junit.Test;import java.util.List;/*** @author tian*/
public class TestDAO {@Test//测试ActorDAO 对 actor 表的crud操作public void testActorDAO() {ActorDAO actorDAO = new ActorDAO();//测试查询语句List<Actor> actors= actorDAO.queryMulti("select * from actor where id =?", Actor.class, 1);System.out.println("查询结果");for (Actor actor : actors) {System.out.println(actor);}//查询单行记录Actor actor = actorDAO.querySingle("select * from actor where id =?", Actor.class, 1);System.out.println(actor);
//查询单行单列Object o = actorDAO.queryScalar("select name from actor where id = ?", 1);System.out.println("==== 查询单行列值===");System.out.println(o);//演示dml操作int update =actorDAO.update("insert into actor values(null,?,?,?,?)", "张无忌", "男", "2000-11-11", "999");System.out.println(update > 0 ? "执行成功":"执行没有影响表");}
}