• day49-JDBC和连接池05


    JDBC和连接池05

    11.BasicDAO

    • 先来分析一个问题

      前面我们使用了Apache-DBUtils和Druid简化了JDBC开发,但仍存在以下不足:

      • SQL语句是固定的,不能通过参数传入,通用性不好,需要进行改进,来更方便执行增删改查

      • 对于select操作,如果有返回值,返回类型还不确定,应该使用泛型

      • 将来如果表很多,业务需求复杂,不可能只靠一个Java来完成

    为了解决这些问题,就要引出BasicDAO的概念

    11.1BasicDao分析

    • 基本说明
    1. DAO,即data access object(数据访问对象)

    2. 这样的通用类称为BasicDao,是专门和数据库进行交互的,即完成对数据库(表)的crud操作

    3. 在BasicDao的基础上,实现一张表对应一个Dao,更好的完成功能

      比如:Customer表--Customer.java类(javabean)--CustomerDao.java

    • 简单的项目结构
    • 进一步的项目结构

    在实际的开发中,由于业务的复杂度,一般会在应用层TestDAO和DAO层之间增加一个业务层XxxService,这一层会完成一些综合性的业务

    11.2BasicDao实现

    BasicDao应用实例

    完成一个简单设计

    li.dao_
    li.dao_.utils //工具类
    li.dao_domain //Javabean
    li.dao_.dao //存放XxxDao和BasicDao
    li.dao_.test //写测试类
    image-20221017212118550

    11.2.1utils

    JDBCUtilsByDruid类

    package li.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数据库连接池的工具类
    */
    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 statemenat, Connection connection) {
    try {
    if (resultSet != null) {
    resultSet.close();
    }
    if (statemenat != null) {
    statemenat.close();
    }
    if (connection != null) {
    connection.close();
    }
    } catch (SQLException e) {
    throw new RuntimeException(e);
    }
    }
    }

    11.2.2domain

    Actor类

    package li.dao_.domain;
    import java.util.Date;
    /**
    * Actor对象和actor表的记录对应
    */
    public class Actor {//JavaBean/POJO/Domain
    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 + '\'' +
    '}';
    }
    }

    11.2.3dao

    11.2.3.1BasicDAO类
    package li.dao_.dao;
    import li.dao_.utils.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的父类
    */
    public class BasicDAO {//泛型指定具体的类型
    private QueryRunner qr = new QueryRunner();
    //开发通用的dml方法,针对任意的表
    /**
    * @param sql 传入的SQL语句,可以有占位符?
    * @param parameters 传入占位符?的具体的值,可以是多个
    * @return 返回的值是受影响的行数
    */
    public int update(String sql, Object... parameters) { //可变参数 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);
    }
    }
    //返回多个对象(即查询的结果是多行),针对任意的表(多行多列)
    /**
    * @param sql 传入的SQL语句,可以有占位符?
    * @param clazz 传入一个类的Class对象,比如 Actor.class[底层需要通过反射来创建Javabean对象]
    * @param parameters 传入占位符?的具体的值,可以是多个
    * @return 根据传入的class对象 Xxx.class 返回对应的ArrayList集合
    */
    public List queryMulti(String sql, Class clazz, Object... parameters) {
    Connection connection = null;
    try {
    connection = JDBCUtilsByDruid.getConnection();
    return qr.query(connection, sql, new BeanListHandler(clazz), parameters);
    } catch (SQLException e) {
    throw new RuntimeException(e);//将一个编译异常转变为运行异常
    } finally {
    JDBCUtilsByDruid.close(null, null, connection);
    }
    }
    //查询单行结果 的通用方法(单行多列)
    public T querySingle(String sql, Class clazz, Object... parameters) {
    Connection connection = null;
    try {
    connection = JDBCUtilsByDruid.getConnection();
    return qr.query(connection, sql, new BeanHandler(clazz), parameters);
    } 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();
    return qr.query(connection, sql, new ScalarHandler(), parameters);
    } catch (SQLException e) {
    throw new RuntimeException(e);//将一个编译异常转变为运行异常
    } finally {
    JDBCUtilsByDruid.close(null, null, connection);
    }
    }
    }
    11.2.3.2ActorDAO类
    package li.dao_.dao;
    import li.dao_.domain.Actor;
    public class ActorDAO extends BasicDAO{
    //1.ActorDAO可以使用BasicDAO的方法
    //2.同时根据业务需求可以编写特有的方法
    }

    11.2.4test

    TestDAO类

    package li.dao_.test;
    import li.dao_.dao.ActorDAO;
    import li.dao_.domain.Actor;
    import org.junit.Test;
    import java.util.List;
    public class TestDAO {
    //测试ActorDAO 对actor表的crud操作
    @Test
    public void testActorDAO() {
    ActorDAO actorDAO = new ActorDAO();
    //1.查询
    List actors =
    actorDAO.queryMulti("select * from actor where id >=?", Actor.class, 1);
    System.out.print("====查询-多行多列-结果====");
    for (Actor actor : actors) {
    System.out.print(actor);
    }
    System.out.println();
    //2.查询单行记录
    Actor actor = actorDAO.querySingle("select * from actor where id =?", Actor.class, 3);
    System.out.print("====查询-单行多列-结果====");
    System.out.println(actor);
    System.out.println();
    //3.查询单行单列
    Object o = actorDAO.queryScalar("select name from actor where id =?", 1);
    System.out.println("====查询-单行单列-结果====");
    System.out.println(o);
    System.out.println();
    //4.dml操作
    int update = actorDAO.update("insert into actor values(null,?,?,?,?)", "张无忌", "男", "2000-11-11", "999");
    System.out.println(update > 0 ? "操作成功" : "执行没有影响表");
    }
    }

    运行结果:

    image-20221017203752269 image-20221017203650205

    11.3练习

    开发GoodsDAO和Goods,完成对表goods的crud

    image-20221017212634726 image-20221017212649833
  • 相关阅读:
    Unity学习shader笔记[一百]简单焦散Caustic效果
    【环境搭建】linux docker安装nexus3
    containerd 源码分析:kubelet 和 containerd 交互
    Serverless 架构下的 AI 应用开发
    Arthas 启动时无法获取java进程
    Kafka3.0.0版本——消费者(消费者组原理)
    首个落地实践!曙光存储案例入选液冷数据中心白皮书
    白话区块链是什么
    【Kotlin基础系列】第7章 类与对象(1)
    CentOS、银河麒麟高级服务器版V10安装mysql5.7
  • 原文地址:https://www.cnblogs.com/liyuelian/p/16800908.html