【mybatis-高级篇】

mybatis-高级篇

一、mybatis原理

Mybatis的四大对象
Executor
ParameterHandler
ResultSetHandler
StatementHandler

一个MappedStatement代表一个增删改查的详细信息
Configuration包含全局配置,所有映射文件信息,接口信息

MappedStatement:一个sql对应一个MappedStatement
MapperProxyFactory:生成MapperProxy实例
Executor:执行增删改查,其中调用StatementHandler处理

原理分析

        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
     // (1)
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
     // (2)
        try (SqlSession session = sqlSessionFactory.openSession()){
     // (3)
            SellMapper mapper = session.getMapper(SellMapper.class);
     // (4)
            Sell sell = mapper.getSellById(1);

            System.out.println(sell);
        }

1、获取SqlSessionFactory对象
把配置文件的信息解析并保存在Configuration对象中(包含所有的映射文件信息、接口信息等),返回包含了Configuration的DefaultSqlSession对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

一个MappedStatement代表一个增删改查的详细信息

2、获取SqlSession
返回SqlSession的实现类Default对象,包含了Executor和Configuration;会有拦截器链(interceptChain.pluginAll(executor))对Executor进行插入修饰。

Executor:执行器,执行增删改查操作
CachingExecutor:包装了Executor,用于二级缓存

3、getMapper
getMapper使用MapperProxyFactory创建一个MapperProxy的代理对象,包含了DefaultSqlSession(Executor)

4、执行方法
创建MapperMethodInvoker(接口,有invoke方法),PlainMethodInvoker写入本次方法查询相关信息(MapperMethod),MapperMethod包括SqlCommand和MethodSignature。调用MapperMethodInvoker.invoke方法执行操作=>PlainMethodInvoker中调用MapperMethod.excute方法。MapperMethod.excute是真正执行方法。调用MapperStatment
通过调用代理类执行方法,创建StatementHandler(ParameterHandler,ResultSetHandler)处理器对象,使用处理器调用底层JDBC执行SQL返回结果。

StatementHandler:创建出Statement对象,预编译设置参数结果返回等工作,包含ParameterHandler和ResultSetHandler
ParameterHandler:设置参数,包含TypeHandler
ResultSetHandler:处理结果,包含TypeHandler

总结:

  • 1、根据配置文件(全局,sql映射)初始化出Configuration对象
  • 2、创建一个DefaultSqlSession对象,他里面包含Configuraiton以及Executor(根据全局配置文件中的defaultExecutorType创建出对应的Executor)
  • 3、DefaultSqlSession.getMapper():拿到Mapper接口对应的MapperProxy;
  • 4、MapperProxy包含了DefaultSqlSession
  • 5、执行增删改查方法:
    1)调用DefaultSqlSession的增删改查(Executor)
    2)会创建一个StatementHandler对象(同时创建出ParameterHandler和ResultSetHandler)
    3)、调用StatementHandler预编译参数以及设置参数值;使用ParaterHandler给sql设置参数
    4)、调用StatementHandler的增删改查方法;
    5)ResultSetHandler封装结果
image.png

二、mybatis插件

责任链模式+动态代理+反射机制
插件编写

  • 1、实现Interceptor
  • 2、使用@Intercepts注解完成插件签名
  • 3、将写好的插件注册到全局的配置文件
@Intercepts({
        @Signature(type = StatementHandler.class,method = "parameterize",args = Statement.class)
})
public class MyFirstPlugin implements Interceptor {

    //如果符合插件插入规则,在对应方法执行时替换为当前方法
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        System.out.println("插件:"+this.getClass());
        Object target = invocation.getTarget();
        MetaObject metaObject = SystemMetaObject.forObject(target);
        Object value = metaObject.getValue("parameterHandler.parameterObject");
        System.out.println("插件查出参数:"+value);
        metaObject.setValue("parameterHandler.parameterObject",(int)value+1);
        Object proceed = invocation.proceed();
        return proceed;
    }

    //如果符合插件插入规则,生成代理对象,将本实例handler传入
    @Override
    public Object plugin(Object target) {
        System.out.println("插件"+this.getClass()+":"+target);
        return Plugin.wrap(target,this);
    }
    
    //从配置文件中获得信息
    @Override
    public void setProperties(Properties properties) {

    }
}
    
        
            
        
    

三、拓展-pagehelper

https://github.com/abel533/MyBatis-Spring-Boot

四、批量处理

方法一:
设置全局步骤defaultExecutorType=BATCH,表示所有的查询都使用批量处理

方法二:
获得批量处理的sqlSession进行处理SqlSession sqlSessin = sqlSessionFactory.openSession(Executor.BATCH)

方法三:
整合注入sqlSession,class=SqlSessionTemplate,类型executorTyepe=BATCH,然后aurowired使用

五、自定义TypeHandler

1、实现TypeHandler接口,或者继承BaseTypeHandler

public class MyTypeHandler implements TypeHandler {

    // 设置参数到数据库中
    @Override
    public void setParameter(PreparedStatement ps, int i, EmpStatus parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i,parameter.getCode().toString());
    }

    // 从数据库中映射到java
    @Override
    public EmpStatus getResult(ResultSet rs, String columnName) throws SQLException {
        int code = rs.getInt(columnName);
        //code再进行替换返回成EmpStatus
        return null;
    }

    @Override
    public EmpStatus getResult(ResultSet rs, int columnIndex) throws SQLException {
        int code = rs.getInt(columnIndex);
        //code再进行替换返回成EmpStatus
        return null;
    }

    @Override
    public EmpStatus getResult(CallableStatement cs, int columnIndex) throws SQLException {
        int code = cs.getInt(columnIndex);
        //code再进行替换返回成EmpStatus
        return null;
    }
}

2、配置使用自定义TypeHandler
方式一:全局配置

    
        
    

方式二:独立配置

保存时:#{emp, typeHandler=xxx}
查询时:使用resultMap,resoult 中指定typeHandler=""

你可能感兴趣的:(【mybatis-高级篇】)