org.mybatis.spring.boot
mybatis-spring-boot-starter
1.3.2
mybatis:
config-location: classpath:mybatis-config.xml
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.data.*
@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注解。
mapper.xml文件中resultMap的type,parameterType,resultType引用实体类,需要写上全类名。
在application.yml文件中设置mybatis:type-aliases-package参数后,可以不写全类名,只写一个实体类的名称的话。
mybatis:
type-aliases-package: com.test.data.*
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语句_星澄码帝的博客-CSDN博客_springboot中mybatis打印sql语句
作用是将List结果集转换成key-value形式的Map结果集,方便快速从结果集中查询指定结果。
Mapper.java
@MapKey("userId")
Map getUserInfoByUserIds(@Param("list") List ids);
Map的key:每条记录的主键(数据库字段或者别名),也可以用其他值表示,ps:此处若将map的key的类型改为其他类型,不影响@MapKey给map的key赋值;
Map的value:表示查询出这条记录的每个字段的字段名称和字段值。
Mapper.xnl
使用
#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。
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 动态参数时需要注意,用$而不是#
原字符 |
转义后的字符 |
描述 |
< |
< |
小于 |
<= |
<= |
小于等于 |
> |
> |
大于 |
>= |
>= |
大于等于 |
& |
& |
与 |
' |
' |
单引号 |
" |
" |
双引号 |
这是XML语法。在CDATA内部的所有内容都会被解析器忽略。
如果文本包含了很多的"<"字符 <=和"&"字符——就象程序代码一样,那么最好把他们都放到CDATA部件中。
但是有个问题那就是
例如:判断字符串XXX为0
用toString()转成字符串, '0'.toString()
改为双引号"0",外层使用单引号。
或者
需要在db链接url后面带一个参数 &allowMultiQueries=true
INSERT INTO xxxx
(a, b, c)
VALUES
(#{user.a}, #{user.b}, #{user.c})
update xxxxxx
a= #{bean.a}
b= #{bean.b}
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 有四个属性
prefix:表示在trim包裹的SQL语句前面添加的指定内容。
suffix:表示在trim包裹的SQL末尾添加指定内容
prefixOverrides:表示去掉(覆盖)trim包裹的SQL的指定首部内容
suffixOverrides:表示去掉(覆盖)trim包裹的SQL的指定尾部内容
实例
update t_user
set modifier = #{modifier},
modification_time = sysdate()
name = #{name},
remark = #{remark},
where id = #{id}
例如:删除菜单时,需要同时删除角色菜单关系表,如果两张表中有一个表删除失败返回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;
}
}