Mybatis笔记

1、#和$的区别

  • #{key} :获取参数的值,预编译到 SQL 中。安全。
  • ${key} :获取参数的值,拼接到 SQL 中。有 SQL 注入问题。

2、resultType和resultMap区别

  • resultType:返回值类型。– 别名或者全类名,如果返回的是集合,定义的是集合中元素的类型。
  • resultMap – 自定义结果集映射
  • resultType和resultMap不能同时使用。

3、Mybatis缓存机制

  1. 一级缓存:SqlSession级别、默认支持

    每个SqlSession类的实例对象中有一个数据结构(HashMap)可以用来存储缓存数据

    缓存的键(key):namespace + sql id +编写的sql查询语句+参数

    缓存机制是引用返回,不是深拷贝后返回,所以会存在第一次查询结果修改后,影响从缓存中取出的查询结果

  2. 二级缓存:Mapper级别、手动开启(在配置文件中设置cacheEnabled属性为true)

    多个SqlSession类的实例对象操作同一个Mapper配置文件中的sql语句,多个SqlSession类的实例对象可以共用二级缓存,二级缓存是跨SqlSession的。

    一个Mapper有一个自己的二级缓存区域(按照namespace划分),两个Mapper的namespace如果相同,那么这两个Mapper执行的sql查询会被缓存在同一个二级缓存中。

4、动态SQL

  • 场景:根据不同条件拼接 SQL 语句
  • 解决痛点:添加必要的空格、去掉列表最后一个列名的逗号等拼接sql的麻烦

4.1、if

