写在文章开头
陆陆续续写了关于Mybatis相关的文章有10+篇,今天又用到了关于集合为空Mybatis拼接出的sql语句异常的问题,遂将之前写过的所有关于Mybatis的文章进行整合,之后关于Mybatis的文章也在这里进行记录,方便后期查阅。
Mybatis 一些地址
1.:Mybatis3 中文官方文档 2. Mybatis PageHelper官方文档 3.Mybatis Plus 官方文档 4.IDEA 神器 Mybatis Code Helper 5.Mybatis Log Plugs 6.Mybatis Code Helper Pro 官方文档
文章正文
1.关于Spring 整合 Mybatis
2.Mybatis 多数据源的操作
3.Mybatis Generator的使用和配置文件 (之后删掉了,用Idea 插件MybatisCodeHelper Pro 吧)
4.关于Mybatis的批量插入的一些写法和坑
5.Mybatis插入与主键相同值的另一个字段
6.关于自己的Mybatis的一些使用技巧~之前师傅说过是奇技淫巧 取不得,龙哥~~
以上是根据想到哪写到哪,所以没有先后顺序,可以在文章Ctrl + F 进行搜索哈
Mybatis批量操作
Mybatis中批量操作方法
1.执行多个sql语句
如果使用insert 中写入了多条语句用;分割开,还需要在url中配置 &allowMultiQueries=true
2.foreach进行sql动态处理
因为两者效率差距很大,所以一般使用foreach进行批量操作
简述操作原理哈
其实Mybatis只是一个模板进行字符串的拼接然后放到mysql中去执行,所以动态sql语句就是必学必会的东西啦
Mybatis的动态SQL
Mybatis的动态SQL语法有如下几种:
在常用来判断是否为空时使用
`if:`
<if test="title != null">
AND title like #{title}
</if>
set:
set常用来更新和删除
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
foreach:
类似arraylist取 并且有index 常用来插入操作
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
bind:
在模糊查询中使用:
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
choose:
如果where后有一个静态条件
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
trim:
如果where后全是动态条件
select * from user
<trim prefix="WHERE" prefixoverride="AND |OR">
<if test="name != null and name.length()>0"> AND name=#{name}</if>
<if test="gender != null and gender.length()>0"> AND gender=#{gender}</if>
</trim>
foreach的批量操作
批量查询
批量查询 一定要判断集合状态
<select id="listExistAccountByBindMobile" resultType="int">
select bind_mobile FROM account WHERE bind_mobile in
<if test="mobileList != null and mobileList.size>0">
<foreach collection="mobileList" open="(" close=")" item="mobile">
#{mobile}
</foreach>
</if>
<if test="mobileList==null or mobileList.size==0">and 1=0</if>
</select>
批量插入
<insert id="batchInsert" >
<choose>
<when test="null != contactsMap and contactsMap.size > 0">
insert ignore into account_address_book (account_id, contact_name, contact_phone) values
<foreach collection="contactsMap" item="name" index="phone" separator=",">
(#{accountId},
#{name},
#{phone})
</foreach>
</when>
<otherwise>
select 0
</otherwise>
</choose>
</insert>
Spring整合Mybatis
SpringBoot 整合mybatis 3种方法
方法一:
如果你熟悉SpringMVC且有Mybatis的Spring配置文件
那么如果你想很快的部署的话:
使用 @ImportResource 注解导入你的xml,恭喜你成功了
方法二:
使用Spring原生配置方式
用@Bean注解配置
但是这里需要注意的是除了MapperScannerConfigurer 其他用的都是SpringBoot的bean
如DataSource和SqlSessionFactory 那么你的bean仅能放到 @SpringBootApplication注解下
也就是启动项下,其他地方@Configuration也会不加载
我认为是设置加载顺序的问题,依赖没有配置好,试了一下午没有出来 作为记录
方法三:
Mybatis Spring Boot项目推荐用 @MapperScan 取扫包 即相当于MapperScannerConfigurer Bean 的作用
有人问了 SqlSession从何而来? Spring Boot配置数据源后会默认产生bean name为 DataSource和SqlSessionFactory的两个bean,当然前提是你的项目仅有一个数据源的情况下
Mybatis多数据源
大致整合了四个数据源,也可以更多哈
1.去除spring boot的默认数据源配置
@SpringBootApplication(
exclude = {DataSourceAutoConfiguration.class}
)
2.我个一般把Mybatis的配置放到模块下面
3.配置MapperScan
4.如果涉及到事务
自定义事务注解
5.关于数据源的配置
6.定义数据源,事务等Bean
多数据源文件的生成可以看我的另一篇博客,利用Thymeleaf生成java代码,其中生成的就是Mybatis多
Mybatis中ResultMap
什么时候使用resultType?
resultType
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。
只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
Mybatis魔法中这样说自动映射功能就是自动查找与字段名小写同名的属性名 (我认为不对)
我已经试验过了!!mybatis3.45 mysql驱动6.0+ mysql 5.7
应该是 类中字段小写后,表中字段小写后然后就可以自动对应起来 相当于两边都进行lowcase 对应这个是mybatis的autoMapping
resultMap
resultMap中标签中需要实现 id和type id为名称 type为指向的类
标签中可以包含以下子标签
id property column property对应类名, column对应表名
如果是单表关系 直接写 多表关系 用
- 关联-association
- 集合-collection
都可以使用columnPrefix 进行加前缀
discriminator结果集映射选择器
mysql when then
如果是在条件中获得size
<if test="map.size > 0">
</if>
如果是在sql中拼接:注意使用
a < ${map.size}
<-- < 小于转义 -->
foreach集合遍历
官方文档地址:http://www.mybatis.org/mybatis-3/zh/dynamic-sql.html
示例:
<foreach collection="map" separator="OR" index="key" item="value" >
#{key},#{value}
</foreach>
最后:请勿将代码直接复制到mybatis中执行,自己手打一遍,因为可能出现网页转义 特殊符号等问题,这会让你很难找到错误原因
Mybatis的日志打印是和mapper.xml中的namespace配置有关
将namespace加入到log配置文件中即可打印日志
mybatis的关联查询嵌套查询有两种
关联嵌套
使用关联嵌套用resultmap引用两个sql会产生n+1问题
使用连接查询 一条sql 没有问题
分页没有问题
集合嵌套
使用集合嵌套用resultmap引用两个sql会产生n+1问题
使用连接查询一条sql没有问题但是会产生分页数据不对
采用1+1解决
Mybatis的基础
Mybatis增删改查的使用
增删改查分别是:
/**
insert
delete
update
selset
*/
//需要注意的是resultType="" resultMap=""
//resultMap 用来返回pojo对象需要用<resultMap type="" id =""></resultMap>定义 我们在使用generator生成时会生成BaseResultMap
还会有到 Base_Column_List 可重用的sql 常用来代替*
Mybatis结果集的映射问题,类型配置别名
类型配置别名方式:
类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余
简单的来说就是每次写完全限定名很麻烦
在mybatis中有很多已经写好的别名 基础数据类型加_ 引用类型用小写
结果集映射在很多情况下都用到了别名
结果几种返回时单体的pojo用 resulttype,返回的是list用resultmap
为什么返回名称用map是因为在mybatis中字段使用map<>保存的 一行数据就是一个map map<“字段名”,“字段值”>
##Mybatis中#{}和${}的使用和注意事项
#{}
用的是最多的并且最好不要用${}
是因为#{}
用来替代?防止sql注入
在传递pojo时不用加注解@Param 直接用属性名称即可,但是一定要写对,我就写错过!-!
##Mybatis和Maven项目中.xml文件是否在target中生成问题
在maven中配置: 这个不是java的问题是maven在编译时会过滤非.java文件,不在classes中生成
<build>
<resources>
<!-- 编译之后包含xml -->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
Mybatis获取主键
原来写过博客 mysql插入与主键相同值的另一个字段
那么在mybatis中如何获取使用呢?
在insert中加上 useGeneratedKeys=“true” keyProperty="…" keyProperty为你要自增的字段,在插入后会返回到原实体中
对于不支持主键的数据库可以使用selectKey来生成id减少代码中的复杂
获取数据库的主键自增SELECT LAST_INSERT_ID();
Mybatis分页
分页还是查询的一种,效率高的分页查询就是每次将上次查询的id或者可以截取的部分取出来用> <取出 这时是二分查找效率高 -
##Mybatis中like查询 使用bind
or
CONCAT('%',#{keyword},'%')
<choose>
<when test="null != contactsMap and contactsMap.size > 0">
</when>
<otherwise>
select 0
</otherwise>
</choose>
多数据源下ResultType的问题
在配置的bean上添加
在application.yml or properties中照常配置 mybatis
然后在创建SqlSessionFactoryBean中配置
@ConfigurationProperties("mybatis")
写在最后
文章还没有整理完毕,因为之前实在写的有点多哈,感觉文章很乱,不清晰,想想怎么整理好点