MyBatis

缓存

一级缓存

SqlSession级别,同一会话中多次重复的查询会使用以及缓存,默认开启

二级缓存

Mappr级别,需要在Mappr显性的开启,不同会话使用同样的Sql会查询二级缓存

Mapper.XML文件中常用标签

  • sql脚本相关
    select、insert、update、delete
  • 动态sql相关
    指定sql的基本数据类型:<resultMap>、 <parameterMap>、 <sql>、 <include>、 <selectKey>
    动态组件sql:trim|where|set|foreach|if|choose|when|otherwise|bind
    针对<sql>标签的脚本可以使用<include>标签引入

Dao的实现原理,方式是否可以重载

通过xml文件中的namspace与dao接口进行管理,xml中使用sql语句段的id与dao接口中的方法名进行绑定;当dao接口中的方法名重复,但是参数不一样时,可以重载使用,实例:

/**
 * Mapper接口里面方法重载
 */
public interface StuMapper {

 List<Student> getAllStu();

 List<Student> getAllStu(@Param("id") Integer id);
}

//xml文件
<select id="getAllStu" resultType="com.pojo.Student">
  select * from student
  <where>
    <if test="id != null">
      id = #{id}
    </if>
  </where>
</select>

Mybatis的插件(拦截器)使用

MyBatis 仅可以编写针对 ParameterHandler、 ResultSetHandler、 StatementHandler、 Executor 这 4 种接口的插件,MyBatis 使用 JDK 的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这 4 种接口对象的方法时,就会进入拦截方法,具体就是 InvocationHandler 的 invoke() 方法,当然,只会拦截那些你指定需要拦截的方法。
使用过程:

  1. 定义拦截器
@Intercepts({
        @Signature(type = ParameterHandler.class, method = "setParameters", args = PreparedStatement.class)
})
public class BaseDataInterceptor implements Interceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        return invokeSetParameter(invocation);
    }

    private Object invokeSetParameter(Invocation invocation) throws Exception {
        return null;
    }

    @Override
    public Object plugin(Object target) {
        return Interceptor.super.plugin(target);
    }

    @Override
    public void setProperties(Properties properties) {
        properties.put("connectionInitSqls", "set names 'utf8mb4'");
        Interceptor.super.setProperties(properties);
    }
}
  1. 在Mybatis配置文件中的sqlSession部分添加拦截器
@Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(
                // 设置mybatis的xml所在位置,这里使用mybatis注解方式,没有配置xml文件
                new PathMatchingResourcePatternResolver().getResources("classpath*:com/zwj/learn/springcloud/**/dao/*.xml"));
        // 注册typehandler,供全局使用
        bean.setTypeHandlers(new UuidTypeHandler());

        BaseDataInterceptor sqlInterceptor = new BaseDataInterceptor();
        //创建属性值
        //将属性值设置到插件中
        Properties properties =  new Properties();
        sqlInterceptor.setProperties(new Properties());
        bean.setPlugins(sqlInterceptor);
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        // 配置SQL打印日志
        configuration.setLogImpl(StdOutImpl.class);
        //开启驼峰映射配置
        configuration.setMapUnderscoreToCamelCase(true);
        bean.setConfiguration(configuration);
        return bean.getObject();
    }

<resultMap>与<resultType>的区别

resultMap需要自己提供映射配置,resultType会自动根据指定的数据类型做自动封装。

<resultMap>实现一对一和一对多映射

  • 一对一
<resultMap id="userResultMap" type="com.example.User">
  <id column="id" property="id" />
  <result column="username" property="username" />
  <result column="password" property="password" />
</resultMap>

<select id="selectUserById" resultMap="userResultMap" parameterType="int">
  SELECT * FROM user WHERE id = #{id}
</select>
  • 一对多
<resultMap id="userResultMap" type="com.example.User">
  <id column="id" property="id" />
  <result column="username" property="username" />
  <result column="password" property="password" />
  <collection property="orders" ofType="com.example.Order">
    <result column="order_id" property="id" />
    <result column="order_name" property="name" />
  </collection>
</resultMap>

<select id="selectUserWithOrdersById" resultMap="userResultMap" parameterType="int">
  SELECT u.*, o.*
  FROM user u
  LEFT JOIN order o ON u.id = o.user_id
  WHERE u.id = #{id}
</select>

批量插入

xml中使用foreach标签

<insert id="insertBatch" parameterType="list">  
    INSERT INTO your_table (column1, column2, ...)  
    VALUES   
    <foreach collection="list" item="item" index="index" separator=",">  
        (#{item.property1}, #{item.property2}, ...)  
    </foreach>  
</insert>

Mybatis执行器Executor

  • SimpleExecutor:
    每执行一次 update 或 select,就开启一个 Statement 对象,用完立刻关闭 Statement 对象。
  • ReuseExecutor:
    执行 update 或 select,以 sql 作为 key 查找 Statement 对象,存在就使用,不存在就创建,用完后,不关闭 Statement 对象,而是放置于 Map<String, Statement>内,供下一次使用。简言之,就是重复使用 Statement 对象。
  • BatchExecutor:
    执行 update(没有 select,JDBC 批处理不支持 select),将所有 sql 都添加到批处理中(addBatch()),等待统一执行(executeBatch()),它缓存了多个 Statement 对象,每个 Statement 对象都是 addBatch()完毕后,等待逐一执行 executeBatch()批处理。与 JDBC 批处理相同。
    使用方式:
    在Mybatis配置中的sqlSession部分添加执行器。
posted @ 2024-03-21 13:10  周仙僧  阅读(14)  评论(0编辑  收藏  举报