自定义JDBC框架

自定义JDBC框架

连接数据库的工具类(数据源):
DBCPUtils:
package com.heima.utils;

import java.awt.image.DataBuffer;
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 DBCPUtils {

	private static DataSource ds ;
	
	static {
		//将配置文件加载进来
		InputStream in = DBCPUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties") ;
		Properties props = new Properties() ;
		try {
			props.load(in) ;
			ds = BasicDataSourceFactory.createDataSource(props) ;
		} catch (Exception e) {
			throw new RuntimeException("服务器忙") ;
		}
	}
	
	//提供获取连接的方法
	public static Connection getConnection(){
		try {
			return ds.getConnection() ;
		} catch (SQLException e) {
			throw new RuntimeException("服务器忙") ;
		}
	}
}
dbcpconfig.properties:
自定义连接数据库的框架:
package com.heima.DBAssist;

import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.heima.handler.ResultHandler;
import com.heima.handler.impl.ResultSetHandlerImpl;
import com.heima.handler.impl.ResultSetListenerHandlerImpl;
import com.heima.utils.DBCPUtils;

//自定义框架
public class DBAsssist {

	
	// 执行添改删语句
	public boolean update(String sql, Object... params) {//sql:要执行的sql语句,params:sql语句中的参数(即?的值)
		// 拿到连接对象
		Connection conn = DBCPUtils.getConnection();
		int t = 0;
		try {
			// 创建预处理命令对象
			PreparedStatement pstmt = conn.prepareStatement(sql);
			// 对?进行赋值
			// 获取ParameterMetaData对象
			ParameterMetaData pmd = pstmt.getParameterMetaData();
			// 拿到?的个数
			int n = pmd.getParameterCount();
			if (n > 0) {
				// sql语句里有?号
				if (params == null || params.length != n) {
					throw new RuntimeException("参数的个数不匹配");
				}
				// 依次给每个?赋值
				for (int i = 0; i < n; i++) {
					pstmt.setObject(i + 1, params[i]);
				}
			}

			t = pstmt.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				conn.close(); // 还回池中了
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return t > 0 ? true : false;
	}

	// 执行查询语句
	public Object query(String sql,Class clazz, Object... params) {
		// 拿到连接对象
		Connection conn = DBCPUtils.getConnection();
		try {
			// 创建预处理命令对象
			PreparedStatement pstmt = conn.prepareStatement(sql);
			// 对?进行赋值
			// 获取ParameterMetaData对象
			ParameterMetaData pmd = pstmt.getParameterMetaData();
			// 拿到?的个数
			int n = pmd.getParameterCount();
			if (n > 0) {
				// sql语句里有?号
				if (params == null || params.length != n) {
					throw new RuntimeException("参数的个数不匹配");
				}
				// 依次给每个?赋值
				for (int i = 0; i < n; i++) {
					pstmt.setObject(i + 1, params[i]);
				}
			}

			ResultSet rs = pstmt.executeQuery();
			return new ResultSetListenerHandlerImpl().handler(rs, clazz) ;
		} catch (SQLException e) {
			throw new RuntimeException() ;
		} finally {
			try {
				conn.close(); // 还回池中了
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}
在执行查询功能时,查询到的结果应该封装到一个javabean中,编写一个类,实现把结果集中的数据封装到bean中:
ResultHandler.java:
package com.heima.handler;

import java.sql.ResultSet;
//此时的需求是把结果集封装到javabean中,用该接口来完成此功能
public interface ResultHandler {

	//返回封装的对象(结果集)
	/**
	 * 
	 * @param rs 要封装的结果集
	 * @param clazz  封装到的那个对象
	 * @return  封装的对象
	 */
	public Object handler(ResultSet rs,Class clazz) ;
}
handler.impl:
ResultSetHandlerImpl.java(只针对一条记录的):
package com.heima.handler.impl;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;

import com.heima.handler.ResultHandler;

//只适用于结果集只有一条记录的情况
//对象的属性名和表中的字段名应当一致
public class ResultSetHandlerImpl implements ResultHandler {

	@Override
	public Object handler(ResultSet rs, Class clazz) {
//结果集的属性名字要和封装到的那个对象的bean里面的属性名字一样
		//拿到结果集的元数据对象
		try {
			if(rs.next()){
				ResultSetMetaData rsmd = rs.getMetaData() ;
				//拿到共有多少列,即拿到列名,找到对应的类当中的对象,依次调用set方法,把值设进去
				int columnCount = rsmd.getColumnCount() ;
				//先创建对象
				Object obj = clazz.newInstance() ;
				for (int i = 0; i < columnCount; i++) {
					//拿到列名
					String columnName = rsmd.getColumnName(i+1) ;		
					//拿到对象对应的属性    列名就是属性的名字 
					Field field = clazz.getDeclaredField(columnName) ;
					//设置私有属性可以访问
					field.setAccessible(true) ;
					//拿到此列对应的值
					Object objectValue = rs.getObject(i+1) ;
					//给属性赋值
					field.set(obj, objectValue) ;
				}
				return obj ;
			}else
				return null ;
		} catch (Exception e) {
			throw new RuntimeException() ;
		}
	}

}
ResultSetListenerHandlerImpl.java(针对多条记录)
package com.heima.handler.impl;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

import com.heima.handler.ResultHandler;

//只适用于结果集有多条记录的情况
//对象的属性名和表中的字段名应当一致
public class ResultSetListenerHandlerImpl implements ResultHandler {

	@Override
	public Object handler(ResultSet rs, Class clazz) {
		
		List<Object> list = new ArrayList<Object>() ;
		//拿到结果集的元数据对象
		try {
			while(rs.next()){
				ResultSetMetaData rsmd = rs.getMetaData() ;
				//拿到公有多少列
				int columnCount = rsmd.getColumnCount() ;
				//先创建对象
				Object obj = clazz.newInstance() ;
				for (int i = 0; i < columnCount; i++) {
					//拿到列名
					String columnName = rsmd.getColumnName(i+1) ;		
					//拿到对象对应的属性
					Field field = clazz.getDeclaredField(columnName) ;
					//设置私有属性可以访问
					field.setAccessible(true) ;
					//拿到此列对应的值
					Object objectValue = rs.getObject(i+1) ;
					//给属性赋值
					field.set(obj, objectValue) ;
				}
				list.add(obj) ;
			}
			return list ;
		} catch (Exception e) {
			throw new RuntimeException() ;
		}
	}

}
bean:
package com.heima.bean;

import java.io.Serializable;

public class Account implements Serializable{

	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
				+ "]";
	}
	
	
	
}

Test:
package com.heima.test;

/**
 * use day16
 * create table account
 * (
 * 	   id int primary key,
 * 	   name varchar(30) ,
 * 	   money float
 * )
 */
import java.util.List;

import org.junit.Test;

import com.heima.DBAssist.DBAsssist;
import com.heima.bean.Account;

//测试自定义框架
public class Test2 {

	// 测试添加
	@Test
	public void test() {
		DBAsssist db = new DBAsssist();
		db.update("insert into account(id,name,money) values(?,?,?)", 2, "乔峰",
				2000);
	}

	// 测试更新
	@Test
	public void test1() {
		DBAsssist db = new DBAsssist();
		db.update("update account set money = money + ? where id = ?", 500, 1);
	}

	// 测试更新
	@Test
	public void test2() {
		DBAsssist db = new DBAsssist();
		db.update("delete from account where id = ?", 1);
	}

	// 测试查询
	@Test
	public void test3() {
		DBAsssist db = new DBAsssist();
		List<Account> list = (List<Account>)db.query("select * from account", Account.class) ;
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
基于JDBC实现自定义持久层框架可以分为以下几个步骤: 1. 设计数据访问接口:首先,你需要定义数据访问接口,包括插入、更新、删除和查询等操作的方法。这些方法应该是通用的,可适用于不同的实体类。 2. 编写实现类:接下来,你需要编写具体的实现类来实现数据访问接口。在这个实现类中,你可以使用JDBC来连接数据库,并执行SQL语句。 3. 定义实体类:为了与数据库中的表进行映射,你需要定义实体类。这些实体类应该与数据库表的结构相对应,并且包含与表中列对应的属性。 4. 建立连接:在进行数据库操作之前,你需要建立与数据库的连接。可以使用JDBC提供的`java.sql.Connection`对象来创建连接。 5. 执行SQL语句:通过使用JDBC提供的`java.sql.Statement`或`java.sql.PreparedStatement`对象,你可以执行SQL语句。可以通过编写动态SQL语句或使用预编译语句来实现各种操作。 6. 处理结果集:对于查询操作,你需要处理返回的结果集。可以使用JDBC提供的`java.sql.ResultSet`对象来遍历结果集并获取数据。 7. 关闭连接:完成数据库操作后,记得关闭连接以释放资源。可以使用`java.sql.Connection`对象的`close()`方法关闭连接。 通过以上步骤,你可以基于JDBC实现自定义持久层框架。当然,在实际应用中,你还可以考虑使用连接池、事务管理等技术来提高性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值