JDBC簡單封裝以及策略模式的利用
阿新 • • 發佈:2018-12-30
結果集封裝為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());
}