package com.itheima.domain;
//一般:实体类的字段名和数据库表的字段名保持一致
//约定优于编码
public class Account {
private int id;
private String name;
private float money;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getMoney() {
return money;
}
public void setMoney(float money) {
this.money = money;
}
@Override
public String toString() {
return "Account [id=" + id + ", name=" + name + ", money=" + money
+ "]";
} }
package com.itheima.util;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
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(e);
}
} public static DataSource getDataSource(){
return dataSource;
} public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
package com.itheima.dbassist;

import java.sql.ResultSet;

public interface ResultSetHandler {
/**
* 把结果中的数据封装到指定的对象中
* @param rs
* @return 封装了数据的对象
*/
Object handle(ResultSet rs);
}
package com.itheima.dbassist;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* 封装到JavaBean中
* 满足约定:数据库字段名和JavaBean字段名保持一致
* @author wzhting
*
*/
public class BeanListHanlder implements ResultSetHandler { private Class clazz;//目标类型
public BeanListHanlder(Class clazz){
this.clazz = clazz;
} public Object handle(ResultSet rs) {
try {
List list = new ArrayList();
while(rs.next()){
//有记录
Object bean = clazz.newInstance();//目标对象
//有多少列,列名和值又是什么?
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();//列数
for(int i=0;i<count;i++){
String fieldName = rsmd.getColumnName(i+1);//得到数据库字段名,也就得到了JavaBan的字段名
Object fieldValue = rs.getObject(fieldName);//字段值
//通过字段反射
Field f = clazz.getDeclaredField(fieldName);
f.setAccessible(true);
f.set(bean, fieldValue);
}
list.add(bean);
}
return list;
} catch (Exception e) {
throw new RuntimeException(e);
}
} }
package com.itheima.dbassist;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
/**
* 适合只有一条查询结果的情况
* 封装到JavaBean中
* 满足约定:数据库字段名和JavaBean字段名保持一致
* @author wzhting
*
*/
public class BeanHanlder implements ResultSetHandler { private Class clazz;//目标类型
public BeanHanlder(Class clazz){
this.clazz = clazz;
} public Object handle(ResultSet rs) {
try {
if(rs.next()){
//有记录
Object bean = clazz.newInstance();//目标对象
//有多少列,列名和值又是什么?
ResultSetMetaData rsmd = rs.getMetaData();
int count = rsmd.getColumnCount();//列数
for(int i=0;i<count;i++){
String fieldName = rsmd.getColumnName(i+1);//得到数据库字段名,也就得到了JavaBan的字段名
Object fieldValue = rs.getObject(fieldName);//字段值
//通过字段反射
Field f = clazz.getDeclaredField(fieldName);
f.setAccessible(true);
f.set(bean, fieldValue);
}
return bean;
}
return null;
} catch (Exception e) {
throw new RuntimeException(e);
}
} }
package com.itheima.dbassist;

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; /**
* 框架的核心类
* @author wzhting
*
*/
public class DBAssist {
private DataSource dataSource;
public DBAssist(DataSource dataSource){
this.dataSource = dataSource;
}
//写:添加、删除、修改
//params参数要和sql中的占位符对应
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 count = pmd.getParameterCount();
if(count>0){
if(params==null){
throw new RuntimeException("必须传入参数的值");
}
if(count!=params.length){
throw new RuntimeException("参数数量不匹配");
}
for(int i=0;i<count;i++){
stmt.setObject(i+1, params[i]);
} } stmt.executeUpdate();
}catch(Exception e){
throw new RuntimeException(e);
}finally{
release(rs, stmt, conn);
}
} //读:查询
public Object query(String sql,ResultSetHandler rsh,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 count = pmd.getParameterCount();
if(count>0){
if(params==null){
throw new RuntimeException("必须传入参数的值");
}
if(count!=params.length){
throw new RuntimeException("参数数量不匹配");
}
for(int i=0;i<count;i++){
stmt.setObject(i+1, params[i]);
} } rs = stmt.executeQuery();
//有结果集,要封装到对象中。策略设计模式
return rsh.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;
}
}
}
package com.itheima.test;

import java.util.List;

import org.junit.Test;

