目的

简化代码,提高开发效率

设计模式

策略设计模式

代码

 #连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/day17
username=root
password=sorry #<!-- 初始化连接 -->
initialSize=10 #最大连接数量
maxActive=50 #<!-- 最大空闲连接 -->
maxIdle=20 #<!-- 最小空闲连接 -->
minIdle=5 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000 #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=utf8 #指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true #driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly= #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=REPEATABLE_READ

dbcpconfig.properties

 import java.util.List;
import org.junit.Test;
import com.itheima.dbassist.BeanHandler;
import com.itheima.dbassist.BeanListHandler;
import com.itheima.dbassist.DBAssist;
import com.itheima.domain.User;
import com.itheima.util.DBCPUtil; public class UserDaoImpl {
private DBAssist da = new DBAssist(DBCPUtil.getDataSource());
//SQL和参数
@Test
public void add(){
da.update("insert into user values(?,?,?,?)", "aa","wf","123","非同寻常");
}
@Test
public void update(){
da.update("update user set password=? where id=?", "12345","aa");
}
@Test
public void delete(){
da.update("delete from user where id=?", "aa");
}
@Test
public void query1(){
User user = (User)da.query("select * from user where id=?", new BeanHandler(User.class), "a5cc6e18-f3b8-44a6-bcdd-c6476f1edb87");
System.out.println(user);
}
@Test
public void query2(){
List<User> users = (List<User>)da.query("select * from user", new BeanListHandler(User.class));
for(User user:users)
System.out.println(user);
}
}

UserDaoImpl

 import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
/**
* 适合有多条结果记录的数据封装
* 返回的是一个List
*
*/
public class BeanListHandler implements ResultSetHandler {
private Class clazz;
public BeanListHandler(Class clazz){
this.clazz = clazz;
}
public Object handle(ResultSet rs) {
try {
List list = new ArrayList();
while(rs.next()){
Object bean = clazz.newInstance();
//封装数据:书写JavaBean的前提,类中的字段名或属性名与数据库表的字段名保持一致
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for(int i=0;i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1);//与JavaBean的字段名一致
Object columnValue = rs.getObject(columnName);//列值 //得到JavaBean的对应字段
Field field = clazz.getDeclaredField(columnName);
field.setAccessible(true);//强暴它 有可能是私有的
field.set(bean, columnValue);
}
list.add(bean); }
return list;
} catch (Exception e) {
throw new RuntimeException("封装数据失败");
}
}
}

BeanListHandler

 import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; import javax.sql.DataSource; import com.itheima.util.DBCPUtil; public class DBAssist {
private DataSource dataSource;
public DBAssist(DataSource dataSource){
this.dataSource = dataSource;
}
/*
* 能够执行DML语句:INSERT UPDATE DELETE
*/
public void update(String sql,Object...params){
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try{
conn = dataSource.getConnection();//具体的数据源无关
stmt = conn.prepareStatement(sql);
//看sql中的占位符的个数:参数元信息的获取
ParameterMetaData pmd = stmt.getParameterMetaData();
int paramCount = pmd.getParameterCount();
//设置参数:略
if(paramCount>0){
//判断参数占位符的个数和params的个数是否一致
if(params==null||params.length!=paramCount){
throw new RuntimeException("参数个数不匹配");
}
//设置SQL中的参数占位符的值
for(int i=0;i<paramCount;i++){
stmt.setObject(i+1, params[i]);
}
}
stmt.executeUpdate();
}catch(Exception e){
throw new RuntimeException(e);
}finally{
release(rs, stmt, conn);
}
}
/**
* 执行查询
* @return 封装了数据的对象
*/
public Object query(String sql,ResultSetHandler handler,Object...params){
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try{
conn = dataSource.getConnection();
stmt = conn.prepareStatement(sql);
//看sql中的占位符的个数:参数元信息的获取
ParameterMetaData pmd = stmt.getParameterMetaData();
int paramCount = pmd.getParameterCount();
//设置参数:略
if(paramCount>0){
//判断参数占位符的个数和params的个数是否一致
if(params==null||params.length!=paramCount){
throw new RuntimeException("参数个数不匹配");
}
//设置SQL中的参数占位符的值
for(int i=0;i<paramCount;i++){
stmt.setObject(i+1, params[i]);
}
}
rs = stmt.executeQuery();//如何封装呢:
//有结果集:不知道有什么字段和值
//不知道封装成什么对象:谁用谁知道 //策略:有数据----->有目标
return handler.handle(rs);
}catch(Exception e){
throw new RuntimeException(e);
}finally{
release(rs, stmt, conn);
}
}
private void release(ResultSet rs,Statement stmt,Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}

DBAssist

 package com.itheima.dbassist;

 import java.sql.ResultSet;
//抽象策略
public interface ResultSetHandler {
/**
*把结果集中的数据封装到对象中
* @param rs
* @return
*/
Object handle(ResultSet rs);
}

ResultSetHandler

 import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
//策略的具体实现
/**
* 专门用于封装结果中只有一条的记录的情况
* 返回值:封装好的Java对象
*
*/
public class BeanHandler implements ResultSetHandler {
private Class clazz;
public BeanHandler(Class clazz){
this.clazz = clazz;
}
public Object handle(ResultSet rs) {
try {
if(rs.next()){
Object bean = clazz.newInstance();
//封装数据:书写JavaBean的前提,类中的字段名或属性名与数据库表的字段名保持一致
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for(int i=0;i<columnCount;i++){
String columnName = rsmd.getColumnName(i+1);//与JavaBean的字段名一致
Object columnValue = rs.getObject(columnName);//列值 //得到JavaBean的对应字段
Field field = clazz.getDeclaredField(columnName);
field.setAccessible(true);//强暴它 有可能是私有的
field.set(bean, columnValue);
} return bean;
}
return null;
} catch (Exception e) {
throw new RuntimeException("封装数据失败");
}
} }

BeanHandler

 public class User {
private String id;
private String username;
private String password;
private String nick;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getNick() {
return nick;
}
public void setNick(String nick) {
this.nick = nick;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password="
+ password + ", nick=" + nick + "]";
} }

User

 import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; public class DBCPUtil {
private static DataSource dataSource;
static{
try {
InputStream in = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties props = new Properties();
props.load(in);
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
throw new ExceptionInInitializerError("初始化数据源失败");
}
}
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException("获取数据库连接失败");
}
}
public static DataSource getDataSource(){
return dataSource;
} }

