1. 程式人生 > >JDBC簡單封裝以及策略模式的利用

JDBC簡單封裝以及策略模式的利用

結果集封裝為Map

    @Test
    public void warp2Map() throws SQLException {
        Map<String, Object> map = warp2Map("select * from user_test where id = 2011");
        System.out.println(map);
    }

    static Map<String, Object> warp2Map(String sql) throws SQLException {
        Map<String
, Object> map = null; Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = ConnCreate.getConnection(); stmt = conn.prepareStatement(sql); rs = stmt.executeQuery(); ResultSetMetaData rsmd =
rs.getMetaData(); // 取得行數 int count = rsmd.getColumnCount(); if (rs.next()) { if (!rs.isLast()) throw new SQLException("查詢記錄超過一行,不能使用Map結果集"); map = new HashMap<String, Object>(); for (int i =
1; i <= count; ++i) { map.put(rsmd.getColumnLabel(i), rs.getObject(i)); } } } finally { ConnCreate.close(conn, stmt, rs); } return map; }

封裝為物件 注重利用反射

    @Test
    public void warp2Object() throws SecurityException, IllegalArgumentException, SQLException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException{
        User user =(User) warp2Class("select * from user_test where id=2011",User.class);
        System.out.println(user.getName());
        System.out.println(user.getBirthday());
        System.out.println(user.getId());
        System.out.println(user.getMoney());
    }

    static Object warp2Class(String sql,Class<?> clazz) throws SQLException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException{
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        Object destObject = clazz.newInstance();
        try {
            conn = ConnCreate.getConnection();
            stmt = conn.prepareStatement(sql);
            rs = stmt.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            if(rs.next()){
                if(!rs.isLast())
                    throw new SQLException("查詢記錄超過一行,不能使用Map結果集");
                Method method = null;
                for(int i=1;i<=rsmd.getColumnCount();i++){
                    method = clazz.getMethod(parseMethodName(rsmd.getColumnLabel(i)),new Class[]{rs.getObject(i).getClass()});
                    method.invoke(destObject, new Object[]{rs.getObject(i)});
                }
            }
        } finally{
            ConnCreate.close(conn, stmt, rs);
        }
        return destObject;
    }

    static String parseMethodName(String columnName){
        String temp = "set";
        temp+=columnName.substring(0, 1).toUpperCase();
        temp+=columnName.substring(1);
        return temp;
    }

封裝為List

@Test
    public void warp2Object() throws SecurityException, IllegalArgumentException, SQLException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException{
        List<Object> userList =warp2Class("select * from user",User.class);
        for(Iterator<Object> it = userList.iterator();it.hasNext();){
            User user  = (User) it.next();
            System.out.println(user.getName()+"|"+user.getBirthday()+"|"+user.getMoney()+"|"+user.getId());
        }
    }

    static List<Object> warp2Class(String sql,Class<?> clazz) throws SQLException, SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, InstantiationException{
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        List<Object> lists = new ArrayList<Object>();
        try {
            conn = ConnFactory.getConnection();
            stmt = conn.prepareStatement(sql);
            rs = stmt.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            while(rs.next()){
                Object destObject = clazz.newInstance();
                Method method = null;
                for(int i=1;i<=rsmd.getColumnCount();i++){
                    method = clazz.getMethod(parseMethodName(rsmd.getColumnLabel(i)),new Class[]{rs.getObject(i).getClass()});
                    method.invoke(destObject, new Object[]{rs.getObject(i)});
                }
                lists.add(destObject);
            }
        } finally{
            ConnFactory.close(conn, stmt, rs);
        }
        return lists;
    }

    static String parseMethodName(String columnName){
        String temp = "set";
        temp+=columnName.substring(0, 1).toUpperCase();
        temp+=columnName.substring(1);
        return temp;
    }

策略模式的應用

前面的三個小節中,我們通過將結果集封裝成三種不同的結構體演示瞭如何通過反射,結果集的元資料將資料庫物件轉換成Java物件,基本功能均已實現,但是存在一個問題,就是我們大多時候使用了強型別轉換,並且沒有使用統一的介面去管理三個不同的封裝形式,如果要我們自己編寫API供別人使用,這將是一個很不太好的方式。