<select id="selectOptions" parameterType="User" resultMap="User">
    select * from  user
    where
    <if test="name!=null">
        name like concat('%',#{name},'%')
    </if>
    <if test="userName!=null">
        user_Name like concat('%',#{userName},'%')
    </if>
</select>

if 测试如果 name 和 userName 都不为空,会拼接两个if中的语句,形成错误,两个条件之间缺少 and 或 or

select * from  user where name like concat('%',?,'%')  user_Name like concat('%',?,'%')

4.2、trim(where, set)

where 可解决 if 存在的问题
where标签会自动处理多出来的AND符号。同理 set标签也一样(set标签用于update语句)

<!--与if不同,如果name和userName都不为空,不会发生错误-->
<select id="selectOptions1" parameterType="User" resultMap="User">
    select * from  user
    <where>
        <if test="name!=null">
            and name like concat('%',#{name},'%')
        </if>
        <if test="userName!=null">
            or user_Name like concat('%',#{userName},'%')
        </if>
    </where>
</select>

4.3、choose (when, otherwise)

类似于Java 的 switch 语句,choose 为 switch,when 为 case,otherwise 则为 default。

<select id="selectOptions2" parameterType="User" resultMap="User">
    select * from  user
    <where>
        <if test="name!=null">
            and name like concat('%',#{name},'%')
        </if>
        <choose>
            <when test="age!=null">
                and age=#{age}
            </when>
            <otherwise>
                and age=12
            </otherwise>
        </choose>
    </where>
</select>

//不传入年龄时,age自动=12

select * from user WHERE name like concat('%',?,'%') or user_Name like concat('%',?,'%') and age=12

4.4、foreach

<select id="selectOptions3" parameterType="User" resultMap="User">
    select * from  user
    <where>
        <if test="name!=null">
            and name like concat('%',#{name},'%')
        </if>
        <if test="idList!=null and idList.size()!=0">
            and id in
            <foreach collection="idList" open="(" separator="," close=")" index="i" item="item">
                #{item}
            </foreach>
        </if>
    </where>
</select>

拼接sql如下

Preparing: select * from user WHERE name like concat('%',?,'%') and id in ( ? , ? )

5、一对一映射和一对多映射

在这里插入图片描述
一个用户可以有一个或多个角色

<!--查询用户及其角色,一对一和一对多只需要修改对应的resultMap即可-->
<select id="selectUserRoleById" resultMap="User">
    select
    u.*,
    r.id role_id,
    r.role_code,
    r.role_name
    from user u
    left join user_role ur on u.id=ur.user_id
    left join role r on ur.role_id=r.id
    where u.id=#{id}
</select>

实体类User

public class User {
	//省略其他属性
    private Role role;
    private List<Role> roleList;
    //省略set、get
    }
public class Role {
    private long id;
    private String roleCode;
    private String roleName;
     //省略set、get
    }

5.1、一对一映射

<resultMap id="User" type="com.xxxx.mybatis.entity.User">
    <id column="id" property="id"/>
    <result column="user_name" property="userName"/>
    <result column="name" property="name"/>
    <result column="birthday" property="birthday"/>
    <result column="age" property="age"/>
    <association property="role" javaType="com.hand.mybatis.entity.Role">
        <id property="id" column="id"/>
        <result property="roleCode" column="role_Code"/>
        <result property="roleName" column="role_Name"/>
    </association>
</resultMap>

5.2、一对多映射

<!--一对多映射-->
<resultMap id="userMap" type="com.xxxx.mybatis.entity.User">
    <id column="id" property="id"/>
    <result column="user_name" property="userName"/>
    <result column="name" property="name"/>
    <result column="birthday" property="birthday"/>
    <result column="age" property="age"/>
    <collection property="roleList" ofType="com.hand.mybatis.entity.Role" foreignColumn="id">
        <id property="id" column="role_id"/>
        <result property="roleCode" column="role_Code"/>
        <result property="roleName" column="role_Name"/>
    </collection>
</resultMap>

引用另一个sql进行行数据查询

<resultMap id="BaseResultMap" type="com.inja.mdm.trader.domain.entity.Customer">
        <result column="customer_id" property="customerId" jdbcType="DECIMAL"/>
        //.......
        <collection property="bankList" ofType="com.inja.mdm.trader.domain.entity.CustomerBank"
                    column="customer_id" foreignColumn="customer_id" javaType="ArrayList"
                    select="com.inja.mdm.trader.infra.mapper.CustomerBankMapper.selectCustomerBankByHeaderId">
        </collection>
        <collection property="contactList" ofType="com.inja.mdm.trader.domain.entity.CustomerContact"
                    column="customer_id" foreignColumn="customer_id" javaType="ArrayList"
                    select="com.inja.mdm.trader.infra.mapper.CustomerContactMapper.selectCustomerContactByHeaderId">
        </collection>
        <collection property="invoiceList" ofType="com.inja.mdm.trader.domain.entity.CustomerInvoice"
                    column="customer_id" foreignColumn="customer_id" javaType="ArrayList"
                    select="com.inja.mdm.trader.infra.mapper.CustomerInvoiceMapper.selectCustomerInvoiceByHeaderId">
        </collection>
    </resultMap>

6、对应关系(最基础)

  1. mybatis-config.xml
<configuration>
	<!-- 数据库映射文件-->
	<properties resource="db.properties"/> 
	<!-- Mapper文件 -->
	<mappers>
    	<mapper resource="mapper/User.xml"/>
    	<mapper resource="mapper/User1.xml"/>
    	<mapper resource="mapper/User2.xml"/>
	</mappers>
</configuration>
  1. XXMapper.xml文件中namespace与对应Mapper接口的Java全限定路径一致
  2. MyBatis引用类的方式(全限定名1+别名2)
<!-- 全限定名-->
<select>
    <select id="selById2" resultType="com.susu.pojo.People" parameterType="com.susu.pojo.People">
  select * from people where id = #{id}
</select>
<!-- 单个类别名-->
<typeAliases>
    <package type="com.susu.pojo.People" alias=”People”/>
    <package type="com.susu.pojo.People1" alias=”People1”/>
</typeAliases>
<!-- 配置包下所有类-->
<typeAliases>
    <package name="com.hand.mybatis.entity"/>
</typeAliases>

单个类别名和配置包之后,即可采用别名进行引用,不必像全限定名一样繁琐

7、其他

  1. 高版本Mybatis使用#{0}、#{1}接受多个参数,需手动开启
<settings>
  <setting name="useActualParamName" value="false" />
</settings>
  1. Parameter ‘idList’ not found. Available parameters are [collection, list]问题
//参数前面加注解@Param(“idList”)标记所遍历集合的名称
public List<User> selectByIdList(@Param("idList") List<Long> idList);
  1. 解耦合分离数据库配置文件
    问题:failed to parse the connection string near ';characterEncoding=utf8&useSSL=true&serverTimezo

将&amp;替换为&

jdbc:mysql://localhost:3306/xxx?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=true&amp;serverTimezone=GMT

替换后

jdbc:mysql://127.0.0.1:3306/xxx?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT
  1. source is null for getProperty(null, “id”)
    问题:一个类中包含另一个类,Mapper文件判断出错
public class User {
	//省略其他属性
	private Role role;
}

解决:在出错的判断前,先判断对象是否为空 ,再判断里面的属性,如下

<if test="role!=null">
    <if test="role.roleCode!=null">
        and role.role_code=#{role.roleCode}
    </if>
    <if test="role.roleName!=null">
        and role.role_name=#{roleName}
    </if>
</if>
  1. Caused by: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘jtFlag’ in ‘class java.lang.String’

强烈注意:@Param(“item”) 不要和 遍历中 collection 的 item=“item” 一样

List<YnjtSmdmItemVO> selectCatgoryChildItems(@Param("item") YnjtSmdmItemDTO itemDTO, @Param("parentCategoryCode") String parentCategoryCode);
 <if test="item.jtFlag != null">
     AND si.jt_flag = #{item.jtFlag}
 </if>
<if test="item.queryItemCodes != null and item.queryItemCodes.size() != 0">
   and si.item_code in
   <foreach collection="item.queryItemCodes" item="item" open="(" close=")" separator=",">
       #{item}
   </foreach>
</if>

8、配置日志

logging:
  level:
    com.netflix.discovery: ${LOG_LEVEL:warn}
    org.apache.ibatis: ${LOG_LEVEL:debug}
    io.choerodon: ${LOG_LEVEL:debug}
    org.hzero.boot.platform.lov: ${LOG_LEVEL:warn}
    org.hzero: ${LOG_LEVEL:debug}
    org.srm: debug
    com.inja: ${LOG_LEVEL:debug}

9、idea插件

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值