目的

简化代码,提高开发效率

设计模式

策略设计模式

代码

 #连接设置
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. 在elementui表单中实现对vue-quill-editor富文本编辑器内容的绑定

    1.v-model(表单标签双向绑定指令) v-model相当于:value=""和@input=""的结合 代码1: <input type=" ...

  2. C++记录(一)

    1 extern 符表示该变量不是当前作用域定义的,用于声明. 如extern i;表示i不是当前作用域里的,是其他某个include的cpp文件里的变量. 2 int *p=0;相当于初始化p为空指 ...

  3. CentOS7.6配置ip

    查看CentOS版本信息 [root@localhost ~]# cat /etc/redhat-release CentOS Linux release (Core) 配置ip [root@loca ...

  4. The Preliminary Contest for ICPC Asia Shenyang 2019 C Dawn-K's water (完全背包)

    完全背包为什么要取到M,可以取到2*M嘛,这题需要整取,对于不能整取的背包容量,dp[k]=INF,以及dp[j-water[i].weight]=INF时,dp[j]也不需要更新.如果不整取的话,后 ...

  5. anacondaPython3.7退回到Python3.6

    https://blog.csdn.net/Fhujinwu/article/details/85851587

  6. tkinter学习(5)messagebox、pack、grid和place方法

    1.messagebox信息弹出框 1.1 代码: import tkinter as tk #导出tk模块 import tkinter.messagebox #导出弹出信息框 #定义窗口.标题.大 ...

  7. tensorflow按需分配GPU问题

    使用tensorflow,如果不加设置,即使是很小的模型也会占用整块GPU,造成资源浪费. 所以我们需要设置,使程序按需使用GPU. 具体设置方法: gpu_options = tf.GPUOptio ...

  8. 让你的逼格瞬间提升的十个Python语法!

    Python 是一种代表简单思想的语言,其语法相对简单,很容易上手.不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了.本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并 ...

  9. leetcode菜鸡斗智斗勇系列(8)--- Find N Unique Integers Sum up to Zero

    1.原题: https://leetcode.com/problems/find-n-unique-integers-sum-up-to-zero/ Given an integer n, retur ...

  10. Bugku-CTF社工篇之社工进阶