文章目录


本章接着上一章手写MyBatis,主要这集中在sqlSession对象的获取!

1.自定义SqlSessionFactory接口

SqlSessionFactory接口是获取session工厂的规范:

package org.apache.ibatis.session;

public interface SqlSessionFactory {

SqlSession openSession();
}

2.自定义SqlSession接口

package org.apache.ibatis.session;

import java.util.List;

public interface SqlSession {


/**
* 查询所有
*
* @param statementId sql唯一id
* @param params sql有可能是模糊查询,传可变参数
* @param <E> 泛型
* @return List集合
*/
<E> List<E> selectList(String statementId, Object... params) throws Exception;

/**
* 根据条件查询单个
*
* @param statementId sql唯一id
* @param params sql有可能是模糊查询,传可变参数
* @param <T> 泛型
* @return 某一对象
*/
<T> T selectOne(String statementId, Object... params) throws Exception;


/**
* 更新操作
*
* @param statementId sql唯一id
* @param params 可变参数
* @return 更新条数
*/
<T> T update(String statementId, Object... params) throws Exception;


/**
* 为Dao层接口生成代理实现类
*
* @param mapperClass 字节码
* @param <T> 泛型
* @return 某一对象
*/
<T> T getMapper(Class<?> mapperClass) throws Exception;
}

3.自定义DefaultSqlSession实现类

DefaultSqlSession类为SqlSession接口的实现类,此处暂时先重写getMapper方法,通过JDK动态代理生成Dao层接口实例对象!

public class CommandType {

public final static String[] sqlCommand = {"insert", "update", "delete"};

}
package org.apache.ibatis.session;

import org.apache.ibatis.configration.Configuration;

import java.lang.reflect.*;
import java.util.Arrays;
import java.util.List;

public class DefaultSqlSession implements SqlSession {

private Configuration configuration;

public DefaultSqlSession(Configuration configuration) {
this.configuration = configuration;
}


@Override
public <E> List<E> selectList(String statementId, Object... params) throws Exception {
return null;
}

@Override
public <T> T selectOne(String statementId, Object... params) throws Exception {
return null;
}

@Override
public <T> T update(String statementId, Object... params) throws Exception {
return null;
}

@Override
public <T> T getMapper(Class<?> mapperClass) throws Exception {

// 使用JDK动态代理来为Dao层接口生成代理对象,并返回。
Object proxyInstance = Proxy.newProxyInstance(mapperClass.getClassLoader(), new Class[]{mapperClass}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/**
* 底层都还是去执行JDBC代码
* 根据不同情况来调用findAll或者findByCondition方法
* 准备参数:
* 1.statementId: sql语句的唯一标识 nnamespace.id = 接口全限定名.方法名
*/
// 方法名
String methodName = method.getName();
String className = method.getDeclaringClass().getName();

String statementId = className + "." + methodName;

// 准备参数 2.params:args
// 获取被调用方法的返回值类型
Type genericReturnType = method.getGenericReturnType();
if (Arrays.asList(CommandType.sqlCommand).contains(methodName)) {
return update(statementId, args);
}
// 判断是否进行了泛型类型参数化
if (genericReturnType instanceof ParameterizedType) {
List<Object> objects = selectList(statementId, args);
return objects;
}
return selectOne(statementId, args);
}
});
return (T) proxyInstance;
}
}

4.自定义DefaultSqlSessionFactory

package org.apache.ibatis.session;

import org.apache.ibatis.configration.Configuration;

public class DefaultSqlSessionFactory implements SqlSessionFactory {

private Configuration configuration;

public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}

@Override
public SqlSession openSession() {
return new DefaultSqlSession(configuration);
}

}

5.自定义SqlSessionFactoryBuilder

SqlSessionFactoryBuilder类的作用是获取SqlSessionFactory

package org.apache.ibatis.session;

import org.apache.ibatis.configration.Configuration;
import org.apache.ibatis.parser.XMLConfigBuilder;
import org.dom4j.DocumentException;

import java.beans.PropertyVetoException;
import java.io.InputStream;

public class SqlSessionFactoryBuilder {

public SqlSessionFactory build(InputStream in) throws DocumentException, PropertyVetoException {
// 1.使用dom4j解析配置文件,将解析出来的内容封装到Configuration
XMLConfigBuilder xmlConfigBuilder = new XMLConfigBuilder();
Configuration configuration = xmlConfigBuilder.parseConfig(in);

// 2.创建SqlSessionFactory对象:工厂类:生产SqlSession:会话对象
DefaultSqlSessionFactory defaultSqlSessionFactory = new DefaultSqlSessionFactory(configuration);
return defaultSqlSessionFactory;
}
}

至此为止sqlsession构建完毕!