在使用JDBC连接技术时我们反复创建连接,或者每次进行DML操作以及查询时需要写大量的代码,很是繁琐,下面我们用一些常见的技术把这些操作封装起来,实现一个简单的框架,这个框架具有以下功能:
1.获取数据库连接(通过配置文件)
2.将传入装入属性信息的map集合转化为一个对象
3.将查询到信息转化为一个对象(返回一个对象)
4.将查询多个信息转化为多个对象(返回一个装有对象的动态数组集合)
5.将查询到的信息装入map集合然后装进list集合并返回查询结果
6.执行DML操作
7.支持事务的DML操作
8.关闭连接、结果集、StateMent对象
用到技术:集合框架,jdbc连接技术,反射,泛型接口、方法
我们定义一个类作为我们的框架:
首先我们创建一个配置文件(配置数据库信息)
注意:先要导入数据库连接驱动,eclipsec通过构建路径配置驱动jar包,Idea通过Alt+shift+ctrl+s进入Project Structure找到Dependencies添加驱动包应用即可,还有一种方式这里不再赘述,读者可以参阅网上的教程,下面我们看一下代码实现。
代码:
package com.softeem.jdbc;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.*;
/**
* 实现一个简单jdbc操作的简单的框架
*
* @Author GQ 2020/8/7 14:59
*/
public class DBUtilsMyself {
/**
* 驱动类名
*/
private static final String DRIVER_CLASS;
/**
* 数据库密码
*/
private static final String PASSWORD;
/**
* 数据库用户名
*/
private static final String USER;
/**
* 数据库路径
*/
private static final String URL;
/**
* map集合转化的对象
*/
private static Object obj;
static {
//创建属性类读取配置
Properties p = new Properties();
try {
//获取流(放入配置文件路径即可)
InputStream is = new FileInputStream("C:\\Users\\14252\\Desktop\\配置文件\\数据库配置文件.txt");
//加载流
p.load(is);
System.out.println(is);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
DRIVER_CLASS = p.getProperty("driver");
URL = p.getProperty("url");
// 数据库服务器登录用户名
USER = p.getProperty("user");
// 数据库服务器登录密码
PASSWORD = p.getProperty("password");
}
/***
* 获取连接
*/
public static Connection getCon() {
Connection conn = null;
try {
//加载驱动
Class.forName(DRIVER_CLASS);
//获取连接
conn = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (SQLException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return conn;
}
/**
* 关闭资源
*
* @param conn
* @param rs
* @param ps
*/
public static void close(Connection conn, ResultSet rs, Statement ps) {
try {
if (conn != null) {
conn.close();
}
if (rs != null) {
rs.close();
}
if (ps != null) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
/***
* 将map集合转化为对象
* @param <T>
* @return
*/
private static <T> T mapToBean(Class<T> t, Map<String, Object> map) {
try {
//获取实例
obj = t.newInstance();
//将map集合中的键值对结构属性转化为对象属性,这里一个k代表一个属性,v代表值
map.forEach((k, v) -> {
//通过键获取属性
try {
Field filed = t.getDeclaredField(k);
//设置属性可见
filed.setAccessible(true);
//给属性赋值
filed.set(obj, v);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
});
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return (T) obj;
}
/**
* 通过sql语句以及相关参数查询结果以键值对结构装入到map集合
* 并将map装入到List集合返回
*
* @param sql
* @param params
* @return
*/
public static List<Map<String, Object>> queryList(String sql, Object... params) {
//创建集合接收值
List<Map<String, Object>> list = new ArrayList<>();
//获取连接
Connection conn = getCon();
ResultSet rs = null;
PreparedStatement ps = null;
try {
//得到执行sql语句的PreparedStateMent对象
ps = conn.prepareStatement(sql);
//通过循环给预编译的语句给值
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
//通过查询获得结果集
rs = ps.executeQuery();
//获取查询结果元数据
ResultSetMetaData metaData = rs.getMetaData();
//获取元数据查询结果列数
int columnCount = metaData.getColumnCount();
while (rs.next()) {
//创建map集合放入查询到的结果
Map<String, Object> map = new HashMap<>();
//取出每一列值加入到map集合中
for (int i = 0; i < columnCount; i++) {
//获取标签值
String label = metaData.getColumnName(i + 1);
//获取查询到的值
Object obj = rs.getObject(label);
//获取列名
String key = metaData.getColumnName(i + 1);
//将查询到元素放入到集合
if (obj != null) {
map.put(key, obj);
}
}
//将map放入到List集合
list.add(map);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭资源
close(conn, rs, ps);
}
return list;
}
/**
* @param sql
* @param params
* @param <T>
* @return
*/
public static <T> T queryOne(Class<T> t, String sql, Object... params) {
//查询一个,掉用queryList得到结果
List<Map<String, Object>> list = queryList(sql, params);
//获取查询到的一个结果
Map<String, Object> map = list.get(0);
//将map集合转化为对象并且返回
return mapToBean(t, map);
}
/**
* 执行DML语句
* @param sql
* @param params
* @return
*/
public static boolean executeUpdate(String sql, Object... params) {
//获取连接
Connection conn = getCon();
return executeUpdate(conn,sql,params);
}
/**
* 支持事务的DML操作方法
* 因为事务需要保证同一连接
* @param conn
* @param sql
* @param params
* @return
*/
public static boolean executeUpdate(Connection conn,String sql,Object...params){
PreparedStatement ps = null;
try {
//得到执行sql语句的PreparedStateMent对象
ps = conn.prepareStatement(sql);
//通过循环给预编译的语句给值
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
//执行,如果结果大于0执行成功返回true
return ps.executeUpdate() > 0;
} catch (SQLException e) {
e.printStackTrace();
}finally{
//关闭资源
close(conn,null,ps);
}
return false;
}
public static <T> List<T> queryBeanList(Class<T> t,String sql,Object...params){
//创建集合存储对象
List<T>list=new ArrayList<>();
//接收查询到的结果
List<Map<String, Object>> maps = queryList(sql, params);
maps.forEach(map->{
//将查询到的集合转化为对应对象
T tt=mapToBean(t,map);
//将查询到结果放入到list集合中
list.add(tt);
});
return list;
}
}
上面程序可以满足大部分查询,更新操作,简化了代码,无需每次访问数据库都重写一样的代码,通过封装操作,在进行dao层操作时非常方便。上面代码由于作者写的比较快,也只做了一些简单的测试,如果有那里不对的地方请联系作者以及时更改!