依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
配置
mybatis:
config-location: classpath:mybatis-config.xml
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.data.*
@MapperScan和@Mapper
@Mapper:在接口类上添加了@Mapper,在编译之后会生成相应的接口实现类。
@Mapper
public interface TestMapper {}
@MapperScan:在Springboot启动类上面添加,指定要变成实现类的接口所在的包,包下面的所有接口在编译之后都会生成相应的实现类。
@SpringBootApplication
@MapperScan("com.mybatis.mappers")
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
在不使用@MapperScan前,需要在每一个Mapper类上面添加注解@Mapper,重复。通过使用@ MapperScan注解,可以不用为每个Mapper类都添加@Mapper注解。
type-aliases-package
mapper.xml文件中resultMap的type,parameterType,resultType引用实体类,需要写上全类名。
在application.yml文件中设置mybatis:type-aliases-package参数后,可以不写全类名,只写一个实体类的名称的话。
mybatis:
type-aliases-package: com.test.data.*
打印sql
第一种
mybatis:
# spring boot集成mybatis的方式打印sql
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
以下表示配置成功

效果

第二种
# 日志的方式打印sql
# com.seamax.bdsearch.dao = 你的mapper包。
logging:
level:
com.seamax.bdsearch.dao: DEBUG
效果

参考:Spring boot mybatis 打印SQL语句_星澄码帝的博客-优快云博客_springboot中mybatis打印sql语句
常用语法
@MapKey返回Map<String,Object> 类型
作用是将List结果集转换成key-value形式的Map结果集,方便快速从结果集中查询指定结果。
Mapper.java
@MapKey("userId")
Map<String,UserInfo> getUserInfoByUserIds(@Param("list") List<String> ids);
Map的key:每条记录的主键(数据库字段或者别名),也可以用其他值表示,ps:此处若将map的key的类型改为其他类型,不影响@MapKey给map的key赋值;
Map的value:表示查询出这条记录的每个字段的字段名称和字段值。
Mapper.xnl
<select id="getUserInfoByUserIds" resultType="java.util.Map">
select
info.id as userId,
info.name as userName
from user_info info
where info.id in
<foreach item="id" collection="list" open="(" separator="," close=")">
#{id}
</foreach>
</select>
truncate清除表数据
使用<update>标签
${}与 #{}区别
-
#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".
-
$将传入的数据直接显示生成在sql中。
order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.
-
#方式能够很大程度防止sql注入,$方式无法防止Sql注入。
$方式一般用于传入数据库对象,例如传入表名.
一般能用#的就别用$。
MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
转义字符
< —— <
> —— >
& —— &
' —— '
" —— "
<![CDATA[ ]]>
这是XML语法。在CDATA内部的所有内容都会被解析器忽略。
如果文本包含了很多的"<"字符 <=和"&"字符——就象程序代码一样,那么最好把他们都放到CDATA部件中。
但是有个问题那就是 <if test=""> </if> <where> </where> <choose> </choose> <trim> </trim> 等这些标签都不会被解析,所以我们只把有特殊字符的语句放在 <![CDATA[ ]]> 尽量缩小 <![CDATA[ ]]> 的范围。
标签
if 标签
例如:判断字符串XXX为0
-
用toString()转成字符串, '0'.toString()
-
改为双引号"0",外层使用单引号。
<if test=" XXX == '0'.toString() ">
或者
<if test = ' XXX != "0" '>
choose标签
实现 if else 逻辑
<choose>
<when test="state == 1">
AND name = #{name1}
</when>
<otherwise>
AND name = #{name2}
</otherwise>
</choose>
foreach标签
需要在db链接url后面带一个参数 &allowMultiQueries=true
批量查询
<select id="queryUserInfoById" resultType="com.user">
SELECT
*
FROM
user_info t
WHERE ID IN
<foreach collection="list" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</select>
批量新增
<insert id="insertBatch">
INSERT INTO xxxx
(a, b, c)
VALUES
<foreach collection ="list" item="user" separator =",">
(#{user.a}, #{user.b}, #{user.c})
</foreach>
</insert>
批量修改
<update id="updateBatchxxxxxx" parameterType="java.util.List">
<foreach collection="list" item="bean" index="index" open="" close="" separator=";">
update xxxxxx
<set>
a= #{bean.a}
</set>
<where>
b= #{bean.b}
</where>
</foreach>
</update>
item:集合中元素迭代时的别名,该参数为必选。
index:在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选
open:foreach代码的开始符号,一般是(和close=")"合用。常用在in(),values()时。该参数可选
separator:元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
close: foreach代码的关闭符号,一般是)和open="("合用。常用在in(),values()时。该参数可选。
collection: 要做foreach的对象,作为入参时,List对象默认用"list"代替作为键,数组对象有"array"代替作为键,Map对象没有默认的键。
入参时可以使用@Param("keyName")来设置键,设置keyName后,list,array将会失效。
还有一种作为参数对象的某个字段的时候。举个例子:如果User有属性List是ids。入参是User对象,那么这个collection = "ids"; 如果User有属性Ids ids,其中Ids是个对象,Ids有个属性List id,入参是User对象,那么collection = "ids.id"。
trim标签
trim 有四个属性
prefix:表示在trim包裹的SQL语句前面添加的指定内容。
suffix:表示在trim包裹的SQL末尾添加指定内容
prefixOverrides:表示去掉(覆盖)trim包裹的SQL的指定首部内容
suffixOverrides:表示去掉(覆盖)trim包裹的SQL的指定尾部内容
实例
<select id="getUserInfo" resultType="UserInfo">
SELECT * FROM t_user t
<trim prefix="WHERE" prefixOverrides="AND |OR">
<if test='id != null'>AND t.ID = #{id}</if>
<if test='name != null'>AND t.NAME = #{name}</if>
</trim>
</select>
<update id="updateUserInfo">
update t_user
set modifier = #{modifier},
modification_time = sysdate()
<trim prefix="," suffixOverrides=",">
<if test='name != null'>name = #{name},</if>
<if test='remark != null'>remark = #{remark},</if>
</trim>
where id = #{id}
</update>
事务管理
例如:删除菜单时,需要同时删除角色菜单关系表,如果两张表中有一个表删除失败返回false或者产生异常,都会产生事务回滚,将之前修改的数据进行回滚。
第一步,在springboot的启动类上开启事务,注解@EnableTransactionManagement
@EnableTransactionManagement
public class SystemManagementApp {}
第二步:事务注解,@Transactional(rollbackFor = Exception.class)
@Transactional(rollbackFor = Exception.class)
public Result deleteMenu(String navigationUuid) {}
正常情况下加注解@Transactional和try catch捕获异常会让注解失效。
解决办法就是在catch语句块中添加TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
@Transactional(rollbackFor = Exception.class)
public Result deleteNavigation(String navigationUuid) {
try {
// TODO
} catch (Exception e) {
// TODO
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return result;
}
}
自定义类型转换 TypeHandler
全局配置
配置一:
mybatis-config.xml配置文件
<configuration>
<typeHandlers>
<typeHandler handler="com.xxx.xx.xxx.mybatis.handler.Timestamp2LongHandler"/>
</typeHandlers>
</configuration>
在 SpringBoot 中指定如下配置,否则将不会生效
mybatis:
config-location: classpath:mybatis-config.xml
配置二:
springboot 配置文件,可以通过指定type-handlers-package来注册 TypeHandler
mybatis:
type-handlers-package: com.xxx.xx.xxx.mybatis.handler
使用:
在实体类上使用
@TableField(typeHandler = JacksonTypeHandler.class)
@ApiModelProperty(value = "显示颜色 {\"color\":\"\",\"id\":\"\"}")
private JSONObject color;
在xml的<result>标签中,通过 typeHandler 指定
<result column="ext_info" property="extInfo" typeHandler="com.zhyq.sys.basic.common.mp.type_handler.JacksonTypeHandler"/>