通用的Java操作数据库工具类(原生JDBC,不使用DBUtils,c3p0等工具)
程序员文章站
2024-03-14 16:57:46
...
这几天给别人写作业遇到一个说问题不是问题,但是不说问题又还是有点问题的问题。是这样的,因为学生的作业嘛,也不是很难,只要实现基本的JDBC操作数据库就可以,但是每次写的时候都要去找以前的笔记,让我有点烦,所以我就索性专门写一篇博客来方便自己也方便他们写一个Java原生JDBC操作数据库的工具类,方便去使用。说明这就是原生的JDBC,没有使用什么连接池、工具包等东西,所以有些嫌繁琐的大佬勿喷,不过我以后会更新通过数据库连接池实现的通用的Java操作数据库的工具类。有一说一,这原生的JDBC其实也是蛮有意思的,还用到了元数据等知识。
注意:这个工具类使用到了元数据知识,所以在查询功能的方面要遵循使用元数据所对应的法则。
法则:要求我们写的sql语句的时候,都给字段名取一个别名, 别名就是entity类的属性名,注意大小写都要一致
做好这个工作就可以使用下面的代码了:
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;
public class DBUtils {
/*
* 通用的获取数据库连接的方法
*/
public static Connection getConnection() {
Connection conn = null;
try {
String driverClassName = "com.mysql.jdbc.Driver";//mysql数据库驱动
String url = "jdbc:mysql://localhost:3306/你数据库的名字?useUnicode=true&characterEncoding=utf-8";//mysql数据库url,springboot为数据库名
String username = "数据库的用户名";//mysql数据库用户名
String password = "数据库的密码";//mysql数据库密码
Class.forName(driverClassName);//注册mysql数据库驱动
conn = DriverManager.getConnection(url, username, password);//通过url,username,password获得数据库连接
}
catch (Exception e) {
System.out.println("获取数据库连接失败");
e.printStackTrace();
}
return conn;
}
/**
* 关闭连接的通用方法,先关闭结果集,再关闭statement,再关闭connection
* @param conn
* @param stat
* @param rs
*/
public static void close(Connection conn, Statement stat, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 这个方法用来实现通用的增改删,传入对应的sql语句
* @param sql
*/
public static Boolean cud(String sql, Object...args) {
Connection conn = null;
PreparedStatement prestatement = null;
int count = 0;
try {
conn = DBUtils.getConnection();
prestatement = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
prestatement.setObject(i+1, args[i]);
}
count = prestatement.executeUpdate();
if (count == 1) {
return true;
}else {
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
} finally {
DBUtils.close(conn, prestatement, null);
}
}
/**
* 通用的查询某个表的一条数据的方法
*
* @param clazz
* @param sql
* @param args
* @return
*/
public static <T> T getData(Class<T> clazz, String sql, Object... args) {
Connection conn = null;
PreparedStatement prestat = null;
ResultSet rs = null;
T entity = null;
ResultSetMetaData rsmd = null;
int columnCount = 0;
try {
// 1.连接数据库
conn = DBUtils.getConnection();
// 2.根据sql创建PrepareStatement对象
prestat = conn.prepareStatement(sql);
// 3.替换掉stat对象里的sql语句里的“?”占位符
for (int i = 0; i < args.length; i++) {
prestat .setObject(i + 1, args[i]);
}
// 4.从rs中拿出数据库取出的具体数据值
// 执行查询sql语句,获得结果集
rs = prestat .executeQuery();
if (rs.next()) {
// 首先通过反射拿到这种类型的对象
entity = (T) clazz.newInstance();
// 首先不知道entity里面有哪些属性,
// 通过结果集rs创建元数据对象
rsmd = rs.getMetaData();
// 根据元数据对象的getColumnCount()方法
// 来知道执行的查询sql语句中有几列
columnCount = rsmd.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
// 别名做key,值为value,因为不知道什么类型所以Object
String columnLabel = rsmd.getColumnLabel(i);
Object columnValue = rs.getObject(columnLabel);
Field field = clazz.getDeclaredField(columnLabel);
// 当isAccessible()的结果是false时不允许通过反射访问该字段
// 变成true就可以访问private修饰的了
field.setAccessible(true);
// 将属性的数值填充进去
field.set(entity, columnValue);
}
}
} catch (Exception exception) {
exception.printStackTrace();
} finally {
DBUtils.close(conn, prestat , rs);
}
return entity;
}
/**
* 通用的查询多条记录的方法,返回一个记录对象的集合
* @param clazz
* @param sql
* @param args
* @return
*/
public static <T> List<T> getListData(Class<T> clazz, String sql, Object... args) {
Connection conn = null;
PreparedStatement prestat = null;
ResultSet rs = null;
T entity = null;
ResultSetMetaData rsmd = null;
int columnCount = 0;
List<T> list = new ArrayList<T>();
try {
conn = DBUtils.getConnection();
prestat = conn.prepareStatement(sql);
for (int i = 0; i < args.length; i++) {
prestat .setObject(i + 1, args[i]);
}
rs = prestat .executeQuery();
if (rs.next()) {
entity = (T) clazz.newInstance();
rsmd = rs.getMetaData();
columnCount = rsmd.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
String columnLabel = rsmd.getColumnLabel(i);
Object columnValue = rs.getObject(columnLabel);
Field field = clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
field.set(entity, columnValue);
}
list.add(entity);
}
} catch (Exception exception) {
exception.printStackTrace();
} finally {
DBUtils.close(conn, prestat , rs);
}
return list;
}
}