1. 先分析一个问题 852
apache-dbutils+ Druid简化了JDBC开发,但还有不足:
1. SQL 语句是固定,不能通过参数传入,通用性不好,需要进行改进,更方便执行增删改查
2.对于select 操作,如果有返回值,返回类型不能固定,需要使用泛型
3.将来的表很多, 业务需求复杂,不可能只靠一个Java类完成
4.引出=》BasicDAO画出示意图,看看在实际开发中,应该如何处理
2. 基本说明 852
1. DAO: data access object数据访问对象
2.这样的通用类, 称为BasicDao,是专门和数据库交互的,即完成对数据库(表)的crud操作。
3.在BaiscDao 的基础上,实现一张表对应一个Dao,更好的完成功能,比如Customer表-
Customer.java类(javabean)-CustomerDao.java
3. BasicDAO 应用实例 853-855
完成一个简单设计
com.stulzl.dao_
1. com.stulzl.dao_.utils//工具类
2. com.stulzl.dao_.domain//javabean
3. com.stulzl.dao_.dao//XxxDAO和BasicDAO
4. com.stulzl.dao_.test//写测试类
代码在 com.stulzl.dao_
com.stulzl.dao_.test; 测试TestDAO
package com.stulzl.dao_.test;
import com.stulzl.dao_.dao.ActorDAO;
import com.stulzl.dao_.domain.Actor;
import org.junit.jupiter.api.Test;
import java.util.List;
//测试Actor对actor表的crud操作 855
public class TestDAO {
@Test
public void testActorDAO(){
ActorDAO actorDAO = new ActorDAO();
//查询多行数据
List 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, 4);
System.out.println("===查询单行数据=== ");
System.out.println(actor);
//查询单行单列(即一个数据)
Object o = actorDAO.queryScalar("select name from actor where id =?", 4);
System.out.println("===查询单行单列===");
System.out.println(o);
//演示dml操作insert,update,delete
int update =
actorDAO.update("insert into actor values(null, ?, ?, ?, ?)",
"张无忌", "男", "2000-11-11", "999");
System.out.println(update > 0 ? "执行成功" : "执行没有影响表");
}
}
com.stulzl.dao_.dao. 父类BasicDAO
package com.stulzl.dao_.dao;
import com.stulzl.jdbcutils_druid.JDBCUtils_Druid;
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 java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
//开发BasicDAO,是其他DAO的父类 854
public class BasicDAO {//泛型指定具体的类型
private QueryRunner qr = new QueryRunner();
//开发通用的dml方法,针对任意的表
public int update(String sql,Object... parameters){//Object... parameters可变形参
Connection connection = null;
try {
connection = JDBCUtils_Druid.getConnection();
int update = qr.update(connection, sql, parameters);
return update;//返回收影响行数
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
//关闭连接
JDBCUtils_Druid.close(null,null,connection);
}
}
//返回多个对象(即查询的结果是多行),这么对任意表
/**
*
* @param sql sql 语句,可以有 ?
* @param clazz 传入一个类的 Class 对象 比如 Actor.class
* @param parameters 传入 ? 的具体的值,可以是多个
* @return 根据 Actor.class 返回对应的 ArrayList 集合
*/
public List queryMulti(String sql, Class clazz, Object...parameters){
Connection connection = null;
try {
connection = JDBCUtils_Druid.getConnection();
return qr.query(connection, sql, new BeanListHandler(clazz), parameters);
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
//关闭连接
JDBCUtils_Druid.close(null,null,connection);
}
}
//查询单行结果的通用方法
public T querySingle(String sql, Class clazz, Object... parameters) {
Connection connection = null;
try {
connection = JDBCUtils_Druid.getConnection();
return qr.query(connection, sql, new BeanHandler(clazz), parameters);
} catch (SQLException e) {
throw new RuntimeException(e); //将编译异常->运行异常 ,抛出
} finally {
JDBCUtils_Druid.close(null, null, connection);
}
}
//查询单行单列的方法,即返回单值的方法
public Object queryScalar(String sql, Object... parameters){
Connection connection = null;
try {
connection = JDBCUtils_Druid.getConnection();
return qr.query(connection, sql, new ScalarHandler(), parameters);
} catch (SQLException e) {
throw new RuntimeException(e); //将编译异常->运行异常 ,抛出
} finally {
JDBCUtils_Druid.close(null, null, connection);
}
}
}
com.stulzl.dao_.dao; 子类ActorDAO
package com.stulzl.dao_.dao;
import com.stulzl.dao_.domain.Actor;
//让ActorDAO去继承BasicDAO并指定特有的对象类 855
public class ActorDAO extends BasicDAO{
//1. 就有 BasicDAO 的方法
//2. 根据业务需求,可以编写特有的方法.
}
com.stulzl.dao_.domain; Actor类
package com.stulzl.dao_.domain;
import java.util.Date;
//Actor对象和actor表记录对应 847
public class Actor {
private Integer id;
private String name;
private String sex;
private Date borndate;
private String phone;
//无参构造器
public Actor() {
}
//有参构造器
public Actor(Integer id, String name, String sex, Date borndate, String phone) {
this.id = id;
this.name = name;
this.sex = sex;
this.borndate = borndate;
this.phone = phone;
}
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 getBorndate() {
return borndate;
}
public void setBorndate(Date borndate) {
this.borndate = borndate;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "\nActor{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", borndate=" + borndate +
", phone='" + phone + '\'' +
'}';
}
}
com.stulzl.dao_.utils; 工具类JDBCUtils_Druid
package com.stulzl.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;
//这是一个基于druid的数据库连接池的工具类 845
//将 JDBCUtils 工具类改成 Druid(德鲁伊)实现
public class JDBCUtils_Druid {
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);
}
}
}