目的

简化代码,提高开发效率

设计模式

策略设计模式

代码

 #连接设置
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. 洛谷P1130红牌(简单DP)

    题目描述 某地临时居民想获得长期居住权就必须申请拿到红牌.获得红牌的过程是相当复杂 ,一共包括NNN个步骤.每一步骤都由政府的某个工作人员负责检查你所提交的材料是否符合条件.为了加快进程,每一步政府都 ...

  2. Django - 美化显示request.META

    def index(request): values = request.META.items() html = [] for k, v in values: html.append('<tr& ...

  3. 红帽RHCE培训-课程3笔记内容1

    1 控制服务和守护进程 systemctl systemctl start ** systemctl restart ** systemctl enable ** systemctl status * ...

  4. Web.config和App.config配置连接字符串

    读取配置文件,获取连接字符串 <!-- 第一种 --> <connectionStrings> <add name="connString" conn ...

  5. java 反射获取设置私有成员变量的值

    for (Object arg:args) { //处理applicationCode Class<?> argClass = arg.getClass(); Field applicat ...

  6. qq音乐解析API

    文档:www.tjit.net 开放的接口:api88.net 个人代码: input2(event){ //将字符转化为encodeURL编码,才能进行正确请求,这是这个接口要求的 //js自带的转 ...

  7. python调用c++开发的动态库

    此处列举一下python调用Windows端动态库. # *- coding=utf-8 -* import ctypes from ctypes import * import os objdll ...

  8. VMware安装EVE

    众所周知,EVE是一个非常强大的仿真环境,能给我们学习带来很大的帮助,这里主要简单记录一下安装在VMware下安装EVE的过程. 1.准备: 我安装的VMware是WORKSTATION 12 PRO ...

  9. 【Struts APP_PATH】StartSystemListener

    StartSystemListener package k.filter; import javax.servlet.ServletContext; import javax.servlet.Serv ...

  10. Python3.5学习之旅——day6

    面向对象编程的学习 一.定义 首先跟大家介绍一位资深的程序员前辈说过的编程心得: 1.写重复代码是非常不好且低级的行为 2.完成的代码需要经常变更 所以根据以上两个心得,我们可以知道写的代码一定要遵循 ...