1. 程式人生 > >瞎j8封裝第二版之數據層的封裝

瞎j8封裝第二版之數據層的封裝

null all next app true 必須 l數據庫 port system

看了以前寫的代碼,對就是下面這個

手把手封裝數據層之DataUtil數據庫操作的封裝

覺得以前寫的代碼好爛啊!!!,重新理了一下思路,寫得更規範和簡練,應該效率也會高很多,用了一下下午寫的連接池(半廢品。。。)

瞎j8封裝第二版之數據庫連接池

下面直接上代碼,代碼很好理解,就是用了簡單的反射,註解的部分我都寫了註釋

package jdbc;

import util.StringUtil;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.*; import java.util.ArrayList; import java.util.List; public class DataUtil { public static int excuteUpdate(String sql, Object... objects) { Connection connection = ConnectionPool.getInstance().getCurrentConnection(); PreparedStatement preparedStatement = null
; try { preparedStatement = getStateMent(connection, sql, objects); return preparedStatement.executeUpdate(); //執行sql並返回結果 } catch (SQLException e) { e.printStackTrace(); } finally { if (preparedStatement != null) {
try { preparedStatement.close(); } catch (SQLException e) { e.printStackTrace(); } } } return 0; } /** * 查詢單挑記錄 * * @param sql 查詢語句 * @param clazz 返回對象的class * @param objects 需要的參數,必須跟sql占位符的位置一一對應 * @param <T> 泛型返回 * @return 返回單個對象 */ public static <T> T queryForObject(String sql, Class<T> clazz, Object... objects) { Connection connection = ConnectionPool.getInstance().getCurrentConnection(); PreparedStatement preparedStatement = null; ResultSet resultSet = null; T object = null; try { preparedStatement = getStateMent(connection, sql, objects); resultSet = getResultSet(preparedStatement); if (resultSet.next()) { object = invokeObject(resultSet, clazz); } } catch (SQLException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } finally { close(preparedStatement, resultSet); //記得關閉 } return object; } /** *查詢多條記錄 * * @param sql 查詢語句 * @param clazz 返回對象的class * @param objects 需要的參數,必須跟sql占位符的位置一一對應 * @param <T> 泛型返回 * * @return list */ public static <T> List<T> queryForList(String sql, Class<T> clazz, Object... objects) { Connection connection = ConnectionPool.getInstance().getCurrentConnection(); PreparedStatement preparedStatement = null; ResultSet resultSet = null; List<T> list = new ArrayList<T>(); try { preparedStatement = getStateMent(connection, sql, objects); resultSet = getResultSet(preparedStatement); while (resultSet.next()) { list.add(invokeObject(resultSet, clazz)); } } catch (SQLException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } finally { close(preparedStatement, resultSet); } return list.size() > 0 ? list : null; } private static void close(PreparedStatement preparedStatement, ResultSet resultSet) { try { if (preparedStatement != null) { preparedStatement.close(); resultSet.close(); } } catch (SQLException e) { e.printStackTrace(); } } private static <T> T invokeObject(ResultSet resultSet, Class<T> clazz) throws IllegalAccessException, InstantiationException, SQLException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException { T object = clazz.newInstance(); ResultSetMetaData metaData = resultSet.getMetaData(); for (int i = 0, count = metaData.getColumnCount(); i < count; i++) { String columnName = metaData.getColumnName(i + 1); //數據庫返回結果的列名 String fieldName = StringUtil.camelName(columnName); //去掉列名中的下劃線“_”並轉為駝峰命名 Field field = clazz.getDeclaredField(fieldName); //根據字段名獲取field String methName = setMethodName(fieldName); //拼set方法名 Class type = field.getType(); //獲取字段類型 Method setMethod = clazz.getDeclaredMethod(methName, field.getType()); Object value = resultSet.getObject(i + 1); //獲取字段值 setMethod.invoke(object, type.cast(value)); //強轉並且賦值 } return object; } private static PreparedStatement getStateMent(Connection connection, String sql, Object... objects) throws SQLException { if (connection == null) { return null; } PreparedStatement preparedStatement = connection.prepareStatement(sql); for (int i = 0, len = objects.length; i < len; i++) { preparedStatement.setObject(i + 1, objects[i]); //給sql每個?占位符填上數據 } return preparedStatement; } private static ResultSet getResultSet(PreparedStatement statement) throws SQLException { if (statement == null) { return null; } else { return statement.executeQuery(); } } private static String setMethodName(String str) { return "set" + StringUtil.firstUpperCase(str); } }

用到了幾個簡單的字符串處理方法

package util;

public class StringUtil {

    /**
     * 轉為駝峰命名
     * @param str
     * @return string
     */
    public static String camelName(String str) {
        if (!isEmpty(str)) {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0, len = str.length(); i < len; i++) {
                if (str.charAt(i) == ‘_‘) {
                    while (str.charAt(i + 1) == ‘_‘) {
                        i++;
                    }
                    stringBuilder.append(("" + str.charAt(++i)).toUpperCase());
                } else {
                    stringBuilder.append(str.charAt(i));
                }
            }
            return stringBuilder.toString();
        }
        return str;
    }

    /**
     * 判斷是否為空串
     * 
     * @param str
     * @return
     */
    public static boolean isBlank(String str) {
        if (str != null && str.length() > 0) {
            for (int i = 0, len = str.length(); i < len; i++) {
                if (!Character.isSpaceChar(str.charAt(i))) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 判斷是否為空串 ?!!! 我怎麽又寫了個一樣的方法?!!!
     * @param str
     * @return
     */
    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }


    /**
     * 將第一個字母替換為大寫
     * @param str
     * @return
     */
    public static String firstUpperCase(String str) {
        return str.substring(0, 1).toUpperCase() + str.substring(1, str.length());
    }
    
}

下面開始是測試了

首先數據庫

技術分享圖片

然後測試類,跟表結構對應的

package po;

import java.util.Date;

public class User {

    private Integer id;
    private Integer age;
    private String name;
    private Double score;
    private Date createTime;
    private Date updateTime;

   //set、get 方法均省略了,但是這個是必須的

測試代碼

import java.util.List;

public class Test {

    public static void main(String[] args) {
        String sql = "select * from t_user";
        List<User> list = DataUtil.queryForList(sql,User.class);
        System.out.println("查詢多條記錄:" + list);
        System.out.println("******************************************************************");


        sql = "select * from t_user where id = ?";
        User user = DataUtil.queryForObject(sql,User.class,1);
        System.out.println("查詢單條記錄:" + user);
        System.out.println("******************************************************************");


        sql = "insert into t_user(name,score,create_time,update_time) values(?,?,now(),now())";
        int t = DataUtil.excuteUpdate(sql,"大牛",66.66);
        System.out.println("執行插入操作結果:"+t);

    }
}

測試結果

技術分享圖片

技術分享圖片

太晚了,先到這了,有空把我的mybatis和ioc容器也瞎j8重寫一下

轉載請註明出處:

大王讓我寫代碼 00:12:24

瞎j8封裝第二版之數據層的封裝