在实现分页操作的过程中,可以在SQL语句中不写两条SQL来统计总查询数、不限制分页条件,将这些功能在service层用PageHelper实现。
引入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.7</version>
</dependency>
在service层实现类中重写方法
@Override
public PageResult<Emp> page(Integer page, Integer pageSize) {
PageHelper.startPage(page, pageSize);
Page<Emp> p = (Page<Emp>)empMapper.list();
return new PageResult<>(p.getTotal(), p.getResult());
}
Page<E>继承ArrayList<E>,此处强转后调用Page类中的getTotal()和getResult()方法,得到总结果数和查询结果列表。
---------------------------------------------------------------------------------------------------------------------------------
在controller层接收前端传来的请求参数时,若没有参数,可使用@RequestParam注解在方法中为参数设置默认值。
例如没有参数时默认请求第一页,每页十条数据
@RequestParam(defaultValue = "1") Integer page,@RequestParam(defaultValue = "10") Integer pageSize
请求参数过多时,方法内形参过多导致代码冗长且可读性差,此时编写一个实体类用一个实体对象来封装。
请求参数为日期,使用@DateTimeFormat注解规定格式。
---------------------------------------------------------------------------------------------------------------------------------
在条件分页查询中,需对姓名模糊查询:name like '%查询的内容%',而为了防止SQL注入,应使用预编译,即name like '%#{name}%'。而在引号中的#{name}无法被识别。
解决方案:
name like concat('%', #{name}, '%')
---------------------------------------------------------------------------------------------------------------------------------
MyBatis中的动态SQL
当条件查询时某个参数没有填写,值为null,普通的SQL语句依然将null作为查询的条件。
解决方案:动态SQL,在Mapper映射文件中使用<if>标签,当标签中的条件符合时,才会拼接标签包裹的SQL语句。
此时还有另外一个问题,如果where后的第一个条件语句没有拼接上,后边的语句拼接到where后会出现where and....的情况造成语法错误。
解决方案:使用<where>标签,MyBatis 的 <where> 标签会智能地处理 AND 和 OR,确保生成的 SQL 语句语法正确。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ytao.mapper.EmpMapper">
<select id="list" resultType="com.ytao.pojo.Emp">
select e.*, d.name deptName
from emp e
left join dept d on e.dept_id = d.id
<where>
<if test="name != null and name != ''">
and e.name like concat('%', #{name}, '%')
</if>
<if test="gender != null">
and e.gender = #{gender}
</if>
<choose>
<when test="begin != null and end != null">
AND e.entry_date BETWEEN #{begin} AND #{end}
</when>
<when test="begin != null">
AND e.entry_date >= #{begin}
</when>
<when test="end != null">
AND e.entry_date <= #{end}
</when>
</choose>
</where>
order by e.update_time desc
</select>
</mapper>
要一次插入多条数据,却又不知道具体要插入多少条。
解决方案:使用<for each>标签遍历插入
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ytao.mapper.EmpExprMapper">
<insert id="insertBatch">
insert into emp_expr(emp_id, begin, end, company, job) values
<foreach collection="exprList" item="expr" separator=",">
(#{expr.empId}, #{expr.begin}, #{expr.end}, #{expr.company}, #{expr.job})
</foreach>
</insert>
</mapper>
---------------------------------------------------------------------------------------------------------------------------------
事务中的所有操作必须全部正确运行,才会被提交,否则回滚。
Spring中的事务管理:在需要创建事务的类、方法或者接口上使用@Transactional注解。@Transactional默认遇到RuntimeException(运行时异常)才会回滚,因此要设置注解中的一个属性值:rollbackFor = {Exception.class},这样才会遇到所有异常都回滚。
@Transactional中还有一个属性propagation,默认值为Propagation.REQUIRES,此时这个事务方法被另一个事务方法调用时,会自动加入调用方法的事务中,此时出现问题,当我们想在一个finally中用一个方法来将日志写入数据库中时,如果调用的方法中出现异常,日志方法中向数据库表中插入数据的语句也被回滚,无法记录所有的提交记录。
设置属性propagation = Propagation.REQUIRES_NEW,此时这个事务方法被另一个事务方法调用时,依然会创建新事务,不受调用方法中事务回滚的影响。
---------------------------------------------------------------------------------------------------------------------------------
复习事物的四大特性-ACID
原子性、一致性、隔离性、持久性
---------------------------------------------------------------------------------------------------------------------------------
今日在自己完成条件分页查询的接口功能时,因为不熟练漏掉许多细节,导致出现很多bug,修bug花费了大量时间。但能够通过使用debug断点、阅读控制台中的异常信息日志并利用ai工具找到bug点并修复,我觉得收获很大。