MyBatis
Mybatis configuration file
template
<?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>
<!--
mybatis 配置文件的主要的两个职责
1. 配置数据源
2. 管理映射文件
3. 设置类型别名
-->
<!-- 配置数据源 -->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 解决 查询 返回 Map 字段 值为 null 不显示 字段的问题 -->
<setting name="callSettersOnNulls" value="true"/>
<!-- 解决驼峰命名和 数据库蛇形命名相互转换的配置 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 设置类型别名 -->
<typeAliases>
<!-- <typeAlias type="com.subai.entity.User" alias="user" /> -->
<!--
如果 通过 package 设置别名,那么 别名的 名字 默认是 类名 (不区分大小写,推荐使用小写!)
-->
<package name="com.subai.entity" />
</typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--合理化配置 分页的参数 , 当页码小于等于0的时候,查询第一页, 当页码大于总页数的时候,查询最后一页 -->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.user}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--
如果使用 package 来管理映射文件, 那么需要满足两个要求
1. 映射文件 和 对应的 接口 名 保持一致
2. 映射文件 和 接口 需要在 同一个包下
如果 后期和 Spring 框架 进行整合, 就可以采用通配符的方式进行一次性的配置
-->
<package name="com.subai.mapper" />
<!-- 该方式只能应用于注解的开发 -->
<!--<mapper class="com.subai.mapper.RoleMapper" />-->
<!--<mapper resource="com/subai/mapper/UserMapper.xml" />-->
<!--<mapper resource="com/subai/mapper/GoodsMapper.xml" />-->
<!--<mapper resource="com/subai/mapper/OrderMapper.xml" />-->
<!--<mapper resource="com/subai/mapper/OrderGoodsMapper.xml" />-->
</mappers>
</configuration>
XML mapper
- sql : a reusable block of statements that can be referenced by other statements
- insert : mapping insert statement
- update : map update statement
- delete : map delete statement
- select : mapping query statement
sql
- The SQL fragment is defined through the sql tag, and the corresponding SQL fragment is introduced through the include tag
<!-- 通过 sql 标签定义 -->
<sql id="columns">
id, username, password, create_time as createTime
</sql>
<!-- 通过 include 标签 引入 -->
<include refid="columns" />
insert
- The first type inserts and gets the primary key
<insert id="save" parameterType="user" useGeneratedKeys="true" keyProperty="id">
insert into tb_user(username, password, create_time) values (#{username}, md5(#{password}), now())
</insert>
- The second inserts and gets the primary key
<insert id="save">
insert into tb_goods(goods_name, goods_price, create_time) values
(#{goodsName}, #{goodsPrice}, now())
<selectKey keyProperty="id" resultType="long" order="AFTER">
select last_insert_id()
</selectKey>
</insert>
update
<update id="update" parameterType="user">
update tb_user set
username = #{username} ,
password = md5(#{password}) ,
create_time = #{createTime} ,
update_time = now()
where id = #{id}
</update>
delete
<delete id="batchRemove">
delete from tb_user where id = #{id}
</delete>
select
- resultType to define the returned result type
<!-- resultType 设置的是查询单条记录的类型 -->
<select id="findUserById" resultType="user">
select id, username, password, create_time, update_time from tb_user where id = #{id}
</select>
- ResultMap Advanced Result Mapping
- Allows the user to define the corresponding relationship between the field name of the query and the entity attribute
<resultMap id="userMap" type="user">
<!--
result 表示 结果集中的一个字段
column : 用来设置 查询的字段名
property : 是用来设置 type类型对应的属性名
javaType : 用来设置 属性的类型
jdbcType : 用来设置 数据库的类型
id 和 result的用法相同,标记 该映射的是一个主键
-->
<id column="id" property="id" />
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="time" property="createTime" />
</resultMap>
<select id="findUserByUsername" parameterType="string" resultMap="userMap">
<!--
如果 参数的类型是字面量类型 (8种基本数据类型+包装类 + String)
且 有且只有一个参数,那么 #{} 中的占位符,可以任意
如果 参数中使用了 @Param 注解,那么只能使用 注解中提供的值作为占位符
-->
select id, username, password, create_time as time from tb_user where username = #{username}
</select>
- The ResultMap advanced result map returns an object
<resultMap id="ogResultMap" type="orderGoods">
<id property="id" column="id" />
<result property="goodsId" column="goods_id"/>
<result property="goodsName" column="goods_name"/>
<result property="goodsPrice" column="goods_price"/>
<result property="goodsNum" column="goods_num"/>
<association property="order" javaType="order">
<id property="id" column="order_id" />
<result property="orderNum" column="order_num"/>
<result property="createTime" column="create_time"/>
<result property="status" column="status"/>
</association>
</resultMap>
<select id="findOrderGoodsByOrderIdOrOrderNum" resultMap="ogResultMap">
select g.id,
g.order_id,
g.goods_id,
g.goods_name,
g.goods_price,
g.goods_num,
t.order_num,
t.user_id,
t.create_time,
t.staus
from tb_order_goods g
right join tb_order t on t.id = g.order_id
<trim prefix="where" prefixOverrides="and |or ">
<choose>
<when test="orderNum != null">
and t.order_num = #{orderNum}
</when>
<when test="orderId != null">
and g.order_id = #{orderId}
</when>
</choose>
</trim>
</select>
- ResultMap Advanced result map returns a collection
<resultMap id="resourceResultMap" type="Resource">
<id property="id" column="id"></id>
<result property="resourceName" column="resource_name"></result>
<result property="resourceDesc" column="resource_desc"></result>
<result property="star" column="star"></result>
<result property="createTime" column="create_time"></result>
<collection property="resourceCommentList" ofType="ResourceComment" >
<id property="id" column="res_id"></id>
<result property="userId" column="user_id"></result>
<result property="content" column="content"></result>
<result property="star" column="cstar"></result>
</collection>
</resultMap>
<select id="findResourceById" resultMap="resourceResultMap">
select r.id,
r.resource_name,
r.resource_desc,
r.star,
r.create_time,
c.res_id,
c.user_id,
c.content,
c.star cstar
from tb_resource r
join tb_resource_comment c
on r.id = c.res_id
where r.id = #{id}
</select>
Dynamic SQL
- if
<update id="update" parameterType="user">
update tb_user set
<if test="username!=null">
username = #{username} ,
</if>
<if test="password!=null">
password = md5(#{password}) ,
</if>
<if test="createTime!=null">
create_time = #{createTime} ,
</if>
update_time = now()
where id = #{id}
</update>
- choose、when、otherwise
<select id="findUser" resultType="user" parameterType="user">
select
id, username, password, create_time as createTime
from tb_user
<!-- where 标签主要适用于 条件的拼接,如果 条件中 多了 and , or , 那么会自动去掉 多余的 and , or -->
<where>
<choose>
<when test="id!=null">and id = #{id}</when>
<when test="username!=null">and username = #{username}</when>
<otherwise>and password = #{password}</otherwise>
</choose>
</where>
</select>
- trim、where、set
<select id="findOrderGoodsByOrderIdOrOrderNum" resultMap="ogResultMap">
select g.id,
g.order_id,
g.goods_id,
g.goods_name,
g.goods_price,
g.goods_num,
t.order_num,
t.user_id,
t.create_time,
t.staus
from tb_order_goods g
right join tb_order t on t.id = g.order_id
<trim prefix="where" prefixOverrides="and |or ">
<choose>
<when test="orderNum != null">
and t.order_num = #{orderNum}
</when>
<when test="orderId != null">
and g.order_id = #{orderId}
</when>
</choose>
</trim>
</select>
- foreach
<insert id="batchSave">
insert into tb_user(username, password, create_time) values
<!--
collection : 定义要遍历的数据
如果传入的参数类型是 List, 那么 collection中的值 写成 list
如果传入的参数类型是 数组 , 那么 collection中的值 写成 array
如果使用了 @Param 注解指定了名字,那么就使用指定的名字
item : 代表 遍历过程中 的 每一条数据 对应的变量, 变量名符合标识符命名规范即可
separator : 用来定义循环中 每一条数据的 分割符号
index : 用来标记该条记录的索引, 从 0 开始
nullable : 是否允许为空,
open : 整个 循环 以 ... 开始
close: 整个循环 以 ... 结尾
-->
<foreach collection="list" item="user" separator=",">
( #{user.username} , md5(#{user.password}) , now() )
</foreach>
</insert>
- bind
For fuzzy query, you need to use the concat function to concatenate %.
In the MySQL database, if the query condition uses a function, it will cause the index to fail.
In mybatis, you can use the bind tag to bind variables,
name is the set variable name, value is the variable value to set
<select id="findUserByLikeName" resultType="user">
<bind name="name" value="'%' + username + '%'" />
select id,username,password, create_time as createTime from tb_user
where username like #{name}
</select>
The difference between ${} and #{} in MyBatis
'#{}' is a placeholder, which is mainly used for the placeholder of the value in SQL. When executing, it will be replaced by ? , and when splicing at the bottom layer, quotation marks
will be automatically added before and after the value. Values can also be escaped, which can be used to prevent SQL injection
'${}' is a placeholder, which is mainly used in SQL structures (non-values), and will not be replaced by ? at the time of execution, and the value will be output literally
as part of the SQL structure
'${}' cannot be abused, because there will be a risk of SQL injection, if you can use #{}, never use ${} for placeholders
cache
- Level 1 cache is enabled by default and cannot be disabled
- Enabling the second-level cache will add caching effects to all selects in the mapping file.
- insert, update, delete will update the cache
- On the select tag, useCache defaults to true, and flushCache defaults to false
- On insert, update, delete tags, useCache is false by default, and flushCache is true by default
- useCache , flushCache To take effect, the second-level cache must be enabled