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 uidfrom t_address as taleft join t_user as tu on ta.user_id = tu.idwhere 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 aidfrom t_user as tuleft join t_address as ta on tu.id = ta.user_idwhere 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);
}