mybatis常用知识点笔记

一、常用标签

1、< if>

<if test="problemId !=null and problemId !=''">
    AND PROBLEM_ID =#{problemId,jdbcType=VARCHAR}
</if>

2、< choose>...< when>...< otherwise>

相当于if…else

<choose>
    <when test="orderType =='asc'">
        order by ead.OPR_DATE asc
    </when>
    <otherwise>
        order by ead.OPR_DATE desc
    </otherwise>
</choose>

3、< foreach>

遍历集合。

collection:集合变量名称

item:遍历时每个元素的名称

separator:分隔符

open:start字符串

close:end字符串

index:当前序号,标识是第几个元素

当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。

当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。

<if test="list != null">
    <foreach collection="list" item="item" separator=" or " open="(" close=")" index="item_index">
        (
        r.activity_id = #{item.activityId, jdbcType=VARCHAR}
        and r.rule_id = #{item.ruleId, jdbcType=VARCHAR}
        )
    </foreach>
</if>

4、< trim prefix="SET" suffixOverrides=",">

自适应添加前缀(prefix)和后缀(suffix),常用语更新语句。

prefix给sql语句拼接的前缀
suffix给sql语句拼接的后缀
prefixOverrides去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND"
suffixOverrides去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定
<update id="updateUserRank" parameterType="com.sinolife.efs.grown.domain.rank.RankDomain">
    update efs_rank   
    <trim prefix="set" suffixOverrides=",">
        <if test="value!=null and value!=''"> 
            value1 = value1 + #{value,jdbcType=DECIMAL}, 
        </if>
        <if test="desc!=null and desc!=''"> 
            desc1 = #{desc,jdbcType=VARCHAR}, 
        </if>
    </trim>
    where is_valid ='Y'
    and activity_id = #{activityId,jdbcType=VARCHAR} 
    and rule_id = #{ruleId,jdbcType=VARCHAR}
    <if test="userId!=null and userId!=''">
        and user_id = #{userId,jdbcType=VARCHAR}
    </if> 
</update>

5、< bind>

bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:

<select id="selectBlogsLike" resultType="Blog">
  <bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
  SELECT * FROM BLOG
  WHERE title LIKE #{pattern}
</select>

6、< typeAlias> 类型别名

<!-- mybatis-config.xml 中 -->
<typeAlias type="com.someapp.model.User" alias="User"/>

<!-- SQL 映射 XML 中 -->
<select id="selectUsers" resultType="User">
  select id, username, hashedPassword
  from some_table
  where id = #{id}
</select>



二、增、删、改、查

select、insert的标签id 需要和mapper接口类中的方法名一致

1、< select>

  • 直接映射返回到Map
<select id="selectPerson" parameterType="int" resultType="map">
  SELECT * FROM table_name WHERE ID = #{id,jdbcType=VARCHAR}
</select>


  • 直接映射返回到自定义resultMap
<select id="selectPerson" parameterType="int" resultMap="baseDataMap">
  SELECT * FROM table_name WHERE ID = #{id,jdbcType=VARCHAR}
</select>

2、< insert>

insert 方法默认会返回一个int值

