MyBatis

MyBatis

建立一个Batis项目需要:

  1. 配置 maven项目的xml文件,如dependency、build资源导出配置

  2. 创建工具类,用SqlSessionFactoryBuilder 工厂模式创建 SqlSessionFactory 对象,用于后续执行sql

  3. 在 resources 文件夹下创建 mybatis-config.xml 配置文件,配置driver、url、username、password,以及建立 mapper 映射,映射到接口实现类的 xml 文件中,mapper中的resource需要使用路径,非点

  4. 编写实体类

  5. 编写接口

  6. 编写实现接口的 xml 文件

  7. 编写测试文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

 

增删改 必须要 提交事务,sqlSession.commit();

如果字段或者参数过多,可以考虑使用Map;

Map 传递参数,直接在 sql 中取出 Key 即可!

对象传递参数,直接在 sql 中 取对象的属性即可!

 

  • 属性优化:properties标签放在最上面,首先读取标签体内的属性,然后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性

  • 设置标签:第二位,settings 标签的 cacheEnabled、lazyLoadingEnabled、logImpl

  • 类型别名优化:typeAliases标签第三位,给实体类起别名,也可以给包起别名,包内的实体类默认首字母小写为类的别名,也可以加注解

  • 环境标签: environment 。MyBatis 默认的事务管理器(transactionManager)是JDBC,数据源(dataSource) 默认 POOLED

  • 映射器标签:Mappers。resource 问题小,class、package 必须要求接口名和xml文件名一样,且在同一个包下。

ResultMap

若实体类名字 和 数据库列名不一致,有两种方法处理:

<select id="getList" resultType="com.wang.pojo.People">
    select * from mybatis.people
</select>
  • 给不一致的起别名

<select id="getList" resultType="com.wang.pojo.People">
    select id,age,name as pname from mybatis.people
</select>
  • 使用ResultMap结果集映射

<resultMap id="PeopleMap" type="com.wang.pojo.People">
    <result column="id" property="id"/>
    <result column="age" property="age"/>
    <result column="name" property="pname"/>
</resultMap>
<select id="getList" resultMap="PeopleMap">
    select * from mybatis.people
</select>

注解

使用注解开发,如下:

@Select("select id,age,name as pname from mybatis.people")
public List<People> getList();
​
// 并在 mybatis-config.xml 里面注册绑定接口
<mappers>
    <mapper class="com.wang.Dao.PeopleMapper"/>
</mappers>

带参数,如下:

@Select("select id,age,name as pname from mybatis.people where id = #{Pid}")
public People getPeoplebyId(int Pid);
// 或者
@Select("select id,age,name as pname from mybatis.people where id = #{id}")
public People getPeoplebyId(@Param("id") int Pid);

@ Param() 注解:

  • 基本类型的参数或者 String 类型,需要加上@Param,SQL中引用的是Param中设置的属性名

  • 引用类型不需要加@Param注解

#{} 和 ${} 区别,#{} 能够防止sql注入,后者不能

安装lombok插件,导入jar包,插入注解,如@Data,可自动生成 get、set、toString、hashcode、equals方法

多对一

子查询

<select id="getStudents" resultMap="TS">
    select * from mybatis.student
</select>
​
<resultMap id="TS" type="com.wang.pojo.Student">
    <result property="id" column="id"/>
    <association property="teacher" column="tid" javaType="com.wang.pojo.Teacher" select="getTeacher"/>
</resultMap>
​
<select id="getTeacher" resultType="com.wang.pojo.Teacher">
    select * from mybatis.teacher where id = #{id}
</select>

联表查询

<select id="getStudents" resultMap="ST">
    select s.id sid,s.name sname,t.name tname,t.id tid
    from mybatis.student as s,mybatis.teacher as t where s.tid=t.id
</select>
<resultMap id="ST" type="com.wang.pojo.Student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="com.wang.pojo.Teacher">
        <result property="name" column="tname"/>
        <result property="id" column="tid"/>
    </association>
</resultMap>

对象用 association, 即为多对一;一个集合用 collection,即为一对多

JavaType用来指定实体类中属性的类型,ofType 用来指定映射到 list 或集合中的pojo的类型,泛型中的约束类型

按照结果嵌套处理(联表查询),按照查询嵌套处理(子查询)

一对多

联表查询

<select id="getTeacher" resultMap="TS">
    select s.id sid, s.name sname,t.name tname,t.id tid 
    from mybatis.teacher as t,mybatis.student as s
    where s.tid = t.id and t.id = #{teaid}
</select>
<resultMap id="TS" type="com.wang.pojo.Teacher">
    <result property="id" column="tid"/>
    <result property="name" column="tname"/>
    <collection property="students" ofType="com.wang.pojo.Student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <result property="tid" column="tid"/>
    </collection>
</resultMap>

子查询

<select id="getTeacher" resultMap="TS">
    select * from mybatis.teacher where id = #{teaid}
</select>
​
<resultMap id="TS" type="com.wang.pojo.Teacher">
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <collection property="students" javaType="ArrayList" ofType="com.wang.pojo.Student" column="id" select="getStu"/>
</resultMap>
​
<select id="getStu" resultType="com.wang.pojo.Student">
    select * from mybatis.student where tid = #{ppid}
</select>

动态SQL

动态SQL就是在拼接SQL语句,按照SQL语句的格式去排列组合。

IF

<select id="queryBlogIF" parameterType="map" resultType="com.wang.pojo.Blog">
    select * from mybatis.blog where 1=1
    <if test="qtitle != null">
        and title = #{qtitle}
    </if>
    <if test="qauthor != null">
        and author = #{qauthor}
    </if>
</select>

choose(when,otherwise)

<select id="queryBlogChoose" parameterType="map" resultType="blog">
    select * from mybatis.blog
    <where>
        <choose>
            <when test="title != null"> and title = #{title} </when>
            <when test="author != null"> and author = #{author} </when>
            <otherwise> and views = #{views} </otherwise>
        </choose>
    </where>
</select>

trim(where,set)

<update id="updateBlog" parameterType="map">
    update mybatis.blog
    <set>
        <if test="title != null"> title = #{title}, </if>
        <if test="authhor != null"> author = #{author}, </if>
    </set>
    where id = #{id}
</update>
<trim prefix="WHERE" prefixOverrides="AND | OR"/>
<trim prefix="SET" suffixOverrides=","/>

SQL 片段

<sql id="sql_section">
    <if test="title != null"> title = #{title}, </if>
    <if test="authhor != null"> author = #{author}, </if>
</sql>
​
<include refid="sql_section"></include>

foreach

<select id="queryBlogForeach" parameterType="map" resultType="blog">
    select * from mybatis.blog
    <where>
        <foreach collection="ids" item="item" open="and (" close=")" separator="or">
            id = #{item}
        </foreach>
    </where>
</select>

缓存

读写分离、主从复制

一级缓存(SqlSession 级别的缓存,默认开启)、二级缓存(需手动开启和配置,namespace级别的缓存)

MyBatis 定义了缓存接口Cache,可通过实现Cache接口来自定义二级缓存;

缓存策略:LRU、FIFO、SOFT、WEAK

一级缓存失效:

  • 查询不同的东西

  • 增删改可能会改变数据,会刷新缓存

  • 查询不同的Mapper.xml

  • 手动清理缓存 sqlSession.clearCache();

在配置文件中的settings中添加 <setting name="cacheEnabled" value="true"/>开启全局缓存,在mapper.xml中插入<cache/> 开启二级缓存,二级缓存在同一个xml下有效,会话提交或关闭会转到二级缓存

若未设置<cache readOnly="true"/>会报错,需要实体类实现序列化接口Serializable,但实现序列化为深拷贝,反序列化后的对象和原对象不是同一个对象,哈希值不同

查询先看二级缓存有没有,再看一级缓存有没有,都没有就去查询数据库

自定义缓存 : EhCache

导入依赖包,在xml中添加<cache type="com.domain.something.MyCustomCache"/>

type 属性指定的类必须实现 org.apache.ibatis.cache.Cache 接口,且提供一个接受 String 参数作为 id 的构造器。

posted on 2022-03-19 18:35  木非辛  阅读(36)  评论(0)    收藏  举报