美文网首页
【mybatis-高级篇】

【mybatis-高级篇】

作者: giraffecode9668 | 来源:发表于2020-06-12 16:00 被阅读0次

    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) {
    
        }
    }
    
        <plugins>
            <plugin interceptor="com.example.mybatistest.plugin.MyFirstPlugin">
                <property name="" value=""/>
            </plugin>
        </plugins>
    

    三、拓展-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<EmpStatus> {
    
        // 设置参数到数据库中
        @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
    方式一:全局配置

        <typeHandlers>
            <typeHandler handler="com.example.mybatistest.typehandler.MyTypeHandler" javaType="com.example.mybatistest.bean.EmpStatus"/>
        </typeHandlers>
    

    方式二:独立配置

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

    相关文章

      网友评论

          本文标题:【mybatis-高级篇】

          本文链接:https://www.haomeiwen.com/subject/pamdtktx.html