【javaee】【分享】一个jdbc实现增删改查的工具类,感觉写的挺好用的
本帖最后由 夏橙M兮 于 2018-12-20 10:38 编辑利用反射给类赋值。适合初学者,没有学过数据层框架类的人。
实现动静态sql赋值。首先你得创建一个数据库bean类,属性的名字与数据库表的字段名相同。之后要查询数据就调用方法。另外还要在src下建一个jdbc.properties。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/**
user=root
password=root
内容根据自己数据库适当修改。
package com.benxi.util;
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.naming.spi.DirStateFactory.Result;
public class JDBCUtils {
private static Statement st;
private static String url;
private static String driver;
private static String user;
private static String password;
static{
try {
//从jdbc.properties文件中获取数据初始化链接的值
Properties pro=new Properties();
InputStream is=JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
pro.load(is);
driver=pro.getProperty("driver");
url=pro.getProperty("url");
user=pro.getProperty("user");
password=pro.getProperty("password");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
// 创建连接
private static Connection getConnection() throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
Class.forName(driver);
return DriverManager.getConnection(url,user,password);
}
//获取statement对象
private static Statement createStatement(Connection con) throws SQLException{
// TODO Auto-generated method stub
return con.createStatement();
}
//获取preparedStatement对象
public static PreparedStatement preparedStatement(Connection con,String sql) throws SQLException{
return con.prepareStatement(sql);
}
// 执行一条静态SQL命令
public static int execUpdates(String sql) throws SQLException, ClassNotFoundException {
Connection con = getConnection();
Statement st = createStatement(con);
int iCount = st.executeUpdate(sql);
closeConnection(con, st, null, null);
return iCount;
}
// 执行多条静态SQL命令
public static int[] execUpdates(String[] sql) throws SQLException, ClassNotFoundException {
Connection con = getConnection();
Statement st = createStatement(con);
for (int i = 0; i < sql.length; i++) {
st.addBatch(sql);
}
int[] iCount = st.executeBatch();
closeConnection(con, st, null, null);
return iCount;
}
// 执行一条动态的SQL命令
public static int execUpdate(String sql,Object[] params) throws SQLException, ClassNotFoundException {
Connection con = getConnection();
PreparedStatement pst = preparedStatement(con, sql);
for (int i = 1; i<=params.length; i++) {
pst.setObject(i, params);
}
int iCount=pst.executeUpdate();
closeConnection(con, null, pst, null);
return iCount;
}
// 执行一条静态SQL命令
public static <T> List<T> execQuery(String sql, Class classs)
throws SQLException, InstantiationException, IllegalAccessException, ClassNotFoundException {
Connection con = getConnection();
Statement st = createStatement(con);
List<T> list = new ArrayList<T>();
ResultSet rs = st.executeQuery(sql);
ResultSetMetaData rsmd = rs.getMetaData();
Field[] fields = classs.getDeclaredFields();
if (rs != null) {
while (rs.next()) {
T t = (T) classs.newInstance();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
String colName = rsmd.getColumnName(i);
for (int j = 0; j < fields.length; j++) {
String fieldName = fields.getName();
if (colName.equals(fieldName)) {
// 赋值
boolean iRet = fields.isAccessible();
fields.setAccessible(true);
fields.set(t, rs.getObject(i));
fields.setAccessible(iRet);
} else {
continue;
}
}
}
list.add(t);
}
}
closeConnection(con, st, null, rs);
return list;
}
// 执行一条动态SQL命令
// 这个方法自己写的,发现错误挺多的 1 预编译和结果集的行数从1开始的 2.fields弄成i了,应该是j;
public static <T>List<T> execQuery(String sql,Object[] obj,Class classs ) throws ClassNotFoundException, SQLException, InstantiationException, IllegalAccessException{
Connection con=getConnection();
PreparedStatement pst=preparedStatement(con, sql);
System.out.println("正在执行预编译查询命令");
for (int i = 1; i <= obj.length; i++) {
pst.setObject(i, obj);
System.out.println(obj);
}
List<T> list=new ArrayList<T>();
ResultSet rs=pst.executeQuery();
ResultSetMetaData rsmd=rs.getMetaData();
Field[] fields=classs.getDeclaredFields();
if(rs!=null){
while(rs.next()){
T t=(T)classs.newInstance();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
String colName=rsmd.getColumnName(i);
for (int j = 0; j < fields.length; j++) {
String fieldName=fields.getName();
if(colName.equals(fieldName)){
Boolean iRet=fields.isAccessible();
fields.setAccessible(true);
fields.set(t, rs.getObject(i));
fields.setAccessible(iRet);
}else{
continue;
}
}
}
list.add(t);
}
}
closeConnection(con, pst, null, rs);
return list;
}
// 关闭连接,释放资源
public static void closeConnection(Connection con, Statement st, PreparedStatement pst, ResultSet rs)
throws SQLException {
if (rs != null) {
rs.close();
}
if (pst != null) {
pst.close();
}
if (st != null) {
st.close();
}
if (con != null) {
con.close();
}
}
}
本帖最后由 夏橙M兮 于 2019-1-7 16:38 编辑
自己增加两个方法,方便自己用动态sql往数据库里插入有多个字段的表。
//将对象属性的值赋值给object数组
public static Object[] getFieldsToArray(Object obj){
if(obj==null)
return null;
List<Object> list=new ArrayList();
Class c=obj.getClass();
Field[] fields=c.getDeclaredFields();
for(Field f:fields){
try {
Boolean iRet=f.isAccessible();
f.setAccessible(true);
list.add(f.get(obj));
f.setAccessible(iRet);
} catch (IllegalArgumentException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return list.toArray();
}
//删除制定数组索引里的值
public static Object[] deleteArrByIndex(Object[] obj,int[] index){
Arrays.sort(index);
List<Integer> list = new ArrayList<>();
for (int i = 0; i < index.length; i++) {
list.add(i, index);
}
int lens = obj.length - index.length;
Object[] nobj = new Object;
int len = 0;
boolean flag = true;
for (int i = 0; i < obj.length; i++) {
/*
* for(int j:index){ if(i!=j){ nobj=obj; len++; }
* 这个算法有问题,当有两个时就凉了。 }
*/
/*
* if (list.size() == 0) { flag = true; } else {
*/
for (int j = 0; j < list.size(); j++) {
if (i == list.get(j)) {
list.remove(j);
flag = false;
break;
}
}
if (flag) {
nobj = obj;
len++;
}
flag = true;
} return nobj;
}
xilidexiao 发表于 2019-1-7 16:10
楼主,我有一个问题想问一下,setAccessible(true)强制开启private权限的访问,不是违背了类的封装原则??
最后不是还原了吗?要不然不好不好给对象赋值呀。 谢谢分享 感谢分享,好好学习。 人是真的少呀。什么时候我能遇到我的伯乐呀?一看到这个帖子就有我正需要的感觉呢。 感谢分享,一起学习进步!!! 不用连接池,大型项目容易扑街 xuan5451 发表于 2019-1-7 15:15
不用连接池,大型项目容易扑街
这只是新手练习项目,以后改获取连接数据库方法就行了啦。 来个好人,给个评分呀!
页:
[1]
2