目录
一.封装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个),因为只需要一份,我们做出Static
private static String user; // 用户名
private static String password; // 密码
private static String url; //url
private 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();
}
}
// 连接数据库 返回一个Connection
public static Connection getConnection(){
try {
return DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
// throwables.printStackTrace();
//将编译异常转换成 运行异常,调用者可以捕获该异常,也可以选择默认处理该异常,比较方便
throw new RuntimeException(e);
}
}
//关闭相关的资源
/*
1.ResultSet 结果集
2.Statement 或者 PreparedStatement
3.关闭Connection
4.如果需要关闭资源,就传入对象,否则传入null
*/
public static void close(ResultSet set, Statement statement,Connection connection){
//判断是否为null
try {
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) {
//测试
}
@Test
public void testSelect(){
//1.得到连接
Connection connection = null;
//2.组织一个sql
String sql = "select * from actor where id = ?";
//测试 select
PreparedStatement 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);
}
}
@Test
public 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_ {
@Test
public 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);
}
}
// 事务来解决
@Test
public void useTransaction() {
//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";
//3.创建PrepareStatement 对象
PreparedStatement preparedStatement = null;
try {
connection = JDBCUtils.getConnection();
// 将connection 设置为不自动提交
connection.setAutoCommit(false); //相当于开始事务
preparedStatement = connection.prepareStatement(sql);
preparedStatement.executeUpdate(); // 执行sql
preparedStatement = 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
//传统的方法添五千条数数据到admin2
public void noBatch() throws SQLException {
//得到连接
Connection connection = JDBCUtils.getConnection();
//sql
String 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);
}
//使用批量处理方式添加数据
@Test
public void batch() throws SQLException {
//获得连接
Connection connection = JDBCUtils.getConnection();
//写sql语句
String sql = "insert into admin3 values(null,?,?)";
//获得preparedStatement
PreparedStatement 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 目录下
//该文件指定了 连接数据库和连接池的线管参数
@Test
public 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 {
@Test
public void testSelect(){
System.out.println("使用德鲁伊的方式完成");
// 1.得到连接
Connection connection = null;
//2.组织一个sql
String 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 {
@Test
public void testSelect(){
System.out.println("使用德鲁伊的方式完成");
// 1.得到连接
Connection connection = null;
//2.组织一个sql
String 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
@Test
public ArrayList<Actor> testSelectToArrayList(){
System.out.println("使用德鲁伊的方式完成");
// 1.得到连接
Connection connection = null;
//2.组织一个sql
String sql = "select * from actor where id >= ?";
PreparedStatement preparedStatement = null;
ResultSet set = null;
//创建一个ArrayList
ArrayList<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.创建一个 QueryRunner
QueryRunner 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 关闭,关闭PrepareStatment
List<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.创建一个 QueryRunner
QueryRunner 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 关闭,关闭PrepareStatment
List<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 完成 返回的结果 是单行记录(单个对象)
@Test
public void testQuerySingle() throws SQLException {
//1.得到连接
Connection connection = JDBCUtilsByDruid.getConnection();
//2.创建QueryRunner
QueryRunner queryRunner = new QueryRunner();
//3.sql 语句 执行相关方法,返回单个对象
String sql = "select * from actor where id = ?";
//因为我们知道返回的是单行记录 单个记录,使用Hander 是 BeanHandler
Actor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 2);
System.out.println(actor);
JDBCUtilsByDruid.close(null,null,connection);
}
// 演示apache-dubtils + druid 完成查询结果是单行单列 - 返回的就是一个Object
// Scalar 胆量
@Test
public void testScalar() throws SQLException {
Connection connection = JDBCUtilsByDruid.getConnection();
QueryRunner queryRunner = new QueryRunner();
//执行相关方法,返回单行单列,返回的就是Obeject
String sql = "select name from actor where id = ?";
//因为返回的是单行单列,返回的是ScalarHandler
Object obj= queryRunner.query(connection, sql, new ScalarHandler(), 2);
System.out.println(obj);
JDBCUtilsByDruid.close(null,null,connection);
}
//演示 apache-dbutils + druid 完成 dml(update insert delect)
@Test
public void testDML() throws SQLException {
//得到连接
Connection connection = JDBCUtilsByDruid.getConnection();
//创建queryRunner
QueryRunner 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 ? "执行成功":"执行没有影响表");
}
}