夏橙M兮 发表于 2018-12-20 10:34

【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兮 发表于 2018-12-21 20:57

本帖最后由 夏橙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;
      }


夏橙M兮 发表于 2019-1-7 16:34

xilidexiao 发表于 2019-1-7 16:10
楼主,我有一个问题想问一下,setAccessible(true)强制开启private权限的访问,不是违背了类的封装原则??

最后不是还原了吗?要不然不好不好给对象赋值呀。

MGHT 发表于 2018-12-20 10:52

谢谢分享

bachelor88 发表于 2018-12-20 11:01

感谢分享,好好学习。                                    

夏橙M兮 发表于 2018-12-21 10:19

人是真的少呀。什么时候我能遇到我的伯乐呀?一看到这个帖子就有我正需要的感觉呢。

feixiang1126 发表于 2018-12-23 15:10

感谢分享,一起学习进步!!!

xuan5451 发表于 2019-1-7 15:15

不用连接池,大型项目容易扑街

夏橙M兮 发表于 2019-1-7 16:39

xuan5451 发表于 2019-1-7 15:15
不用连接池,大型项目容易扑街

这只是新手练习项目,以后改获取连接数据库方法就行了啦。

夏橙M兮 发表于 2019-1-7 16:40

来个好人,给个评分呀!
页: [1] 2
查看完整版本: 【javaee】【分享】一个jdbc实现增删改查的工具类,感觉写的挺好用的