<insert id="insertActor" parameterType="canger.study.chapter04.bean.Actor">
    insert into table_name 
    (first_name,last_name) 
    values 
    (#{firstName,jdbcType=VARCHAR},#{lastName,jdbcType=VARCHAR})
 </insert>

3、< delete>

<delete id="deleteByExample" parameterType="string" >
    delete from table_name
    where id = #{id,jdbcType=VARCHAR}
</delete>

4、< update>

<update id="updateUserRank" parameterType="com.sinolife.efs.grown.domain.rank.RankDomain">
    update efs_rank   
    <trim prefix="set" suffixOverrides=",">
        <if test="value!=null and value!=''"> 
            value1 = value1 + #{value,jdbcType=DECIMAL}, 
        </if>
        <if test="desc!=null and desc!=''"> 
            desc1 = #{desc,jdbcType=VARCHAR}, 
        </if>
    </trim>
    where is_valid ='Y'
    and activity_id = #{activityId,jdbcType=VARCHAR} 
    and rule_id = #{ruleId,jdbcType=VARCHAR}
    <if test="userId!=null and userId!=''">
        and user_id = #{userId,jdbcType=VARCHAR}
    </if> 
</update>

三、sql片段

sql片段是一个可被其它语句引用的可重用语句块。

1、定义sql片段:

<sql id="userinfo_sql" >
	 id,name,age
</sql>

2、使用sql片段:

<select id="selectPerson" parameterType="int" resultMap="baseDataMap">
	SELECT 
    <include refid="userinfo_sql" />
	FROM table_name 
    WHERE ID = #{id,jdbcType=VARCHAR}
</select>

四、resultMap结果集

resultMap标签的结构

  • constructor - 用于在实例化类时,注入结果到构造方法中

    idArg - ID 参数;标记出作为 ID 的结果可以帮助提高整体性能
    arg - 将被注入到构造方法的一个普通结果

  • id – 一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能

  • result – 注入到字段或 JavaBean 属性的普通结果

  • association – 一个复杂类型的关联;许多结果将包装成这种类型
    嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用

  • collection – 一个复杂类型的集合
    嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用

  • discriminator – 使用结果值来决定使用哪个 resultMap
    case – 基于某些值的结果映射
    嵌套结果映射 – case 也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射


下面是一个简单的resultMap

<resultMap id="UserBelongToGroupMap" type="com.sinolife.efs.grown.domain.UserBelongToGroupInfo">
    <id column="ID" jdbcType="VARCHAR" property="id" />
    <result column="USER_ID" jdbcType="VARCHAR" property="userId" />
    <result column="MOBILE" jdbcType="VARCHAR" property="mobile" />
    <result column="EMAIL" jdbcType="VARCHAR" property="email" />
    <result column="NICKNAME" jdbcType="VARCHAR" property="nickname" />
    <result column="HEAD_IMG_URL" jdbcType="VARCHAR" property="headImgUrl" />
    <result column="CREATED_USER" jdbcType="VARCHAR" property="createdUser" />
    <result column="CREATED_DATE" jdbcType="TIMESTAMP" property="createdDate" />
</resultMap>

association:嵌套结果集映射(一对一)

property:映射到列结果的字段或属性

javaType:一个 Java 类的完全限定名,或一个类型别名

  • 单步查询:
<resultMap id="cityPlusResultMap" type="canger.study.CityPlus">
    <id column="city_id" jdbcType="VARCHAR" property="id"/>
    <result column="city" jdbcType="VARCHAR" property="name"/>
    <result column="country_id" jdbcType="VARCHAR" property="countryId"/>
    <result column="last_update" jdbcType="VARCHAR" property="lastUpdate"/>
    <association property="country" javaType="canger.study.Country">
        <id column="country_country_id" jdbcType="VARCHAR" property="id"/>
        <result column="country" jdbcType="VARCHAR" property="name"/>
        <result column="country_last_update" jdbcType="VARCHAR" property="lastUpdate"/>
    </association>
</resultMap>

使用级联属性实现一对一查询:

需要countryPlus对象中有一个country成员变量,该成员变量是一个country对象
<resultMap id="cityPlusResultMap" type="canger.study.CountryPlus">
    <id column="city_id" jdbcType="VARCHAR" property="id"/>
    <result column="city" jdbcType="VARCHAR" property="name"/>
    <result column="country_id" jdbcType="VARCHAR" property="countryId"/>
    <result column="last_update" jdbcType="VARCHAR" property="lastUpdate"/>
    <result column="country_country_id" jdbcType="VARCHAR" property="country.id"/>
    <result column="country" jdbcType="VARCHAR" property="country.name"/>
    <result column="country_last_update" jdbcType="VARCHAR" property="country.lastUpdate"/>
</resultMap>
  • 分步查询:

property:映射到列结果的字段或属性

select:子查询的SQL ID。需要加上命名空间namespace

column:传递多参数方式:column="{id=country_id,name=countryName}"

<resultMap id="cityPlusResultMapStep" type="canger.study.chapter04.bean.CityPlus">
    <id column="city_id" jdbcType="VARCHAR" property="id"/>
    <result column="city" jdbcType="VARCHAR" property="name"/>
    <result column="country_id" jdbcType="VARCHAR" property="countryId"/>
    <result column="last_update" jdbcType="VARCHAR" property="lastUpdate"/>
    <association property="country"
                 select="canger.study.selectCountryById"
                 column="country_id">
    </association>
</resultMap>

collection:嵌套结果集映射(一对多)

  • 单步查询:

property:映射到列结果的字段或属性

ofType:一个 Java 类的完全限定名,或一个类型别名

<select id="selectCountryPlusById" resultMap="countryPlusResultMap">
    select 
        country.country_id as country_id,
        country,
        country.last_update as last_update,
        city_id,
        city,
        city.country_id as city_country_id,
        city.last_update as city_last_update
    from country left join city on  country.country_id = city.country_id
    where country.country_id=#{id}
</select>

<resultMap id="countryPlusResultMap" type="canger.study.CountryPlus">
    <id column="country_id" jdbcType="VARCHAR" property="id"/>
    <result column="country" jdbcType="VARCHAR" property="name"/>
    <result column="last_update" jdbcType="VARCHAR" property="lastUpdate"/>
    <collection property="cityList" ofType="canger.study.City">
        <id column="city_id" jdbcType="VARCHAR" property="id"/>
        <result column="city" jdbcType="VARCHAR" property="name"/>
        <result column="city_country_id" jdbcType="VARCHAR" property="countryId"/>
        <result column="city_last_update" jdbcType="VARCHAR" property="lastUpdate"/>
    </collection>
</resultMap>

  • 分步查询:

property:映射到列结果的字段或属性

select:子查询的SQL ID。需要加上命名空间namespace

column:传递多参数方式:column="{id=country_id,name=countryName}"

<select id="selectCountryPlusByIdStep" resultMap="countryPlusResultMapStep">
    select *
    from country
    where country_id=#{id}
</select>

<select id="selectCountryPlusById" resultMap="countryPlusResultMap">
    select 
        city_id,
        city,
        city.country_id as city_country_id,
        city.last_update as city_last_update
    from country left join city on  country.country_id = city.country_id
    where country.country_id=#{id}
</select>


<resultMap id="countryPlusResultMapStep" type="canger.study.CountryPlus">
    <id column="country_id" jdbcType="VARCHAR" property="id"/>
    <result column="country" jdbcType="VARCHAR" property="name"/>
    <result column="last_update" jdbcType="VARCHAR" property="lastUpdate"/>
    <collection property="cityList"
                select="canger.study.selectCityByCountryId"
                column="country_id">
    </collection>
</resultMap>

<resultMap id="countryPlusResultMap" type="canger.study.City">
    <id column="city_id" jdbcType="VARCHAR" property="id"/>
    <result column="city" jdbcType="VARCHAR" property="name"/>
    <result column="city_country_id" jdbcType="VARCHAR" property="countryId"/>
    <result column="city_last_update" jdbcType="VARCHAR" property="lastUpdate"/>
</resultMap>

discriminator :鉴别器(根据字段的值,决定使用哪个结果集映射)

<resultMap id="vehicleResult" type="Vehicle">
    <id property="id" column="id" />
    <result property="vin" column="vin"/>
    <result property="year" column="year"/>
    <result property="make" column="make"/>
    <result property="model" column="model"/>
    <result property="color" column="color"/>
    <discriminator javaType="int" column="vehicle_type">
        <case value="1" resultMap="carResult"/>
        <case value="2" resultMap="truckResult"/>
        <case value="3" resultMap="vanResult"/>
        <case value="4" resultMap="suvResult"/>
    </discriminator>
</resultMap>

五、插入时获取自增或序列作为主键id

  • 使用bind和java.util.UUID函数:
<insert id="insertUser" parameterType="com.study.mybatis.po.User">
    <bind name="id" 
      value='@java.util.UUID@randomUUID().toString().replace("-", "")' />

    INSERT INTO USER
    (id,username,birthday,sex,address)
    VALUES(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
  • Oracle 获取序列:
<insert id="insertUser" parameterType="com.study.mybatis.po.User">
    <selectKey keyProperty="id" resultType="int" order="BEFORE">
        SELECT seq.nextval FROM dual
    </selectKey>

    INSERT INTO USER
    (id,username,birthday,sex,address)
    VALUES(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
  • mysql获取自增主键的值:

它是在插入数据后查,通过LAST_INSERT_ID()查最后一条数据的id。

<insert id="insertUser" parameterType="com.study.mybatis.po.User">
	<selectKey keyProperty="id" resultType="int" order="AFTER">
		SELECT
		LAST_INSERT_ID()
	</selectKey>

	INSERT INTO USER
	(username,birthday,sex,address)
	VALUES(#{username},#{birthday},#{sex},#{address})
</insert>
  • mysql使用UUID()函数:
<insert id="insertUser2" parameterType="com.study.mybatis.po.User">
    <selectKey keyProperty="id" resultType="string" order="BEFORE">
        SELECT UUID() 
    </selectKey>

    INSERT INTO USER
    (id,username,birthday,sex,address)
    VALUES(#{id},#{username},#{birthday},#{sex},#{address})
</insert>



六、常见的 Java 类型内建的类型别名

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator



七、数据库类型和java类型转换关系

类型处理器Java 类型JDBC 类型
BooleanTypeHandlerjava.lang.Boolean, boolean数据库兼容的 BOOLEAN
ByteTypeHandlerjava.lang.Byte, byte数据库兼容的 NUMERICBYTE
ShortTypeHandlerjava.lang.Short, short数据库兼容的 NUMERICSMALLINT
IntegerTypeHandlerjava.lang.Integer, int数据库兼容的 NUMERICINTEGER
LongTypeHandlerjava.lang.Long, long数据库兼容的 NUMERICBIGINT
FloatTypeHandlerjava.lang.Float, float数据库兼容的 NUMERICFLOAT
DoubleTypeHandlerjava.lang.Double, double数据库兼容的 NUMERICDOUBLE
BigDecimalTypeHandlerjava.math.BigDecimal数据库兼容的 NUMERICDECIMAL
StringTypeHandlerjava.lang.StringCHAR, VARCHAR
ClobReaderTypeHandlerjava.io.Reader-
ClobTypeHandlerjava.lang.StringCLOB, LONGVARCHAR
NStringTypeHandlerjava.lang.StringNVARCHAR, NCHAR
NClobTypeHandlerjava.lang.StringNCLOB
BlobInputStreamTypeHandlerjava.io.InputStream-
ByteArrayTypeHandlerbyte[]数据库兼容的字节流类型
BlobTypeHandlerbyte[]BLOB, LONGVARBINARY
DateTypeHandlerjava.util.DateTIMESTAMP
DateOnlyTypeHandlerjava.util.DateDATE
TimeOnlyTypeHandlerjava.util.DateTIME
SqlTimestampTypeHandlerjava.sql.TimestampTIMESTAMP
SqlDateTypeHandlerjava.sql.DateDATE
SqlTimeTypeHandlerjava.sql.TimeTIME
ObjectTypeHandlerAnyOTHER 或未指定类型
EnumTypeHandlerEnumeration TypeVARCHAR 或任何兼容的字符串类型,用来存储枚举的名称(而不是索引序数值)
EnumOrdinalTypeHandlerEnumeration Type任何兼容的 NUMERICDOUBLE 类型,用来存储枚举的序数值(而不是名称)。
SqlxmlTypeHandlerjava.lang.StringSQLXML
InstantTypeHandlerjava.time.InstantTIMESTAMP
LocalDateTimeTypeHandlerjava.time.LocalDateTimeTIMESTAMP
LocalDateTypeHandlerjava.time.LocalDateDATE
LocalTimeTypeHandlerjava.time.LocalTimeTIME
OffsetDateTimeTypeHandlerjava.time.OffsetDateTimeTIMESTAMP
OffsetTimeTypeHandlerjava.time.OffsetTimeTIME
ZonedDateTimeTypeHandlerjava.time.ZonedDateTimeTIMESTAMP
YearTypeHandlerjava.time.YearINTEGER
MonthTypeHandlerjava.time.MonthINTEGER
YearMonthTypeHandlerjava.time.YearMonthVARCHARLONGVARCHAR
JapaneseDateTypeHandlerjava.time.chrono.JapaneseDateDATE



八、mappers配置的几种方式

如果mapper.java 和mapper.xml文件的路径和名称一致,那么就不需要配置:
<mappers> <mapper resource="mybatis/sqlmap/User.xml" /> </mappers>

<mappers>
    <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
    <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
    <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- Using url fully qualified paths -->
<mappers>
    <mapper url="file:///var/mappers/AuthorMapper.xml"/>
    <mapper url="file:///var/mappers/BlogMapper.xml"/>
    <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- Using mapper interface classes -->
<mappers>
    <mapper class="org.mybatis.builder.AuthorMapper"/>
    <mapper class="org.mybatis.builder.BlogMapper"/>
    <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- Register all interfaces in a package as mappers -->
<mappers>
    <package name="org.mybatis.builder"/>
</mappers>



九、mybatis缓存

一级缓存

一级缓存是基于PerpetualCache 的 HashMap本地缓存;

一级缓存的作用域是SqlSession,即不同的SqlSession使用不同的缓存空间;

一级缓存的开启和关闭

  • 一级缓存是默认开启的;
  • 关闭一级缓存只需要在settings中设置localCacheScope为STATEMENT

清空一级缓存的操作

  • SqlSession调用commit方法;
  • SqlSession调用clearCache方法;
  • select标签的flushCache属性为true;
  • SqlSession执行了insert、update或delete操作,此时无论三种标签的 flushCache 属性是否为 false;

二级缓存

二级缓存默认也是采用 PerpetualCache,HashMap存储;

二级缓存的存储作用域为 Mapper(确切说是Namespace),即一个Mapper执行了insert、update或delete操作,不影响另外一个Mapper(不同namespace);

二级缓存可自定义存储实现,如 Ehcache、redis;

二级缓存开启后,需要对应的java Bean实现

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"/>

二级缓存的开启和关闭

  • settings中可设置 cachaEnable为true或false,该属性是二级缓存的总开关,如果关闭,则所有mapper的二级缓存均不生效;
  • 在cachaEnable为true的情况下,在mapper文件中添加<cache/>标签即可开启二级缓存,如果没有该标签,则二级缓存不生效;

cache标签属性

  • **eviction:缓存回收策略:**flushInterval:缓存多长时间清空一次,默认不清空,单位毫秒 ms
    • LRU——最少使用的,移除最长时间不适用的对象;
    • FIFO——先进先出
    • WEAK——弱引用,更积极的移除基于垃圾回收器状态和弱引用规则的对象
    • SOFT——软引用,更积极的移除基于垃圾回收器状态和弱引用规则的对象
  • flushInterval:缓存多久清空一次,默认不清空,时间毫秒 ms
  • readOnly:缓存是否只读
  • size:缓存觉存放元素个数,默认1024
  • type:自定义缓存的全类名



在多个命名空间中共享相同的缓存配置和实例

<cache-ref namespace="com.someone.application.data.SomeMapper"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值