package com.softeem.util;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.*;
/**
* 封装驱动加载
* 获取连接
* 基本的增删改操作
* 查询单个信息的操作
*/
public class DBUtils {
public static String driver;
public static String url;
public static String username;
public static String password;
//读取文件并且加载驱动
static{
try {
//创建一个输入流,用来读取属性文件
//DBUtils.class:获取到当前正在执行的类
//1、如果配置文件和DBUtils放在同一个目录中的时候就不需要加getClassLoader,也不需要加/
//2、如果放在src目录中的时候,就需要在目录前面加"/"或者加getClassLoader
InputStream is = DBUtils.class.getResourceAsStream("jdbc.properties");
//创建一个Properties对象
Properties p = new Properties();
//将输入流信息加载到属性中
p.load(is);
//根据属性名称获取属性值
driver = p.getProperty("driver");
url = p.getProperty("url");
username = p.getProperty("username");
password = p.getProperty("password");
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConn(){
try {
return DriverManager.getConnection(url,username,password);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 封装通用的更新操作,对所有更新(Insert Update Delete)相关的操作进行实现
* @param sql 数据库操作语句
* @param obj 需要提供的参数
* @return
*/
public static boolean exeUpdate(String sql,Object... obj){
Connection conn = null;//创建连接
PreparedStatement ps = null;//sql语句的预处理
try {
conn = getConn();//开启连接
ps = conn.prepareStatement(sql);//处理sql语句
for(int i = 0; i < obj.length; i++){//将所有的参数进行遍历
ps.setObject(i + 1,obj[i]);//第一个参数是要处理的占位符,第二个参数是添加的值
}
return ps.executeUpdate() > 0;//判断影响是否大于0条
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(ps,conn);
}
return false;
}
/**
* 封装方法用来获取单个的对象
* @param t
* @param sql
* @param params
* @param <T>
* @return
*/
public static <T> T queryOne(Class<T> t,String sql,Object... params){
T obj = null;//创建一个对象
Connection conn = null;
PreparedStatement ps = null;
try {
conn = getConn();//获取连接
ps = conn.prepareStatement(sql);//将sql语句进行预处理
for(int i = 0; i < params.length; i++){
ps.setObject(i + 1,params[i]);
}
ResultSet rs = ps.executeQuery();
//通过主键来获取到相关的信息,使用的是类似主键唯一的那个方式
ResultSetMetaData rsmd = rs.getMetaData();
//对象关系映射的操作
if(rs.next()){
//创建一个指定类型的实例对象(必须包含默认的构造函数)
//相当于将要查询的数据的类的对象创建好,
//然后将这个类中的属性全部列出来,
//数据库中查找到的信息赋值给类中的属性
obj = t.newInstance();//进行了类的关系映射 比如是一个student类的话,Student s = new Student();
//获取到这个结果集中一共有多少个列
for(int i = 0; i < rsmd.getColumnCount(); i++){
//获取指定的列的名称
String cname = rsmd.getColumnLabel(i + 1);
//获取到列的值
Object value = rs.getObject(cname);
//判断这个值是否为空
if(Objects.nonNull(value)){
//根据列名获取java类中的属性名
//要求表中给的列名称必须与类中的属性名保持一致
Field field = t.getDeclaredField(cname);
//将字段设置为了可以访问的状态
field.setAccessible(true);
//为字段设置属性值
field.set(obj,value);
}
}
}
} catch (SQLException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
return obj;
}
/**
* 技术参数:
* 集合框架 泛型 反射 JDBC封装
* 封装一个通用的查询多条信息的操作
* @param t
* @param sql
* @param params
* @param <T>
* @return
*/
public static <T>List<T> queryList(Class<T> t,String sql,Object... params) throws SQLException, IllegalAccessException, InstantiationException, NoSuchFieldException {
List<T> list = new ArrayList<T>();//创建一个集合用来存储查找到的信息
T obj = null;//定义一个变量,先将信息存储到对象里面,然后再将对象存储在集合中
Connection conn = null;
PreparedStatement ps = null;
conn = getConn();//创建连接
ps = conn.prepareStatement(sql);//将sql语句放入到预处理平台
for (int i = 0; i < params.length; i++){//使用循环遍历传入有的参数的数组
ps.setObject(i + 1,params[i]);
}
ResultSet rs = ps.executeQuery();//确定做的是查询操作需要得到一个结果集
ResultSetMetaData rsmd = rs.getMetaData();//获取查询结果集中的源数据(获取列类型,数量以及长度等信息)
Map<String,Object> map = new HashMap<String,Object>();//创建一个map集合,将信息存储进去
//遍历结果集
while (rs.next()){
map.clear();//在存储第二条信息之前,将之前的缓存信息全部清除
//遍历所有的列
for(int i = 0; i < rsmd.getColumnCount(); i++){
//获取列名
String cname = rsmd.getColumnName(i + 1);
//获取列类型的int表示形式,以及列类型名称
//System.out.println("列类型:" + rsmd.getColumnName(i + 1) + "-----" + rsmd.getColumnTypeName(i + 1));
//获取列中的值
Object value = rs.getObject(cname);
//将列名和列值存储到map集合中
map.put(cname,value);//处理的是数据库中的数据
}
//利用反射将map集合中的数据注入对象的属性中,然后将对象存储到集合中
if(!map.isEmpty()){
//获取到了map集合中的键集(列名的集合)
Set<String> columnNames = map.keySet();
//上面创建过一个对象,使用反射的形式进行对象的赋值
obj = t.newInstance();
//System.out.println(obj);
for (String column : columnNames){//遍历键集
//根据键来找到值
Object value = map.get(column);
//判断当前数据对象是不是为空,如果不为空,就注入到属性中
if(Objects.nonNull(value)){
//获取属性对象
Field f = t.getDeclaredField(column);
//设置属性为可以访问的状态 暴力访问
f.setAccessible(true);
//将值给了属性
f.set(obj,value);
}
}
list.add(obj);
}
}
return list;
}
public static void close(Statement stmt,Connection conn){
try {
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
//测试连接是否成功
System.out.println(getConn());
}
}
JDBC封装(增删改查已经全部封装好)
最新推荐文章于 2022-09-07 22:32:39 发布