优化JDBC开发
一、元数据
元数据:数据库、表、列的定义信息
1、DataBaseMetaData对象
getURL():返回一个String类对象,代表数据库的URL。
getUserName():返回连接当前数据库管理系统的用户名。
getDatabaseProductName():返回数据库的产品名称。
getDatabaseProductVersion():返回数据库的版本号。
getDriverName():返回驱动驱动程序的名称。
getDriverVersion():返回驱动程序的版本号。
isReadOnly():返回一个boolean值,指示数据库是否只允许读操作。
/**
* 获取数据库的元数据
* @throws SQLException
*/
@Test
public void test1() throws SQLException{
Connection con = JdbcUtils_DBCP.getConnection(); //获取数据库的元数据
DatabaseMetaData meta = con.getMetaData();
//获取数据库的版本
System.out.println(meta.getDatabaseMajorVersion());
//获取数据库的产品名称
System.out.println(meta.getDatabaseProductName());
//获取数据库默认的隔离级别
System.out.println(meta.getDefaultTransactionIsolation()); /**
* 结果:
* 5
MySQL
2
*
*/
}
2、 ParameterMetaData对象
PreparedStatement . getParameterMetaData()
获得代表PreparedStatement元数据的ParameterMetaData对象。
Select * from user where name=? And password=?
ParameterMetaData对象
getParameterCount()
获得指定参数的个数
getParameterType(int param)
获得指定参数的sql类型
/**
* 获取参数元数据
* @throws SQLException
*/
@Test
public void test2() throws SQLException{
Connection con = JdbcUtils_DBCP.getConnection();
String sql = "insert into account(name,money) values(?,?)";
//预编译sql语句
PreparedStatement ps = con.prepareStatement(sql);
//获取参数元数据
ParameterMetaData meta = ps.getParameterMetaData(); //获取参数的个数 结果:2
System.out.println(meta.getParameterCount()); //获取参数的类型
System.out.println(meta.getParameterType(1));
}
3、ResultSetMetaData对象
ResultSet. getMetaData()
获得代表ResultSet对象元数据的ResultSetMetaData对象。
ResultSetMetaData对象
getColumnCount()
返回resultset对象的列数
getColumnName(int column)
获得指定列的名称
getColumnTypeName(int column)
获得指定列的类型
/*
* 获取结果集元数据
*/ @Test
public void test3() throws SQLException{
Connection con = JdbcUtils_DBCP.getConnection();
String sql = "select * from account";
//预编译sql语句
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery(); //获取元数据
ResultSetMetaData meta = rs.getMetaData();
System.out.println(meta.getColumnCount());
System.out.println(meta.getColumnName(1));
System.out.println(meta.getColumnName(2));
System.out.println(meta.getColumnName(3)); //结果:id name money
}
二、对JDBC进行优化
1、对增、删、改进行优化
所有实体的CUD操作代码基本相同,仅仅发送给数据库的SQL语句不同而已,因此可以把CUD操作的所有相同代码抽取到工具类的一个update方法中,并定义参数接收变化的SQL语句。
//优化JDBC的增、删、改
/**
*
* @param sql 接受参数
* @param params 参数 替换掉sql语句的?号
* @throws SQLException
*/
public static void create_delete_update(String sql,Object params[]) throws SQLException{
Connection con = null;
PreparedStatement st = null;
ResultSet result = null; try{
con = getConnection();
st = con.prepareStatement(sql); //把sql的?号替换掉
for(int i=0;i<params.length;i++){ //因为不清楚表的列数据是什么类型,所以用Object
st.setObject(i+1,params[i]);
} st.executeUpdate(); }finally{
release(con, st, result);
}
}
2、对查找进行优化
//优化sql查询
public static Object query(String sql,Object params[],ResultSetHandler handler) throws SQLException{
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
con = getConnection();
st = con.prepareStatement(sql);
//替代问号
for(int i=0;i<params.length;i++){
st.setObject(i+1, params[i]);
} //执行
rs = st.executeQuery(); //由于不知道调用者怎么处理结果集,所有由调用者调用时传入一个处理器对象,调用处理器对象的处理方法
return handler.handler(rs);
}finally{
release(con, st, rs);
}
} } //暴露接口
interface ResultSetHandler{
public Object handler(ResultSet rs);
} //实现把结果封装到bean里面,适用于查找一条数据
class BeanHandler implements ResultSetHandler{
Class clazz;
public BeanHandler(Class clazz){
this.clazz = clazz;
} //处理方法,把数据封装到javabean
public Object handler(ResultSet rs) {
try {
if(!rs.next()){
return null;
} //创建封装结果的bean对象
Object bean = clazz.newInstance(); //得到结果集数的元数据,已获取结果集的信息
ResultSetMetaData meta = rs.getMetaData(); //得到结果集的列数
int count = meta.getColumnCount(); //for循环赋值给bean对象
for(int i=0;i<count;i++){
String name = meta.getColumnName(i+1);
Object value = rs.getObject(name); //反射出bean上与列名相应的属性
Field f = bean.getClass().getDeclaredField(name);
//由于属性是私有的,要把属性设置成可见的
f.setAccessible(true);
//设置属性
f.set(bean, value);
} return bean;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} //把结果封装到一个集合里面去
class BeanListHandler implements ResultSetHandler{
Class clazz;
public BeanListHandler(Class clazz){
this.clazz = clazz;
} public Object handler(ResultSet rs){
List list = new ArrayList();
try{
while(rs.next()){
//创建bean对象
Object bean = clazz.newInstance();
ResultSetMetaData meta = rs.getMetaData(); //获取列数
int count = meta.getColumnCount();
for(int i=0;i<count;i++){
//列名
String name = meta.getColumnName(i+1);
Object value = rs.getObject(name);
Field f = bean.getClass().getDeclaredField(name);
f.setAccessible(true);
f.set(bean, value);
}
list.add(bean);
}
}catch(Exception e){
throw new RuntimeException(e);
}
return list;
}
}
3、完整代码
package com.utils;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory; public class DButils { //数据库连接池
private static DataSource ds = null;
static{
try{
//读取配置文件
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties prop = new Properties();
prop.load(in);
BasicDataSourceFactory factory = new BasicDataSourceFactory();
//创建连接池
ds = factory.createDataSource(prop);
}catch(Exception e){
throw new ExceptionInInitializerError(e);
}
} //获取连接
public static Connection getConnection() throws SQLException{ return ds.getConnection();
} //释放资源
public static void release(Connection con,Statement st,ResultSet result){
if(result!=null){
try {
result.close();
} catch (Exception e) {
e.printStackTrace();
}
result = null;
} if(st!=null){
try {
st.close();
} catch (Exception e) {
e.printStackTrace();
}
st = null;
} if(con!=null){
try {
con.close();
} catch (Exception e) {
e.printStackTrace();
} }
} //优化JDBC的增、删、改
/**
*
* @param sql 接受参数
* @param params 参数 替换掉sql语句的?号
* @throws SQLException
*/
public static void create_delete_update(String sql,Object params[]) throws SQLException{
Connection con = null;
PreparedStatement st = null;
ResultSet result = null; try{
con = getConnection();
st = con.prepareStatement(sql); //把sql的?号替换掉
for(int i=0;i<params.length;i++){ //因为不清楚表的列数据是什么类型,所以用Object
st.setObject(i+1,params[i]);
} st.executeUpdate(); }finally{
release(con, st, result);
}
} //优化sql查询
public static Object query(String sql,Object params[],ResultSetHandler handler) throws SQLException{
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
try{
con = getConnection();
st = con.prepareStatement(sql);
//替代问号
for(int i=0;i<params.length;i++){
st.setObject(i+1, params[i]);
} //执行
rs = st.executeQuery(); //由于不知道调用者怎么处理结果集,所有由调用者调用时传入一个处理器对象,调用处理器对象的处理方法
return handler.handler(rs);
}finally{
release(con, st, rs);
}
} } //暴露接口
interface ResultSetHandler{
public Object handler(ResultSet rs);
} //实现把结果封装到bean里面,适用于查找一条数据
class BeanHandler implements ResultSetHandler{
Class clazz;
public BeanHandler(Class clazz){
this.clazz = clazz;
} //处理方法,把数据封装到javabean
public Object handler(ResultSet rs) {
try {
if(!rs.next()){
return null;
} //创建封装结果的bean对象
Object bean = clazz.newInstance(); //得到结果集数的元数据,已获取结果集的信息
ResultSetMetaData meta = rs.getMetaData(); //得到结果集的列数
int count = meta.getColumnCount(); //for循环赋值给bean对象
for(int i=0;i<count;i++){
String name = meta.getColumnName(i+1);
Object value = rs.getObject(name); //反射出bean上与列名相应的属性
Field f = bean.getClass().getDeclaredField(name);
//由于属性是私有的,要把属性设置成可见的
f.setAccessible(true);
//设置属性
f.set(bean, value);
} return bean;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
} //把结果封装到一个集合里面去
class BeanListHandler implements ResultSetHandler{
Class clazz;
public BeanListHandler(Class clazz){
this.clazz = clazz;
} public Object handler(ResultSet rs){
List list = new ArrayList();
try{
while(rs.next()){
//创建bean对象
Object bean = clazz.newInstance();
ResultSetMetaData meta = rs.getMetaData(); //获取列数
int count = meta.getColumnCount();
for(int i=0;i<count;i++){
//列名
String name = meta.getColumnName(i+1);
Object value = rs.getObject(name);
Field f = bean.getClass().getDeclaredField(name);
f.setAccessible(true);
f.set(bean, value);
}
list.add(bean);
}
}catch(Exception e){
throw new RuntimeException(e);
}
return list;
}
}
测试:
package com.utils; import java.sql.SQLException;
import java.util.Iterator;
import java.util.List; import org.junit.Test; import com.domain.Account; public class Demo { //测试添加
@Test
public void testAdd() throws SQLException{
Account a = new Account();
a.setName("陈海宏");
a.setMoney(30);
add(a);
} @Test
//测试删除
public void testDelete() throws SQLException{
delete(1);
} @Test
//测试更改
public void testUpdate() throws SQLException{
Account a = new Account();
a.setId(2);
a.setName("王五");
a.setMoney(30);
update(a);
} @Test
//测试查找单项记录
public void testFind() throws SQLException{
Account a = find(7);
System.out.println(a.getName());
} //测试查找单记录
@Test
public void testGetAll() throws SQLException{
List list = getAll();
//对集合进行迭代
Iterator it = list.iterator();
while(it.hasNext()){
Account a = (Account) it.next();
System.out.println(a.getId()+"+"+a.getName()+"+"+a.getMoney()); }
} //添加
public void add(Account a) throws SQLException{ //准备sql语句
String sql = "insert into account(name,money) values(?,?)";
//替换?的参数数据
Object params[] = {a.getName(),a.getMoney()};
DButils.create_delete_update(sql, params); } //删除
public void delete(int id) throws SQLException{ //准备sql语句
String sql = "delete from account where id=?";
//替换?的参数数据
Object params[] = {id};
DButils.create_delete_update(sql, params);
} //更新
public void update(Account a) throws SQLException{
String sql = "update account set name = ?,money = ? where id=?";
Object params[] = {a.getName(),a.getMoney(),a.getId()};
DButils.create_delete_update(sql, params);
} //查找单项记录
public Account find(int i) throws SQLException{
String sql = "select * from account where id=?";
Object params[] = {i};
return (Account) DButils.query(sql, params,new BeanHandler(Account.class));
} //查找所有记录
public List getAll() throws SQLException{
String sql = "select * from account";
Object params[] = {};
return (List) DButils.query(sql, params,new BeanListHandler(Account.class));
}
}
优化JDBC开发的更多相关文章
- DbUtils是Apache出品一款简化JDBC开发的工具类
DbUtils - DbUtils是Apache出品一款简化JDBC开发的工具类 - 使用DbUtils可以让我们JDBC的开发更加简单 - DbUtils的使用: ...
- spark之JDBC开发(连接数据库测试)
spark之JDBC开发(连接数据库测试) 以下操作属于本地模式操作: 1.在Eclipse4.5中建立工程RDDToJDBC,并创建一个文件夹lib用于放置第三方驱动包 [hadoop@CloudD ...
- 优化JDBC编程-多提提意见
优化JDBC编程这是我根据MS SQL SERVER 2000 JDBC DRIVER HELP,并参考其它资料整理而成.ms的这个帮助文件实在有失大家风范,示例代码很.....有兴趣者可以去下载ht ...
- JAVA基础之JDBC开发、JSTL语法、EL表达式与数据分页
一.直接使用JDBC开发的问题 1.当表中的列很多时,需要写很长的SQL语句 还需要写大量 setXXX() 设置参数语句 读取数据时还需要写大量setXXXX()设置属性语句 2.非常容易出错,而且 ...
- JDBC开发,数据库的连接
JDBC开发步骤 1.建完工程后,右击工程,new,新建一个文件夹Folder,装jar包, 2.将下载好的驱动包打开,找到jar文件,CTRL+C,选中装jar包的文件夹,CTRL+V ...
- Spring+SpringMVC+MyBatis+easyUI整合优化篇(九)数据层优化-jdbc连接池简述、druid简介
日常啰嗦 终于回到既定轨道上了,这一篇讲讲数据库连接池的相关知识,线程池以后有机会再结合项目单独写篇文章(自己给自己挖坑,不知道什么时候能填上),从这一篇文章开始到本阶段结束的文章都会围绕数据库和da ...
- 数据层优化-jdbc连接池简述、druid简介
终于回到既定轨道上了,这一篇讲讲数据库连接池的相关知识,线程池以后有机会再结合项目单独写篇文章(自己给自己挖坑,不知道什么时候能填上),从这一篇文章开始到本阶段结束的文章都会围绕数据库和dao层的优化 ...
- 前端网络、JavaScript优化以及开发小技巧
一.网络优化 YSlow有23条规则,中文可以参考这里.这几十条规则最主要是在做消除或减少不必要的网络延迟,将需要传输的数据压缩至最少. 1)合并压缩CSS.JavaScript.图片,静态资源CDN ...
- JDBC开发
1.JDBC简介 )数据库驱动 )Sun公司为简化数据库开发,定义了一套jdbc接口,这套接口由数据库厂商去实现,这样,开发人员只需要学习jdbc接口,并通过jdbc加载具体的驱动,就可以操作数据库. ...
随机推荐
- IKVM.NET入门(1)
IKVM.NET是一个针对Mono和微软.net框架的java实现,其设计目的是在.NET平台上运行java程序.本文将比较详细的介绍这个工具的原理.使用入门(如何java应用转换为.NET应用.如何 ...
- 原生js实现一个DIV的碰撞反弹运动
原生js实现一个DIV的碰撞反弹运动: 关键在于DIV的边界检测,进而改变运动方向,即可实现碰撞反弹效果. <!DOCTYPE html> <html lang="en& ...
- 4-4 R语言函数 tapply
#对向量的子集进行操作 #tapply(参数):tapply(向量,因子/因子列表,函数/函数名) > x <- c(rnorm(5),runif(5),rnorm(5,1)) > ...
- 切换composer国内镜像
composer config -g repo.packagist composer https://packagist.phpcomposer.com
- 【openjudge】【字符串+模拟】1777:文件结构“图”
[题目传送门:]戳 [描述:] 在计算机上看到文件系统的结构通常很有用.Microsoft Windows上面的"explorer"程序就是这样的一个例子.但是在有图形界面之前,没 ...
- [USACO08NOV]lites
嘟嘟嘟 竟然还能发现这么水的题.就是线段树维护区间亦或嘛~~~~ #include<cstdio> #include<iostream> #include<algorit ...
- leetcode 217. Contains Duplicate 287. Find the Duplicate Number 442. Find All Duplicates in an Array 448. Find All Numbers Disappeared in an Array
后面3个题都是限制在1-n的,所有可以不先排序,可以利用巧方法做.最后两个题几乎一模一样. 217. Contains Duplicate class Solution { public: bool ...
- 多线程之线程间协作的两种方式:wait、notify、notifyAll和Condition
Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...
- MySQL数据库启停
坑1:net start mysql 提示:服务名无效 1.win+R打开运行窗口,输入services.msc 2.在其中查看mysql的服务名,我的是MySQL55 3.以管理员身份打开cmd,输 ...
- 【题解】洛谷P1070 道路游戏(线性DP)
次元传送门:洛谷P1070 思路 一开始以为要用什么玄学优化 没想到O3就可以过了 我们只需要设f[i]为到时间i时的最多金币 需要倒着推回去 即当前值可以从某个点来 那么状态转移方程为: f[i]= ...