- mybatis
- mybatis分页问题
- #和$符号的区别
- mybatis的优缺点
- mybatis的xml映射文件中,不同的xml映射文件的id是否可以重复
- mybatis的一二级缓存?
- mybatis进行目标对象映射
- mybatis的工作原理
- 采用全量查询进行list分页
// 方式一
List<String> data = new ArrayList<>();
List<List<String>> partition = Lists.partition(data, pageSize);
List<String> list = partition.get(currPage - 1);
// 方式二
// 从第几条数据开始
int firstIndex = (currPage - 1) * pageSize;
// 到第几条数据结束
int lastIndex = currPage * pageSize;
data.subList(firstIndex, lastIndex);
缺点:数据量大的时候不能进行全量查询
- 使用limit进行查询
## 第2是偏移量 1是查询条数
select * from student limit 2,1
缺点:偏移量较大的时候近乎全量扫描
解决方案如下
## 原sql
SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno order by a.id desc limit 4800000,25;
## 使用索引覆盖+子查询优化
SELECT a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno
where a.id >= (select id from emp order by id limit 4800000,1)
order by a.id limit 25;
## 记住上次查询的末尾 局限性:需要根据唯一主键进行处理,并且分页查询连续查询下一页
SELECT a.id,a.empno,a.empname,a.job,a.sal,b.depno,b.depname
from emp a left join dep b on a.depno = b.depno
where a.id > 4800000
order by a.id limit 25;
- 降级策略:配置limit的偏移量和获取数一个最大值,超过这个最大值,就返回空数据
- pagehelper等工具类,需要添加依赖,原理:拦截待执行的sql,然后重写sql
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.1.10version>
dependency>
具体用法如下:
int pageSize = 10;
int pageNum = 1;
// 方法一
PageInfo<Object> objectPageInfo = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() ->{
// 执行查询
}
);
// 方法二
PageHelper.startPage(pageNum, pageSize);
// 执行查询
// 查询语句
List<String> sqlResult = new ArrayList<>();
PageInfo<String> pageInfo = new PageInfo<>(sqlResult);
// 获取总数
long total = pageInfo.getTotal();
#和$符号的区别
- #{}是参数占位符 预编译,很大程度上防止sql注入,在DBMS中,在替换过程中会自动给参数加上’1’单引号
- ${}是字符串替换符,即sql拼接,不能防止sql注入,在DBMS之外,在进行替换的过程中会直接进行替换 因此需要手动添加单引号(正常在传入的是表名和列名的时候进行使用 $ {})
优点:
1. 基于sql语句编程,sql卸载xml中解除与代码的耦合
2. 减少了代码量,消除了jdbc的大量的冗余代码,不需要手动开关连接
3. 很好的兼容数据库,jdbc支持的同样支持
4. 能够很好的与spring集成
5. 提供映射标签,支持对象和数据库字段的关系映射
缺点:
1. sql语句编写量工作大,当字段多、关联表多时,对开发人员编写sql语句功底有一定要求
2. sql语句依赖于数据库,移植性差,导致数据库不能随意更换
mybatis的xml映射文件中,不同的xml映射文件的id是否可以重复
不同的xml文件如果配置了namespace,那么id可以重复,因为namespace—+id是作为map的key使用的,如果没有namespace那么id重复,在旧版本中namespace是可选的,新版本中是必须有的
mybatis的一二级缓存?
1. 一级缓存:基于PerpetualCache的Hashmap本地缓存,其存储作用域为Session,当Session flush或者close之后,Session中的Cache就会清空
2. 二级缓存:与一级缓存机制相同,其作用域为namespace,并且可以自定义存储源,如Ehcache。默认不打开二级存储,要开启,使用耳机缓存属性类需要实现Serializable序列化接口,可以在配置文件中进行配置
3. 当摸一个作用域的进行了增删改 *** 作之后,默认该作用域下所有select中的缓存将被清除,如果开启了二级缓存,只是根据配置判断是否刷新。
mybatis进行目标对象映射
1. 进行列别名,然后树勇resultType映射到对象
2. 使用标签进行映射,即resultMap编写,通过resultMap映射到实体类当中
mybatis的工作原理
1. 读取MyBatis配置文件:mybatis-config.xml为MyBatis的全局配置文件,配置了MyBatis的运行环境等信息,例如数据库连接信息。
2. 加载映射文件。映射文件即SQL映射文件,该文件中配置了 *** 作数据库的SQL语句,需要在MyBatis配置文件mybatis-config.xml中加载。mybatis-config.xml文件可以加载多个映射文件,每个文件对应数据库中的一张表。
3. 构造会话工厂:通过MyBatis的环境等配置信息构建会话工厂SqlSessionFactory。
4. 创建会话对象:由会话工厂创建SqlSession对象,该对象中包含了执行SQL语句的所有方法。
5. Executor执行器:MyBatis底层定义了一个Executor 接口来 *** 作数据库,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。
6. MappedStatement 对象:在Executor接口的执行方法中有一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息。
7. 输入参数映射:输入参数类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输入参数映射过程类似于 JDBC对preparedStatement对象设置参数的过程。
8. 输出结果映射:输出结果类型可以是Map、List等集合类型,也可以是基本数据类型和POJO类型。输出结果映射过程类似于 JDBC对结果集的解析过程。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)