编写JDBC框架:(策略设计模式)
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框架:(策略设计模式)的更多相关文章
- 【总结】编写自己的JDBC框架
一.数据库连接池: 在一般用JDBC 进行连接数据库进行CRUD操作时,每一次都会: 通过:java.sql.Connection conn = DriverManager.getConnection ...
- 黑马程序员—创建JDBC框架及原理分析
对于Java数据库的连接,由最初学习的每次全部手工代码,到后面的不断利用知识简化代码量:这是不断学习的过程,就像人类由原始社会的钻木取火到当代的文明,都是一步步过来的! 本文不从最开始的JDBC入门开 ...
- 编写自定义的JDBC框架与策略模式
本篇根据上一篇利用数据库的几种元数据来仿造Apache公司的开源DbUtils工具类集合来编写自己的JDBC框架.也就是说在本篇中很大程度上的代码都和DbUtils中相似,学完本篇后即更容易了解DbU ...
- java web学习总结(二十三) -------------------编写自己的JDBC框架
一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...
- javaweb学习总结(四十)——编写自己的JDBC框架
一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...
- javaweb总结(四十)——编写自己的JDBC框架
一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...
- 编写自己的JDBC框架(转)
一.元数据介绍 元数据指的是"数据库"."表"."列"的定义信息. 1.1.DataBaseMetaData元数据 Connection.g ...
- 编写自己的JDBC框架
目的 简化代码,提高开发效率 设计模式 策略设计模式 代码 #连接设置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost ...
- 实现简易JDBC框架
1 准备 JDBC 基本知识 JDBC元数据知识 反射基本知识 2: 两个问题 业务背景:系统中所有实体对象都涉及到基本的CRUD操作.所有实体的CUD操作代码基本相同,仅仅是发送给数据库的sql语 ...
随机推荐
- Actor模型---SwiftActors
actor是一个无线程区别的内存访问对象:actor背后有线程支持:actor的事件处理依赖与这个线程(队列.池). actor是一种面向对象的线程(池)模型,强调对事件的响应:在iOS中相当于一种通 ...
- Android4.4 ContentResolver查询图片无效 及 图库删除 增加图片后,ContentResolver不更新的问题解决
问题背景: 参考链接 做了一个图片浏览,用ContentResolver扫描图库照片,且严格按照时间拍摄顺序排好序显示在listview里.如下图所示: 遇到的问题是在4.2的手机上能正常显示,但是新 ...
- java过滤器filter使用
一:filter:过滤器,拦截servlet的请求和响应. 1. package jd.com.filter; import javax.servlet.*; import java.io.IOExc ...
- jsp泛型支持
今天在使用idea做练习时,某个jsp页面报错如下: '<>'operator is not allowed for source level below 1.7 出错代码如下: Map& ...
- day33
今日内容: 1.关于UDP传输的模拟实现 2.使用socketserver模块实现TCP传输的并发操作 3.进程理论的介绍 1.关于UDP传输的模拟实现 模拟UDP传输与之前的模拟TCP传输大致相同 ...
- java进阶的书籍
通过观看职话大数据论坛,了解到华信智原.项目总监就为我们推荐了一些JAVA程序员必看的书籍,使我们在学习过程中可以少走弯路.有些程序员在学习的时候总是急功近利,这里看看 那里学学,最后都不能把该掌握的 ...
- dom阻止事件冒泡
通常有两种事件流模型,一种是冒泡,一种是捕获.顾名思义,冒泡就是从内往外传播,捕获就是从外往里传播. 对于dom事件,就是这样的.比如,有两个父子div. <div id="pdiv& ...
- Debuggex – 超好用的正则表达式可视化调试工具
正则表达式通常被用来检索或替换符合某个模式的文本内容,编写正则是开发人员的必备技能.简单的正则表达式一下就能看懂含义,但是复杂的正则理解起来就很困难了.有了这款可视化的正则调试工具,以后编写正则表达式 ...
- word导入导出自定义属性列表
Sub ExportCustom() ' ' ExportCustom 宏 ' 导出自定义属性到custom.txt ' Dim lFileNumber As Long Dim sFilePath A ...
- jquery ajax error函数和及其参数详细说明(转载)
使用jquery的ajax方法向服务器发送请求的时候,常常需要使用到error函数进行错误信息的处理,本文详细的说明了ajax中error函数和函数中各个参数的用法.一般error函数返回的参数有三个 ...