【java】對jdbc操作結果簡單的映射封裝


1. 對jdbc做一個簡單的封裝,select可以返回一個javabean對象,而不是resultset。主要用了反射。這是我之前寫的代碼,做了簡單的修改。

  實現功能:a.對數據庫的基本操作 增刪改查

       b.對查詢的單條記錄返回一個指定類型的javabean對象,利用java反射,jdbc ResultSet類和ResultSetMetaData類

       c. 對查到的結果集返回一個List, 泛型

  數據源:用到的 數據庫連接池是我自己簡單實現的一個連接池:【java】簡單實現數據庫連接池,主要為了后續實現事務的簡單實現

  用到的java知識 : 反射,泛型,jdbc

        


import
com.yeyeck.noob.ConnectionPollImpl; import com.yeyeck.noob.IConnectionPool; 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 DBUtil { public static int excuteUpdate(String sql, Object... objects) { IConnectionPool connectionPool = ConnectionPollImpl.getInstance(); Connection connection = connectionPool.getConnection(); 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) { IConnectionPool connectionPool = ConnectionPollImpl.getInstance(); Connection connection = connectionPool.getConnection(); 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 | IllegalAccessException | InstantiationException | NoSuchFieldException | NoSuchMethodException | 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) { IConnectionPool connectionPool = ConnectionPollImpl.getInstance(); Connection connection = connectionPool.getConnection(); PreparedStatement preparedStatement = null; ResultSet resultSet = null; List<T> list = new ArrayList<>(); try { preparedStatement = getStateMent(connection, sql, objects); resultSet = getResultSet(preparedStatement); while (resultSet.next()) { //調用 invokeObject方法,把一條記錄封裝成一個對象,添加到list中 list.add(invokeObject(resultSet, clazz)); } } catch (SQLException | IllegalAccessException | InstantiationException | NoSuchFieldException | NoSuchMethodException | InvocationTargetException e) { e.printStackTrace(); } finally { close(preparedStatement, resultSet); } return list.size() > 0 ? list : null; } private static void close(PreparedStatement preparedStatement, ResultSet resultSet) { try { if(resultSet != null) { resultSet.close(); } if (preparedStatement != null) { preparedStatement.close(); } } catch (SQLException e) { e.printStackTrace(); } } /** * 把數據庫中的一條記錄通過反射包裝成相應的Bean * @param resultSet * @param clazz * @param <T> * @return * @throws IllegalAccessException * @throws InstantiationException * @throws SQLException * @throws NoSuchFieldException * @throws NoSuchMethodException * @throws InvocationTargetException */ private static <T> T invokeObject(ResultSet resultSet, Class<T> clazz) throws IllegalAccessException, InstantiationException, SQLException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException { T object = clazz.getDeclaredConstructor().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 { 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); } }

其中用到的StringUtil的幾個方法

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());
    }
}

測試

1.測試用到的表

 CREATE TABLE `t_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `age` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 |

初始數據

測試代碼

import java.util.List;

public class DBUtilTest {

    public static void main(String[] args) {


        List<User> users1 = DBUtil.queryForList("select * from t_user", User.class);
        System.out.println(users1);

        User user = new User();
        user.setUsername("劉能");
        user.setAge(12);
        String sql1 = "insert into `t_user`(username, age) values (?, ?)";
        System.out.println("insert 語句測試返回結果:" + DBUtil.excuteUpdate(sql1, user.getUsername(), user.getAge()));
        List<User> users2 = DBUtil.queryForList("select * from t_user", User.class);
        System.out.println(users2);

        String sql2 = "delete from t_user where id = ?";
        System.out.println("delete 語句測試返回結果:" + DBUtil.excuteUpdate(sql2, 3));

        String sql3 = "update t_user set age = ? where id = ?";
        System.out.println("update 語句測試返回結果:" + DBUtil.excuteUpdate(sql3, 100, 1));

        String sql4 = "select * from t_user where id = ?";
        User user2 = DBUtil.queryForObject(sql4, User.class, 2);
        System.out.println("select 語句測試返回結果: " + user2 );
        List<User> users3 = DBUtil.queryForList("select * from t_user", User.class);
        System.out.println(users3);


    }

}

測試結果

[User{id=1, username='小明', age=100}, User{id=2, username='小紅', age=15}, User{id=4, username='小二', age=12}, User{id=5, username='劉能', age=12}]
insert 語句測試返回結果:1
[User{id=1, username='小明', age=100}, User{id=2, username='小紅', age=15}, User{id=4, username='小二', age=12}, User{id=5, username='劉能', age=12}, User{id=6, username='二蛋', age=99}]
delete 語句測試返回結果:1
update 語句測試返回結果:1
select 語句測試返回結果: User{id=2, username='小紅', age=15}
[User{id=1, username='小明', age=20}, User{id=2, username='小紅', age=15}, User{id=4, username='小二', age=12}, User{id=6, username='二蛋', age=99}]

數據庫數據

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM