4

day49-JDBC和连接池05 - 一刀一个小西瓜

 1 year ago
source link: https://www.cnblogs.com/liyuelian/p/16800908.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

  • 简单的项目结构
BasicDao2.png
  • 进一步的项目结构

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

%E9%A1%B9%E7%9B%AE%E7%9A%84%E7%AE%80%E5%8D%95%E5%9F%BA%E6%9C%AC%E6%A1%86%E6%9E%B6.png

11.2BasicDao实现

BasicDao应用实例

完成一个简单设计

li.dao_li.dao_.utils //工具类li.dao_domain //Javabeanli.dao_.dao //存放XxxDao和BasicDaoli.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<T> {//泛型指定具体的类型 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<T> queryMulti(String sql, Class<T> clazz, Object... parameters) { Connection connection = null; try { connection = JDBCUtilsByDruid.getConnection(); return qr.query(connection, sql, new BeanListHandler<T>(clazz), parameters); } catch (SQLException e) { throw new RuntimeException(e);//将一个编译异常转变为运行异常 } finally { JDBCUtilsByDruid.close(null, null, connection); } } //查询单行结果 的通用方法(单行多列) public T querySingle(String sql, Class<T> clazz, Object... parameters) { Connection connection = null; try { connection = JDBCUtilsByDruid.getConnection(); return qr.query(connection, sql, new BeanHandler<T>(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<Actor>{ //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<Actor> 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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK