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());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值