com.github.pagehelper.PageHelper
github上的一个基于mybatis的分页插件PageHelper
原理:
1.1把计算好的分页放到线程变量中
1.2在mybatis查询,会进入到拦截器中,根据这个线程变量看是否要分页
PageHelper实现分页原理 - 十黎九夏 - 博客园
1.3多数据源适配分页(关于auto-dialect: true是网上看到的 没有亲自尝试)
参考文章
使用Pagehelper进行分页时下一页没有数据依旧有数据返回_花儿小新♥-CSDN博客
之前我没加@Param 报了500 说找不到idList参数
如果是collection,默认是collection="list"
接上边那一点
参考
MyBatis(映射文件中使用foreach标签时报错,属性collection的问题)
MyBatis,在foreach标签对中,使用List类型参数时,collection属性到底怎么写_HairyCoder的博客-CSDN博客
默认collection='list' 但是如果mapper中使用了@Param("") ,collection就得按照@Param指定的值
5.1.1resultMap是xml中定义的<resultMap>标签的id
5.1.2resultType需要写返回类的全路径
5.2.1resultType对应pojo与数据库字段应一一对应
5.2.2 如果数据库中有下划线分割
如数据库字段为user_name,自定义实体属性为userName,可以在application.yml中开启驼峰自动转换
或者application.properties中
5.3.1目前,在我的实际应用中,一般java提供的类如String,Integer的才会用resultType,而自定义的类,一般都用resultMap做字段与实体类属性的映射
5.3.2根据阿里的开发手册,也是resultMap优先
为了解耦
我用了mybatis分页拦截PageHelper,再执行过程中后边加了LIMIT,然后因为这个<select>里边已经写了分号,所以整个的sql就变成了.....;LIMIT ,看到了吧,limit前边有个分号,自然执行出错
如果你不涉及到分页,那这样写可能不会报错
以下为理论知识没有亲自实践
databaseId
比如你写了了两个select id一样 然后就databaseId不一样 一个是mybasql 一个是oracle 那么当url配置的是达梦时候就会执行dm那个select 当url配置的是h2时候就会执行h2那个select
加上databaseId这个属性 属性值和url中jdbc:后边的值一致
为什么我会碰到这个知识点,因为踩了一个坑
公司要从mysql数据库切换到达梦数据库,然后遇到一个字段begin是关键字,切换为达梦后执行是有问题的。
我采取的几种方式
1.我之前的方式是把字段给改了名字begin->beginDM。
2.然后又考虑到有别人用所以又把名字改回去beginDM->begin,并且把关键字加了双引号 "begin"。
3.但是,如果哪天我们再切换成别的数据库怎么办?所以,搜索了mybatis如何兼容多种数据库:databaseId
mybatis在把sql传入DBMS之前,先动态解析,再预编译
${}在动态解析那步,就进行字符串替换,所以我们在控制台能看到即将执行的sql
#{}在预编译那步,才替换为? 所以我们在控制台看到的是带?的sql
8.1.1正例
如想执行的sql是select id from user where user_name = #{userName}
然后入参userName为 张三 那预编译就变成'张三' 即 select id from user where user_name = '张三'
8.1.2反例
如想执行的sql是select id from #{table} where user_name = '张三'
然后传入user 那么sql就变成了 select id from 'user' where user_name = '张三'
此时sql无法执行
所以上一个反例 应该写成select id from ${table} where user_name = #{username}
因为容易出现sql注入,${}是一个简单的String替换,字符串是什么,解析就是什么
${}不安全,容易引起sql注入,举个栗子
如果我的tableName传入的是
那么完整的sql就变成了
其中--where name =?就变成了注释 不会执行 而且还把我user表删了 所以确实不安全
<where>标签
<where>是把第一个and去掉,set是把最后一个逗号,去掉
如下sql,就算classname为空,执行也不会报错
以上,<where>和<set>可以看作<trim>的简写
<where>相当于<trim prefix="where" prefixOverrides="and | or">
<set>相当于<trim prefix="set" suffixOverrides=",">
批量插入
separator表示分割方式 separator="," 就是用逗号,隔开
比如写一个批量插入的sql
INSERT INTO `devdb`.`testorder`(`order1`, `order2`) VALUES (1, 2),(3,4),(3,4),(3,4),(3,4),(3,4),(3,4);
hibernate无法自定义组装sql,对于复杂关联表以及复杂sql支持弱
但是开发速度快,省事
如果一个项目要求几天开发完,首选hibernate
但是hibernate性能不如mybatis
目前只知道mybatis这种模式与动态代理有关:通过Mapper 动态代理机制,可以只编写接口以及方法的定义
xml的namespace是mapper的全路径名
@Mapper或者@MapperScan扫描mapper,
mybatis:mapper-locations扫描xml文件
怎么注册成bean?我的理解:通过mybatis-spring中间件,把扫描到的注册成bean
作用:
1.直接扫描路径,不用每个接口上都写@Mapper : 在接口类上添加了@Mapper,在编译之后会生成相应的接口实现类
2.指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类
到现在,我也一直觉得,mybatis的xml就相当与mapper接口的实现类,不然我们怎么都用@Autowired注入mapper接口
如果对象中有有参得构造方法,需要再mybatis中配置<constructor>,否则mybatis无法实例化对象
查出来数据需要转化成对象时,要用到那个对象得构造方法
数据库主键设置为自动递增时,程序在insert前不知道新的主键是什么
原理:数据库产生过的最大主键加1
比如最大主键101,把他删了,再插入一条,主键就是102
同mysql函数
复杂写法
selectkey中 order为after 是先插入数据后拿到主键
把涉及到的参数都整理到实体里,然后改一下parameterType就行
23.1.mapper接口需要继承
23.2.namespace要一致,xml的namespace要使用子接口的全路径名
Pf1001BaseMapper.xml
Pf1001Mapper.xml
实际应用踩坑
mybatis的自动生成插件生成了mapper A和xml A之后 我新增了extendMapper B 和extendXml B 在mapper B中继承了mapper A
我在B中想使用A的resultMap 但是执行时报B中没有这个resultMap 原因是我xml A中的namespace没有改成mapper B
注意这里