封裝CRUD操作
首先我們需要創建一個SqlSession接口類,在其中定義會話的內容接口,同樣,今天所提及的類都存放在“sqlSession”包下,SqlSession接口類的代碼如下所示:
package com.lwl.sqlSession;
import java.util.List;
public interface SqlSession {
/**
* 查詢所有
* @param statementId
* @param params
* @param <E>
* @return
*/
public <E> List<E> selectList(String statementId,Object... params) throws Exception;
/**
*
* 根據條件查詢
* @param <T>
* @param statementId
* @param
* @return
*/
public <T> T selectOne(String statementId, Object... params) throws Exception;
/**
*
* 修改用戶
* @param <T>
* @param statementId
* @param
* @return
*/
Integer update(String statementId, Object... params) throws Exception;
//爲dao層生成代理實現類
public <T> T getMapper(Class<?> mapperClass);
}
創建DefaultSession 定義對數據庫的操作 CRUD
package com.lwl.sqlSession;
import com.lwl.pojo.Configuration;
import com.lwl.pojo.MappedStatement;
import java.lang.reflect.*;
import java.util.List;
import java.util.Map;
public class DefaultSqlSession implements SqlSession {
private Configuration configuration;
// 處理器對象
private Executor simpleExecutor = new SimpleExecutor();
public DefaultSqlSession(Configuration configuration) {
this.configuration = configuration;
}
@Override
public <E> List<E> selectList(String statementId, Object... params) throws Exception {
//將要完成對simpleExecutor類的創建 query()的調用
SimpleExecutor simpleExecutor = new SimpleExecutor();
Map<String, MappedStatement> mappedStatementMap = configuration.getMappedStatementMap();
MappedStatement mappedStatement = mappedStatementMap.get(statementId);
List<Object> list = simpleExecutor.query(configuration, mappedStatement, params);
return (List<E>) list;
}
@Override
public <T> T selectOne(String statementId, Object... params) throws Exception {
List<Object> objects = selectList(statementId, params);
if (objects.size() == 1){
return (T)objects.get(0);
}else if (objects.size() > 1){
throw new RuntimeException("查詢結果返回多個");
}else {
return null;
}
}
/**
* 修改用戶
*
* @param
* @param params
* @return
*/
@Override
public Integer update(String statementId, Object... params) throws Exception {
SimpleExecutor simpleExecutor = new SimpleExecutor();
Map<String, MappedStatement> mappedStatementMap = configuration.getMappedStatementMap();
MappedStatement mappedStatement = mappedStatementMap.get(statementId);
return simpleExecutor.update(configuration,mappedStatement,params);
}
@Override
public <T> T getMapper(Class<?> mapperClass) {
//使用jdk動態代理 來爲dao生成代理對象 並返回
//代理對象調用接口的任意方法,都會去執行invoke方法
Object proxyInstance = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
/**
*
* @param proxy 當前代理對象的引用
* @param method 當前被調用的方法
* @param args 傳遞的參數
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//底層還是要去執行JDBC方法
//根據不同情況來調用selectList 或者selectOne
//準備參數 statementId sql語句的唯一標示 namespace.id = 接口的權限定名.方法名
String methodName = method.getName();
String className = method.getDeclaringClass().getName();
String statementId = className+"."+methodName;
if (methodName.startsWith("find")){
//獲取調用方法的返回值類型
Type genericReturnType = method.getGenericReturnType();
//判斷參數的返回值類型
if (genericReturnType instanceof ParameterizedType){
List<Object> list = selectList(statementId, args);
return list;
}
return selectOne(statementId,args);
}else {
return update(statementId,args);
}
}
});
return (T) proxyInstance;
}
}