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. OpenCV——ROI截取、线性混合、通道分离、合并、亮度对比度调整

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

  2. JAVA框架 Spring 约束配置本地资源

    一:粘贴约束url:http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.or ...

  3. Jredis的使用范例

    简单使用 public class JedisTest { private static final Logger LOGGER = LoggerFactory.getLogger(JedisTest ...

  4. CPP2-基础部分(1)

    参考自<c++ primer 5th zh>,本系列将会接着将<The C++ Programming Language 4th Ed><c++ primer plus ...

  5. day59

    轮播图作业 <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF ...

  6. day 27

    今日内容: 关于面向对象的一些内置方法 1.__str__:在对象被打印时自动触发,可用来定义对象被打印. 注意:返回必须是一个字符串类型的值 ############################ ...

  7. php操作文件类的函数

    <?php /** // 一行一行读取一个文件 (文件内容很大的时候,适用.file_get_contents此场景就不太好) $re = fopen("index.php" ...

  8. URL最大长度

    今天在测试Email Ticket的时候发现在进行Mark as Read/Unread操作时,请求是通过GET方式进行的.URL中列出了所有参与该操作的Ticket Id.于是,我想起GET请求是有 ...

  9. 经常使用命令 echo、@、call、pause、rem

    经常使用命令 echo.@.call.pause.rem(小技巧:用::取代rem)是批处理文件最经常使用的几个命令,我们就从他们開始学起. 首先, @ 不是一个命令, 而是DOS 批处理的一个特殊标 ...

  10. excel的宏与VBA入门(三)——流程控制

    一.条件控制IF if 逻辑表达式 then 语句块 end if 带else的if语句: If 逻辑表达式1 Then 语句块1 ElseIf 逻辑表达式2 Then 语句块2 ElseIf 逻辑表 ...