在本節中我們通過一個統一的介面來作為抽象,三種不同的實現作為繼承,這樣使用者只需要通過介面進行程式設計即可。

  • ResultHandler
public interface ResultHandler<T> {
    public T handler(String sql,Class<T> clazz) throws SQLException, IllegalAccessException, InstantiationException, NoSuchMethodException;
}
  • ResultMap
import java.sql.*;
import java.util.HashMap;
import java.util.Map;

public class ResultMap implements ResultHandler<Map<String,Object>> {

    @Override
    public Map<String, Object> handler(String sql, Class<Map<String, Object>> clazz) throws SQLException {
        Map<String, Object> map = null;
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            conn = ConnCreate.getConnection();
            stmt = conn.prepareStatement(sql);
            rs = stmt.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            int count = rsmd.getColumnCount();
            if (rs.next()) {
                if (!rs.isLast())
                    throw new SQLException("查詢記錄超過一行,不能使用Map結果集");
                map = new HashMap<String, Object>();
                for (int i = 1; i <= count; ++i) {
                    map.put(rsmd.getColumnLabel(i), rs.getObject(i));
                }
            }
        } finally {
            ConnCreate.close(conn, stmt, rs);
        }

        return map;
    }

}
  • ResultBean
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

public class ResultBean<T> implements ResultHandler<T>{

    private String parseMethodName(String columnName){
        String temp = "set";
        temp+=columnName.substring(0, 1).toUpperCase();
        temp+=columnName.substring(1);
        return temp;
    }

    @SuppressWarnings("unchecked")
    public T handler(String sql, Class<?> clazz) throws Exception {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        T t = (T) clazz.newInstance();
        try {
            conn = ConnFactory.getConnection();
            stmt = conn.prepareStatement(sql);
            rs = stmt.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            if(rs.next()){
                if(!rs.isLast())
                    throw new SQLException("查詢記錄超過一行,不能使用Map結果集");
                Method method = null;
                for(int i=1;i<=rsmd.getColumnCount();i++){
                    method = clazz.getMethod(parseMethodName(rsmd.getColumnLabel(i)),new Class[]{rs.getObject(i).getClass()});
                    method.invoke(t, new Object[]{rs.getObject(i)});
                }
            }
        } finally{
            ConnFactory.close(conn, stmt, rs);
        }
        return t;
    }
}
  • ResultList
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;

public class ResultList<T> implements ResultHandler<List<T>>{

    private String parseMethodName(String columnName){
        String temp = "set";
        temp+=columnName.substring(0, 1).toUpperCase();
        temp+=columnName.substring(1);
        return temp;
    }

    @SuppressWarnings("unchecked")
    public List<T> handler(String sql, Class<?> clazz) throws Exception {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        List<T> lists = new ArrayList<T>();
        try {
            conn = ConnFactory.getConnection();
            stmt = conn.prepareStatement(sql);
            rs = stmt.executeQuery();
            ResultSetMetaData rsmd = rs.getMetaData();
            while(rs.next()){
                T destObject = (T) clazz.newInstance();
                Method method = null;
                for(int i=1;i<=rsmd.getColumnCount();i++){
                    method = clazz.getMethod(parseMethodName(rsmd.getColumnLabel(i)),new Class[]{rs.getObject(i).getClass()});
                    method.invoke(destObject, new Object[]{rs.getObject(i)});
                }
                lists.add(destObject);
            }
        } finally{
            ConnFactory.close(conn, stmt, rs);
        }
        return lists;
    }
}
  • Test
@Test
    public void mapWarp() throws Exception{
        ResultHandler<Map<String, Object>> handler = new ResultMap();
        Map<String,Object> maps=handler.handler("select * from user where id=1", null);
        System.out.println(maps);
    }

    @Test
    public void beanWarp() throws Exception{
        ResultHandler<User> handler = new ResultBean<User>();
        User user = handler.handler("select * from user where id=1", User.class);
        Assert.assertEquals("test", user.getName());
    }

    @Test
    public void ListWarp() throws Exception{
        ResultList<User> handler = new ResultList<User>();
        List<User> lists = handler.handler("select * from user", User.class);
        Assert.assertEquals(2, lists.size());
    }