自定义mybatis框架
自定义mybatis框架整体思路如下:
首先我们需要获取一个输入流 然后解析我们的xml主配置文件 这里面主要涉及到数据库的连接信息和我们的mapper配置文件信息
数据库连接信息封装到我们的configuration类即可 然后我们还需要在该类中存放我们的mapper信息
private Map<String,Mapper> mappers = new HashMap<String,Mapper>();
001假如是mapper配置文件 我们是这样处理解析mapper配置文件
<mapper resource="com/po/mapper/UserMapper.xml"/>
其中 key值是namespace+"."+标签的id;
value值是
Mapper mapper = new Mapper();
mapper.setQueryString(queryString);//具体的sql
mapper.setResultType(resultType);//实体类的全限定类名
因为我们执行sql语句之后 需要得到sql语句查询结果对应的实体类 所以这个实体类就是mapper里的resultType
002假如是注解配置我们是这样处理
首先我们需要新建一个select注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Select {
//配置SQL语句的
String value();
}
如果我们从主配置文件中没有获取到resource属性 那说明没有mapper配置文件 那说明我们是配置了注解模式开发 所以我们需要获取class属性 得到接口的全限定类名
<!-- 002使用映射器接口实现类的完全限定类名 -->
<mapper class="com.po.pf.repository.UserMapper"/>
得到全限定类名后 我们通过反射 遍历每个方法 获取每个方法头上的注解的标签 并获取到值
//取出注解的value属性值
Select selectAnno = method.getAnnotation(Select.class);
String queryString = selectAnno.value();
mapper.setQueryString(queryString);
String key = className+"."+methodName;
得到上述信息之后 把主配置文件和mapper配置文件的数据存在我们的configuration类中
然后我们利用建造者模式创建SqlSessionFactoryBuilder对象 我们把输入流交给构建者 构建者调用工具类帮我们获取configuration 然后返给我们一个factory对象 工程对象
public SqlSessionFactory build(InputStream config){
Configuration cfg = XMLConfigBuilder.loadConfiguration(config);
return new DefaultSqlSessionFactory(cfg);
}
传入一个输入流对象 内部通过解析获取configuration 然后再创建sqlsessionFactory工厂
sqlsessionFactory工厂对象帮我们提供了一个打开session方法 然后我们需要在session里面处理我们的业务 比如执行sql这样
但是现在有个问题 比如我并不知道我传过来的确切的mapper类是什么 然后我也不知道他里面具体有什么方法 那我就无法得知里面的内容 所以就没办法调用
所以此时需要引入动态代理 我们只需要传入class就可以帮助我们获取这个类里面的方法 然后调用invoke帮我们去执行sql语句
所以sqlsession类里有一个getMapper的动态代理方法
public <T> T getMapper(Class<T> daoInterfaceClass) {
return (T) Proxy.newProxyInstance(daoInterfaceClass.getClassLoader(),
new Class[]{daoInterfaceClass},new MapperProxy(cfg.getMappers(),connection));
}
然后我们的MpperProxy帮助我们去执行这些sql语句
package com.po.pf.mybatis;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.Map;
public class MapperProxy implements InvocationHandler {
//map的key是全限定类名+方法名
private Map<String,Mapper> mappers;
private Connection conn;
public MapperProxy(Map<String,Mapper> mappers,Connection conn){
this.mappers = mappers;
this.conn = conn;
}
//用于对方法进行增强的,我们的增强其实就是调用selectList方法
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//1.获取方法名
String methodName = method.getName();
//2.获取方法所在类的名称
String className = method.getDeclaringClass().getName();
//3.组合key
String key = className+"."+methodName;
//4.获取mappers中的Mapper对象
Mapper mapper = mappers.get(key);
//5.判断是否有mapper
if(mapper == null){
throw new IllegalArgumentException("传入的参数有误");
}
//6.调用工具类执行查询所有
return new Executor().selectList(mapper,conn);
}
}
到这里我们的工具基本完成任务
标签:mapper,自定义,框架,mappers,获取,mybatis,new,我们,配置文件 From: https://www.cnblogs.com/popopopopo/p/16982116.html