MyBatis
1.联查
1.1 一对一
例如,有user表和address表,其中每一个用户可以有多个地址,每个地址只能对应一个用户
以address表为主表,user表为副表,通过address表联查user表的形式就是一对一
如何进行一对一查询?
首先,在vo包下创建一个AddressAndUserVO类,并在mapper包下的IAddressMapper接口中定义一个抽象方法
package com.tledu.mydemo.vo;
import com.tledu.mydemo.entity.User;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* ClassName: AddressAndUserVO
* Pacakage: com.tledu.mydemo.vo
* Description:
*
* @Author: 刘松泽
* @Create 2024/3/27 11:07
* @Version 1.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AddressAndUserVO {
private Integer id;
private String addr;
private String phone;
private String postcode;
private Integer userId;
private User user;
}
/**
* 一对一的联查 主表为t_address 副表为t_user
* @param id
* @return
*/
AddressAndUserVO getAddressAndUser(int id);
然后,到对应的xml文件中
<resultMap id="AddressAndUserMap" type="AddressAndUserVO" autoMapping="true">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<association property="user" javaType="User" column="user_id" autoMapping="true">
<id column="uid" property="id"/>
</association>
</resultMap>
<!--联查 一对一-->
<select id="getAddressAndUser" parameterType="int" resultMap="AddressAndUserMap">
select ta.*, tu.*, tu.id as uid
from t_address as ta
left join t_user as tu on ta.user_id = tu.id
where ta.id = #{id}
</select>
1.2 一对多
还是以user表和address表为例,以user表为主表,address表为副表,通过user表联查address表的形式就是一对多
如何进行一对多查询?
首先,在vo包下创建一个UserAndAddressVO类,在mapper包下的IUserMapper接口中定义一个抽象方法
package com.tledu.mydemo.vo;
import com.tledu.mydemo.entity.Address;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* ClassName: UserAndAddressVO
* Pacakage: com.tledu.mydemo.vo
* Description:
*
* @Author: 刘松泽
* @Create 2024/3/27 11:07
* @Version 1.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserAndAddressVO {
private Integer id;
private String username;
private String password;
private String nickname;
private Integer type;
private List<Address> addressList;
}
/**
* 一对多的联查 主表为t_user 副表为t_address
* @param id
* @return
*/
UserAndAddressVO userAndAddress(int id);
然后,到对应的xml文件中
<resultMap id="UserAndAddressMap" type="userAndAddressVO" autoMapping="true">
<id column="id" property="id"/>
<collection property="addressList" column="id" javaType="list" ofType="com.tledu.mydemo.entity.Address"
autoMapping="true">
<id column="aid" property="id"/>
<result column="user_id" property="userId"/>
</collection>
</resultMap>
<!--联查 一对多-->
<select id="userAndAddress" parameterType="int" resultMap="UserAndAddressMap">
select tu.*, ta.*, ta.id as aid
from t_user as tu
left join t_address as ta on tu.id = ta.user_id
where tu.id = #{id}
</select>
2.事务
2.1 事务的四大特性(ACID)
① 原子性:不可再分
② 一致性:对数据库影响前后数据保持一致
③ 隔离性:处理数据的请求之间时隔离的
④ 持久性: 对数据库的影响是持久的
2.2 隔离机制
① 读未提交
② 读已提交(默认隔离机制)
③ 可重复读
④ 序列化
3.分页
3.1 为什么要分页?
当数据特别多的时候,单次请求返回大量的数据会消耗很多时间。对于数据量特别大的查询,我们都会采用分页查询
3.2 如何分页?
(1)手动分页
首先,在dto包下创建一个类帮助我们进行分页相关的计算
例如
package com.tledu.mydemo.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* ClassName: PageUtilDTO
* Pacakage: com.tledu.mydemo.dto
* Description:
*
* @Author: 刘松泽
* @Create 2024/3/27 16:15
* @Version 1.0
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class PageUtilDTO {
private Integer pageNum; //要获取第几页
private Integer pageSize; //每一页的数据个数
//通过次方法将pageNum设置为该页开始的索引
public void getStartNum() {
this.pageNum = (this.pageNum - 1) * this.pageSize;
}
}
然后,在接口中定义一个抽象方法
/**
* 手动分页查询地址
* @param pageUtilDTO
* @return
*/
List<Address> getAddressPage(PageUtilDTO pageUtilDTO);
之后,在xml文件中
<resultMap id="AddressPageMap" type="address" autoMapping="true">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
</resultMap>
<!--分页查询-->
<select id="getAddressPage" parameterType="pageUtilDTO" resultMap="AddressPageMap">
select *
from t_address limit #{pageNum},#{pageSize}
</select>
测试
//手动分页
@Test
public void getAddressPage() {
Integer pageNum = 3;
Integer pageSize = 2;
PageUtilDTO pageUtilDTO = new PageUtilDTO();
pageUtilDTO.setPageNum(pageNum);
pageUtilDTO.setPageSize(pageSize);
pageUtilDTO.getStartNum();
List<Address> addressList = session.getMapper(IAddressMapper.class).getAddressPage(pageUtilDTO);
System.out.println(addressList);
}
(2) 自动分页
首先,需要引入依赖
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
然后,在mybatis-config.xml文件中的typeAliases标签与environments标签之间增加插件
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
<property name="param1" value="value1"/>
</plugin>
</plugins>
然后就可以使用自动分页的插件了
例如
在接口中定义一个抽象方法
/**
* 自动分页查询地址
* @return
*/
List<Address> getAddressAutoPage();
然后,到对应的xml文件中
<resultMap id="AddressPageMap" type="address" autoMapping="true">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
</resultMap>
<!--分页查询-->
<select id="getAddressAutoPage" resultMap="AddressPageMap">
select *
from t_address
</select>
测试
//自动分页
@Test
public void getAddressAutoPage() {
Integer pageNum = 2;
Integer pageSize = 4;
PageHelper.startPage(pageNum, pageSize);
List<Address> addressList = session.getMapper(IAddressMapper.class).getAddressAutoPage();
System.out.println(addressList);
}