文章目录
- 一、BasicDao是什么?
- 二、BasicDao分析
- 三、BasicDao实现
- (1)BasicDao
- (2)ActorDao
- (3)TestDao
- 四、总结
一、BasicDao是什么?
BasicDao:基础的数据对象,可以完成通用的增删改查方法。
该方法的返回值类型是List, 但实际上的返回值类型是不确定的。
这种设计理念体现一种思想:各司其职。
各个部分之间的对应关系。
(1)DAO:数据访问对象。
(2)BasicDao是一个通用类,专门对数据库进行交互,完成对数据库(表)的CRUD操作。
(3)在BasicDao的基础上,实现 一张表对应一个Dao。
即Actor表 - Actor.java类(javaBean) - ActorDao.java。
二、BasicDao分析
dao包是写与数据库的crud操作。
test包是再这个基础上加入一些业务逻辑的判断。
domain实体类
utils工具类
三、BasicDao实现
先引入工具类,再创建表对应的实体类。然后将BasicDao实现。
(1)BasicDao
import com.hspedu.dao_.domain.Actor;
import com.hspedu.jdbc.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 java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
*开发BasicDao, 是其他DAO的父类。
* Dao,数据访问对象。
*/
public class BasicDao<T> {//泛型指定具体类型
private QueryRunner qr=new QueryRunner();
//开发通用的dml方法,针对任意的表 ,update方法,包含了insert ,delete ,update
public int update(String sql,Object... parameters){
Connection connection=null;
try {
connection= JDBCUtilsByDruid.getConnection();
int update = qr.update(connection,sql, parameters);
return update;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null,null,connection);
}
}
//返回值List<T> , 可以返回存放任意类型T的List集合。
/**
*
* @param sql
* @param clazz 传入一个Class对象,比如Actor.class Class<T>->反射->Class类
* @param parameters 传入占位符?的具体的值,可以是多个
* @return 根据Actor.class 返回对应的ArrayList的集合
*/
//查询 多行结果 的通用方法
public List<T> queryMulti(String sql,Class<T> clazz,Object... parameters){
Connection connection=null;
try {
connection=JDBCUtilsByDruid.getConnection();
List<T> query = qr.query(connection, sql, new BeanListHandler<>(clazz), parameters);
return query;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null,null,connection);
}
}
/*
Class类每个类只有1份,由系统创建。
反射调用属性的过程:得到每个类的Class类,
代码阶段,类加载阶段,允许阶段。
String<T> ?不对,泛型是 在类或接口(引用) 定义的时候进行声明,在创建对象时具体的指定类型。String类定义时并没有使用泛型
数组?集合中可以。
Class<T> ,BasicDao<T> 表示传入该类的T类型,这样T类型就可以作属性,参数和返回值了。
*/
//查询单行结果 的通用方法
public T querySingle(String sql,Class<T> clazz,Object... parameters){
Connection connection=null;
try {
connection= com.hspedu.dao_.utils.JDBCUtilsByDruid.getConnection();
T query = qr.query(connection, sql, new BeanHandler<>(clazz), parameters);
return query;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null,null,connection);
}
}
// 查询单行单列记录。
public Object queryScalar(String sql,Object... parameters){
Connection connection=null;
try {
connection=JDBCUtilsByDruid.getConnection();
Object query = qr.query(connection, sql, new ScalarHandler(), parameters);
return query;
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JDBCUtilsByDruid.close(null,null,connection);
}
}
}
(2)ActorDao
public class ActorDao extends BasicDao<Actor> {
//1.就要BasicDao的方法
//2.根据业务需求,可以编写特有的方法。
}
(3)TestDao
import com.hspedu.dao_.dao.ActorDao;
import com.hspedu.dao_.dao.GoodsDao;
import com.hspedu.dao_.domain.Actor;
import com.hspedu.dao_.domain.Goods;
import org.junit.Test;
import java.util.List;
/**
*
*/
public class TestDao {
// 测试ActorDao 对actor表的crud操作
@Test
public void testActorDao() {
ActorDao actorDao = new ActorDao();
// 1.查询
String sql = "select * from actor where id>=?";
// 使用泛型后,要查询那个表,只需要更换两个参数就可以了。
List<Actor> actors = actorDao.queryMulti(sql, Actor.class, 1);
System.out.println("=====查询结果=====");
for (Actor actor : actors) {
System.out.println(actor);
}
// 2.查询单行记录
// String sql2 = "select * from actor where id=?";
// Actor actor = actorDao.querySingle(sql2, Actor.class, 3);
// System.out.println("查询单行记录" + actor);
//3.查询单行单列记录
// String sql3 = "select name from actor where id=?";
// Object o = actorDao.queryScalar(sql3, 4);
// System.out.println("查询单行单列记录 " + o);
// 4.dml语句, insert ,update, delete
// String sql4 = "update actor set name=? where id=?";
// int n = actorDao.update(sql4, "张三", 3);
// System.out.println((n > 0) ? "更新执行成功" : "执行没有影响到表");
// String sql5 = "delete from actor where id=?";
// int delete = actorDao.update(sql5, 4);
// System.out.println((delete > 0) ? "删除成功" : "删除没有影响到表");
// String sql6 = "insert into actor values(null,?,?,now(),null)";
// int insert = actorDao.update(sql6, "王云", "女");
// System.out.println((insert>0)?"添加成功":"添加没有影响到表");
}
@Test
public void testGoodsDao(){
System.out.println("查询");
String sql="select * from hsp_db01.goods";
GoodsDao goodsDao = new GoodsDao();
List<Goods> goods = goodsDao.queryMulti(sql, Goods.class);
for (Goods goods1:goods){
System.out.println(goods1);
}
// sql="insert into hsp_db01.goods values(?,?,?)";
// int n = goodsDao.update(sql, 700, "飞天摩托", 77777);
// System.out.println((n>0)?"添加成功":"添加没有影响到表");
//sql="update hsp_db01.goods set price=? where id=?";
// int update = goodsDao.update(sql, 8888, 100);
// System.out.println((update>0)?"更新成功":"更新失败");
sql="delete from hsp_db01.goods where id=?";
int update = goodsDao.update(sql, 700);
System.out.println((update>0)?"删除成功":"删除失败");
}
}
使用goods表的goodsDao和actor表的类似。
四、总结
使用BasicDao之后,可对任意表使用BasicDao上的方法执行crud操作。只需要传入sql语句和参数类型,非常灵活。并且查询多行记录得到的是结果集包装后的集合,无需连接也可使用。