import com.itheima.dbassist.BeanHanlder;
import com.itheima.dbassist.BeanListHanlder;
import com.itheima.dbassist.DBAssist;
import com.itheima.domain.Account;
import com.itheima.util.DBCPUtil; public class DBAssistTest {
private DBAssist da = new DBAssist(DBCPUtil.getDataSource());
@Test
public void testAdd(){
da.update("insert into account values (?,?,?)", 7,"ggg",1000);
}
@Test
public void testUpdate(){
da.update("update account set money=? where id=?", 10000,7);
}
@Test
public void testDel(){
da.update("delete from account where id=?",7);
}
@Test
public void testQueryOne(){
Object obj = da.query("select * from account where id=?",new BeanHanlder(Account.class),2);
System.out.println(obj);
}
@Test
public void testQueryAll(){
List list = (List)da.query("select * from account",new BeanListHanlder(Account.class));
for(Object o:list)
System.out.println(o);
}
}

编写JDBC框架:(策略设计模式)的更多相关文章

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

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

  2. 黑马程序员—创建JDBC框架及原理分析

    对于Java数据库的连接,由最初学习的每次全部手工代码,到后面的不断利用知识简化代码量:这是不断学习的过程,就像人类由原始社会的钻木取火到当代的文明,都是一步步过来的! 本文不从最开始的JDBC入门开 ...

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

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

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

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

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

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

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

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

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

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

  8. 编写自己的JDBC框架

    目的 简化代码,提高开发效率 设计模式 策略设计模式 代码 #连接设置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost ...

  9. 实现简易JDBC框架

    1 准备 JDBC 基本知识 JDBC元数据知识 反射基本知识 2:  两个问题 业务背景:系统中所有实体对象都涉及到基本的CRUD操作.所有实体的CUD操作代码基本相同,仅仅是发送给数据库的sql语 ...

随机推荐

  1. BZOJ5369:[PKUSC2018]最大前缀和(状压DP)

    Description 小C是一个算法竞赛爱好者,有一天小C遇到了一个非常难的问题:求一个序列的最大子段和. 但是小C并不会做这个题,于是小C决定把序列随机打乱,然后取序列的最大前缀和作为答案. 小C ...

  2. day3-课堂笔记

    函数有2种: 1种是有返回值的,不改变对象本身 1种是没有返回值的,改变对象本身   eval函数就是实现list.dict.tuple与str之间的转化(只能把类似格式的字符串进行相应转换)str函 ...

  3. JavaScript 删除数组中的对象

    1.获得对象在数组中的下标 function (_arr,_obj) { var len = _arr.length; for(var i = 0; i < len; i++){ if(_arr ...

  4. tarjan - 强连通

    如果两个点可以互相到达,则称为强连通.如果有向图G每个点都可以互相到达,则称为强连通图.其中G中的极大强连通子图,则称为强连通分量.现求强连通分量是多少,且哪些点属于同一个强连通分量 tarjan由d ...

  5. HDU 3592 World Exhibition(线性差分约束,spfa跑最短路+判断负环)

    World Exhibition Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  6. odoo销售转生产

    <!--form view 一个form视图足以--><record id="view_sale_tomrp_form" model="ir.ui.vi ...

  7. PHP设计模式——訪问者模式

    声明:本系列博客參考资料<大话设计模式>,作者程杰. 訪问者模式表示一个作用于某对象结构中的各元素的操作. 它使你能够在不改变各元素类的前提下定义作用于这些元素的新操作. UML类图: w ...

  8. Hadoop体系结构杂谈

    hadoop体系结构杂谈 今天跟一个朋友在讨论hadoop体系架构,从当下流行的Hadoop+HDFS+MapReduce+Hbase+Pig+Hive+Spark+Storm开始一直讲到HDFS的底 ...

  9. 【小程序】本地资源图片无法通过 WXSS 获取

    小程序升级更改: 本地资源图片无法通过 WXSS 获取,可以使用网络图片,或者 base64,或者使用<image/>标签.请参考文档: https://mp.weixin.qq.com/ ...

  10. WC 2019 游记 - 败者之低语

    败者之低语 WC 2019 游记 Day -1 看了一圈PKU和THU的题,感觉图像识别真有意思... 感觉非常讲道理,pku还是比thu简单一点的... 听说高二414在thu没有进面试? 震惊!( ...