DBCPUtil

编写自己的JDBC框架的更多相关文章

  1. 【总结】编写自己的JDBC框架

    一.数据库连接池: 在一般用JDBC 进行连接数据库进行CRUD操作时,每一次都会: 通过:java.sql.Connection conn = DriverManager.getConnection ...

  2. javaweb学习总结(四十)——编写自己的JDBC框架

    一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...

  3. 编写自定义的JDBC框架与策略模式

    本篇根据上一篇利用数据库的几种元数据来仿造Apache公司的开源DbUtils工具类集合来编写自己的JDBC框架.也就是说在本篇中很大程度上的代码都和DbUtils中相似,学完本篇后即更容易了解DbU ...

  4. javaweb总结(四十)——编写自己的JDBC框架

    一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...

  5. 编写自己的JDBC框架(转)

    一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...

  6. java web学习总结(二十三) -------------------编写自己的JDBC框架

    一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...

  7. JDBC 学习复习10 编写自己的JDBC框架

    首先万分感谢狼哥 孤傲苍狼 博客,整个jdbc学习的博客资料 链接为http://www.cnblogs.com/xdp-gacl/p/4006830.html 详细代码见狼哥博客,列出我学习过程中遇 ...

  8. JDBC框架

    一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...

  9. Spring的JDBC框架

    转自: http://www.cnblogs.com/windlaughing/p/3287750.html Spring JDBC提供了一套JDBC抽象框架,用于简化JDBC开发. Spring主要 ...

随机推荐

  1. Servlet获取配置信息(ServletConfig)

    ServletConfig ServletConfig:当Servlet容器初始化Servlet时,Servlet容器会给Servlet的init方法传入一个ServletConfig.Servlet ...

  2. 数据查询SELECT FROM

    [1]指定查询字段数据 SELECT  id,name,job FROM    stu_info;      #指定查询id,name,job字段的信息. SELECT  name FROM    s ...

  3. dubbo+zookeeper搭建笔记

    参考博客: http://blog.csdn.net/u013142781/article/details/50396621#reply http://blog.csdn.net/u013142781 ...

  4. Django+Celery+redis kombu.exceptions.EncodeError:Object of type is not JSON serializable报错

    在本文中例子中遇到问题的各种开发版本如下: Python3.6.8 Django==2.2 celery==4.4.0 kombu==4.6.7 redis==3.3.0 大概的报错如下截图: 是在开 ...

  5. 2020 i春秋新春战疫公益赛 misc

    0x01 code_in_morse morse decode后得到: RFIE4RYNBINAUAAAAAGUSSCEKIAAAAEUAAAAA7AIAYAAAAEPFOMTWAAABANUSRCB ...

  6. 安装和配置Windows系统虚拟机

    1.打开虚拟机软件,点击新建虚拟机. 2.选择典型配置,点击下一步. 3.点击安装程序光盘映像文件,选择对应的映像文件,然后点击下一步.选择对应的密钥和版本,设置密码等. 4.创建虚拟机名字和存储位置 ...

  7. 201771010135 杨蓉庆/张燕《面对对象程序设计(java)》第十三周学习总结

    1.实验目的与要求 (1) 掌握事件处理的基本原理,理解其用途: (2) 掌握AWT事件模型的工作机制: (3) 掌握事件处理的基本编程模型: (4) 了解GUI界面组件观感设置方法: (5) 掌握W ...

  8. 吴裕雄 python 机器学习——模型选择损失函数模型

    from sklearn.metrics import zero_one_loss,log_loss def test_zero_one_loss(): y_true=[1,1,1,1,1,0,0,0 ...

  9. TensorFlow卷积神经网络实现手写数字识别以及可视化

    边学习边笔记 https://www.cnblogs.com/felixwang2/p/9190602.html # https://www.cnblogs.com/felixwang2/p/9190 ...

  10. leetcode929 Unique Email Addresses

    Every email consists of a local name and a domain name, separated by the @ sign. For example, in ali ...