优化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加载具体的驱动,就可以操作数据库. ...
随机推荐
- 将jpg压缩成webp格式的图片
cwebp名称 cwebp -压缩图像文件为的WebP文件概要 cwebp [选项] INPUT_FILE -o output_file.webp描述 cwebp压缩使用的WebP格式的图像.输入格式 ...
- BZOJ4517:[SDOI2016]排列计数(组合数学,错排公式)
Description 求有多少种长度为 n 的序列 A,满足以下条件: 1 ~ n 这 n 个数在序列中各出现了一次 若第 i 个数 A[i] 的值为 i,则称 i 是稳定的.序列恰好有 m 个数是 ...
- Hive学习之路 (十四)Hive分析窗口函数(二) NTILE,ROW_NUMBER,RANK,DENSE_RANK
概述 本文中介绍前几个序列函数,NTILE,ROW_NUMBER,RANK,DENSE_RANK,下面会一一解释各自的用途. 注意: 序列函数不支持WINDOW子句.(ROWS BETWEEN) 数据 ...
- ES6新特性5:类(Class)和继承(Extends)
本文摘自ECMAScript6入门,转载请注明出处. 一.类(Class) 1.基本语法 JavaScript语言的传统方法是通过构造函数,定义并生成新对象.下面是一个例子 function Poin ...
- 豆瓣电影top250爬取并保存在MongoDB里
首先回顾一下MongoDB的基本操作: 数据库,集合,文档 db,show dbs,use 数据库名,drop 数据库 db.集合名.insert({}) db.集合名.update({条件},{$s ...
- Python自动化之__unicode__
def __unicode__(self): return u'%s %s' % (self.first_name, self.last_name) 如果定义了__unicode__()方法但是没有定 ...
- PAT乙级1017
1017 A除以B (20 分) 本题要求计算 A/B,其中 A 是不超过 1000 位的正整数,B 是 1 位正整数.你需要输出商数 Q 和余数 R,使得 A=B×Q+R 成立. 输入格式: 输 ...
- P1437 [HNOI2004]敲砖块
题目描述 在一个凹槽中放置了 n 层砖块.最上面的一层有n 块砖,从上到下每层依次减少一块砖.每块砖 都有一个分值,敲掉这块砖就能得到相应的分值,如下图所示. 14 15 4 3 23 33 33 7 ...
- Spring Cloud和Dubbo整合开发笔记(1)
一.需求背景: 公司内部老项目微服务技术栈使用Dubbo, 新项目技术栈使用主流的Spring Cloud相关组件开发,新旧项目涉及交互调用,无法直接通信数据传递. 老项目基于Dubbo,重构代码升级 ...
- .NET中Quartz任务调度器的简单应用实例
1.首先从NuGet中安装Quartz,安装最新版本就OK 2.新建一个Job类实现Quart中的IJob接口用于执行业务逻辑,代码如下: class CheckUpdateJob : IJob { ...