Mybatis學習之自定義持久層框架(五) 自定義持久層框架:封裝CRUD操作

封裝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;
    }
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章