3.mybatis第一个案例-查询
小试牛刀
上面的环境打好了以后,接下来就是对数据库的crud操作了。实际开发当中,查询是最常用的。所以我们来一个查询一张表的所有数据。
首先要在我们的mapper接口上创建一个查询的方法,由于我们是查询所有数据,那么肯定返回的是一个集合,那么我们就用List来接收,方法名称随便起,就叫selectAll()吧。然后在mapper对应的xml文件中,编写对应的sql语句。详细代码如下
public interface StudentMapper {
/**
* 查询所有
* @return
*/
List<Student> selectAll();
}
<?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">
<!--这里的namespace取值就是接口全限定类目-->
<mapper namespace="com.bky.mapper.StudentMapper">
<!-- id属性值要和接口方法名一样(必须),resulType是查询后映射的实体类-->
<select id="selectAll" resultType="com.bky.entity.Student">
select *
from student
</select>
</mapper>
上面将主要的实现写完了,但是如何调用这个方法呢?那么我们要创建一个测试类,并且通过mybatis提供的api来实现这个接口(StudentMapper)。从而调用selectAll()方法。好的,直接上代码:
public class Test1 {
public static void main(String[] args) throws IOException {
//将配置文件变成输入流
InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
//创建SqlSessionFactoryBuilder对象,用来解析输入流
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//解析输入流后生成SqlSessionFactory
SqlSessionFactory factory = builder.build(input);
//SqlSessionFactory生成SqlSession,本质上就是用SqlSession来跟数据库打交道
SqlSession sqlSession = factory.openSession();
//利用SqlSession提供的api来获取我们接口的实现类,这里用到了jdk的动态代理
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
//调用对应的接口方法
List<Student> students = studentMapper.selectAll();
for (Student student : students) {
System.out.println("student = " + student);
}
}
}
控制台输出结果以及相关日志:
哈哈,只有一条数据。好的,完成了查询所有的演示。
很多同学看到这,会认为最终封装到的实体类只能是Student,其实不然。只要你的实体类字段能跟数据库对应上,都是能将结果集封装到你自己定义的实体类中的。只要在sql映射文件中做一个小小的修改就行。
好,接下来我们定义一个StudentDTO类,结构跟Student一样:
@Data
public class StudentDTO {
/**
*
*/
private Long id;
/**
* 姓名
*/
private String username;
/**
* 性别
*/
private String gender;
}
我们将查询所有的方法返回值的list泛型变为他:
/**
* 查询所有
* @return
*/
List<StudentDTO> selectAll();
修改对应的sql的返回值resultType:
<select id="selectAll" resultType="com.bky.dto.StudentDTO">
select *
from student
</select>
不测试了,大家可以试一下。
接下来我们带条件查询,比如根据id查询,但是这个id是在实体类中,那么接口方法是这样
/**
* 根据条件查询
* @param student 条件值在对象中
* @return
*/
Student queryById(Student student);
上面我的注释写的是根据条件,是因为参数是一个实体类,而实体类中参数很多,所以你的查询条件就很灵活,可以根据id,username..... 而我这里只演示根据参数中的id查询,这里就用到mybatis提供的 #
来取值
<select id="queryById" resultType="com.bky.entity.Student" parameterType="com.bky.entity.Student">
select * from student where id = #{id}
</select>
mybatis别名配置
上面我们完成了一个简单的查询,接下来我们要给我们的实体类配置一个别名。请看我们的sql映射文件,resultType的属性值是一个全限定类名。我觉得麻烦。mybatis也很聪明,知道我们程序员很懒。于是提供了别名设置。
打开我们的mybatis的配置文件,只要增加如下配置,我们就可以使用别名了。
<configuration>
<typeAliases>
<!-- 给我们的实体类设置别名,可以写多个包路径-->
<package name="com.bky.entity"/>
<package name="com.bky.dto"/>
</typeAliases>
当我们配置了别名以后,我们sql语句的返回类型就可以不用写包名了,直接写实体类的名称,并且大小写任意
<select id="selectAll" resultType="studentDtO">
select *
from student
</select>
<!--实际开发不要这么顽皮啊,写类的简单名称就行(StudentDTO),别像我这样搞事情。。。-->
好了,也很简单,我就不测试了。
上面这些简单的demo大家自己玩玩。有个小点要注意,如果你的sql语句查询会返回多个记录,而你的接口返回值是单个实体对象,那么这样会报错。
resultMap标签的使用
接下来有个令人难缠的问题,比如我现在数据库有个字段跟实体类不一样,比如这样:
对应实体类:
@Data
public class Student implements Serializable {
/**
*
*/
private Long id;
/**
* 姓名
*/
private String username;
/**
* 性别
*/
private String gender;
/**
* 女朋友,多个女朋友逗号隔开
*/
private String girlFriends;
private static final long serialVersionUID = 1L;
}
很显然,女朋友这个字段跟表字段对应不上。肯定封装不进来,不信我们测试一下,还是拿查询所有来测试
这样,他们的女朋友无缘无故消失了,究其原因,还是字段没对应上,怎么解决这个问题呢?
方法一,sql查询语句对应的字段起别名
我们现在就只是女朋友这个字段对应不上,那么在查询的时候,将女朋友这个字段单独捞出来起个别名就行,这个别名跟实体类女朋友字段一样就行:
<select id="selectAll" resultType="Student">
select id,username,gender,girl_friends girlFriends
from student
</select>
是不是很简单,对,就这么简单。可是这样一来就有个小问题,如果我现在一个实体类有很多字段跟表字段对应不上,难道都起别名了吗?那不违背了程序员上班摸鱼的原则吗???于是,我们引出了resultMap标签
方法二,resultMap标签使用
换一个实体类吧,这个实体类咱们就多弄几个字段跟表字段对应不上。
@Data
public class Order {
/**
* 订单id,主键
*/
private Long orderId;
/**
* 订单项
*/
private String orderItem;
/**
* 下单时间
*/
private Date createTime;
}
对应的表:
对应的mapper接口
public interface OrderMapper {
List<Order> selectAll();
}
xml映射文件:
<?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.bky.mapper.OrderMapper">
<select id="selectAll" resultType="com.bky.entity.Order">
select * from my_order
</select>
</mapper>
上面这个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">
<!--这里的namespace取值就是接口全限定类目-->
<mapper namespace="com.bky.mapper.OrderMapper">
<!-- 配置resultMap
id,在当前的xml文件里面必须唯一,因为resultMap可以配置多个,type就是你要映射的实体类
由于我们配置了别名,所以可以简写。
-->
<resultMap id="orderMap" type="Order">
<result property="orderId" column="order_id"/>
<result property="orderItem" column="order_item"/>
<result property="createTime" column="create_time"/>
</resultMap>
<!-- resultType换成resultMap-->
<select id="selectAll" resultMap="orderMap">
select * from my_order
</select>
</mapper>
搞定!!!!
mybatis一对一查询
一对一查询也是一个常规操作,我现在有个爸爸表和一个妈妈表,对应实体如下
@Data
public class Father implements Serializable {
/**
*
*/
private Long id;
/**
*
*/
private String username;
/**
*
*/
private Integer age;
private static final long serialVersionUID = 1L;
}
@Data
public class Mother implements Serializable {
/**
*
*/
private Long id;
/**
*
*/
private String motherName;
/**
* 关联的爸爸id
*/
private Long fatherId;
private static final long serialVersionUID = 1L;
}
一对一查询方式有很多,随便介绍几种吧,第一种就是我们新建一个dto类,然后将爸爸的字段和妈妈的字段全部塞到dto中去(当然你直接在father类添加mother字段也是可以的,懂得都懂)。
@Data
public class FatherDTO {
/**
* 爸爸id
*/
private Long id;
/**
* 爸爸名字
*/
private String username;
/**
* 爸爸年龄
*/
private Integer age;
/**
* 妈妈id
*/
private Long motherId;
/**
* 妈妈名字
*/
private String motherName;
/**
* 关联的爸爸id
*/
private Long fatherId;
}
对应的mapper方法:
public interface FatherMapper {
FatherDTO selectFatherAndMotherByFid(Long id);
}
<select id="selectFatherAndMotherByFid" resultType="FatherDTO">
<!--这里的妈妈返回的字段要起别名,目的是为了跟FatherDTO对应上-->
select f.*
,m.id motherId
,m.mother_name motherName
,m.father_id fatherId from father f
left join mother m
on f.id = m.father_id
where f.id = #{id}
</select>
好,这种方式大家要记住。
还有中方式就是将妈妈类嵌套在爸爸类中,这种方式也很多件,再来建立一个dto:
@Data
public class FatherInDTO {
/**
* 爸爸id
*/
private Long id;
/**
* 爸爸名字
*/
private String username;
/**
* 爸爸年龄
*/
private Integer age;
/**
* 妈妈实体类
*/
private Mother mother;
}
这时候呢,sql语句的写法会发生一些变化,不能直接去join查询了。我们来看看如何操作。
首先在father的xml文件中建立一个resultMap标签,这个标签有点特殊,要关联妈妈的相关信息和sql
<resultMap id="FinMMap" type="FatherInDTO">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
<result property="age" column="age" jdbcType="INTEGER"/>
<!-- association就是这个结果集映射的一个嵌套
property表示FatherInDTO中哪个嵌套对象,
javaType 表示这个对象是什么类型
select 表示查询妈妈的方法调用的是哪个
colum 表示跟FatherInDTO中哪个字段关联,很显然,是FatherInDTO的id字段
-->
<association property="mother" javaType="com.bky.entity.Mother" select="com.bky.mapper.MotherMapper.selectByFatherId" column="id"></association>
</resultMap>
对应妈妈的mapper接口和xml文件
public interface MotherMapper {
Mother selectByFatherId(Long fId);
}
<?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.bky.mapper.MotherMapper">
<resultMap id="BaseResultMap" type="com.bky.entity.Mother">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="motherName" column="mother_name" jdbcType="VARCHAR"/>
<result property="fatherId" column="father_id" jdbcType="BIGINT"/>
</resultMap>
<sql id="Base_Column_List">
id,mother_name,father_id
</sql>
<select id="selectByFatherId" resultMap="BaseResultMap">
select * from mother where father_id = #{fId}
</select>
</mapper>
来测试下吧:
好的,一对一讲完了,上面这些写法满足了大部分需求,肯定还有其他的写法。大家可以自己查阅一下。这里就不介绍了
mybatis一对多查询
一对多查询也是实战中经常用到的,跟一对一差不多,一对多也是类似的写法,比如我现在有父亲类和孩子类,一个父亲会有多个孩子。
@Data
public class Father implements Serializable {
/**
*
*/
private Long id;
/**
*
*/
private String username;
/**
*
*/
private Integer age;
/**
* 所有的孩子
*/
private List<Children> childrenList;
}
@Data
public class Children implements Serializable {
/**
*
*/
private Long id;
/**
*
*/
private String username;
/**
*
*/
private Integer age;
/**
* 爸爸id
*/
private Long fatherId;
}
我们在爸爸mapper接口定义一个查询某一个爸爸和他的所有孩子,根据爸爸的id查询
/**
* 查询爸爸和他的所有孩子
* @param fid 爸爸id
* @return
*/
Father selectFatherAndChildByFid(Long fid);
同样,还是要在爸爸的xml文件建立一个resultMap标签,这个标签就有查询多个孩子的用法,其实跟一对一差不多
<resultMap id="FatherChildMap" type="Father">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
<result property="age" column="age" jdbcType="INTEGER"/>
<!-- 一对多查询,用这个标签,
property 多的一方在一的一方的属性名
ofType 多的类型
column 关联的一的一方的字段
select 调用多的一方的哪个查询方法
-->
<collection property="childrenList" ofType="com.bky.entity.Children" column="id" select="com.bky.mapper.ChildrenMapper.selectByFatherId">
</collection>
</resultMap>
<select id="selectFatherAndChildByFid" resultMap="FatherChildMap">
select * from father where id = #{fid}
</select>
多的一方(孩子)xml中的方法
<resultMap id="BaseResultMap" type="com.bky.entity.Children">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
<result property="age" column="age" jdbcType="INTEGER"/>
<result property="fatherId" column="father_id" jdbcType="BIGINT"/>
</resultMap>
<select id="selectByFatherId" resultMap="BaseResultMap">
select * from child_ren where father_id = #{fid}
</select>
这样就行了,我们进行简单测试
mybatis多对多查询
多对多也是实际开发常用的,我现在有三张表,老师表,班级表,老师班级对应表
对应实体类
@Data
public class Classes implements Serializable {
/**
*
*/
private Long id;
/**
* 班级编号
*/
private String classesNo;
private static final long serialVersionUID = 1L;
}
@Data
public class Teacher implements Serializable {
/**
*
*/
private Integer id;
/**
* 教师工作证编号
*/
private String teacherNo;
/**
* 教师姓名
*/
private String username;
private static final long serialVersionUID = 1L;
}
@Data
public class ClassTeacher implements Serializable {
/**
*
*/
private Long id;
/**
* 教师id
*/
private Long teacherId;
/**
* 班级id
*/
private Long classId;
private static final long serialVersionUID = 1L;
}
那么现在有个需求就是根据教师的id查询对应班级下的所有老师,暂不查询班级,只查询老师。其实这个问题的难点并不是mybatis,而是对应的sql语句比较难。这是我写的sql语句,大家看一下:
SELECT
*
FROM
teacher
WHERE
id IN (
SELECT
t.id
FROM
teacher t
INNER JOIN class_teacher ct ON t.id = ct.teacher_id
WHERE
ct.class_id IN ( SELECT class_id FROM class_teacher WHERE teacher_id = 1 )
GROUP BY
t.id
)
Navicat工具执行的结果:
上面这个sql是当老师id为1的时候查询出的所有老师,我们再次看一下老师班级中间表,看看结果对不对
那么sql语句都出来了,整个mybatis查询也容易了,我们在老师mapper接口新建方法
public interface TeacherMapper {
/**
* 根据教师id查询所有的教师
* 就是说,一个老师对应多个班级,那么多个班级又对应
* 多个老师,那么返回所有的老师
* @param tid
* @return
*/
List<Teacher> selectAllById(Long tid);
}
对应xml
<?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.bky.mapper.TeacherMapper">
<resultMap id="BaseResultMap" type="Teacher">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="teacherNo" column="teacher_no" jdbcType="VARCHAR"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
</resultMap>
<select id="selectAllById" resultMap="BaseResultMap" parameterType="java.lang.Long">
SELECT *
FROM teacher
WHERE id in
(SELECT t.id
FROM teacher t
INNER JOIN class_teacher ct ON t.id = ct.teacher_id
WHERE ct.class_id IN (SELECT class_id FROM class_teacher WHERE teacher_id = #{tid})
GROUP BY t.id)
</select>
</mapper>
好,接下来我们将难度升级一点,根据老师id查询所有的老师和所有的班级。这个其实有很多方式,那我们来弄一个最简单的方式,
首先查询所有的老师,这个上面那个案例已经完成了,我们贴一下sql语句
SELECT *
FROM teacher
WHERE id in
(SELECT t.id
FROM teacher t
INNER JOIN class_teacher ct ON t.id = ct.teacher_id
WHERE ct.class_id IN (SELECT class_id FROM class_teacher WHERE teacher_id = 1)
GROUP BY t.id)
我们再查询这个老师对应的所有班级
SELECT
*
FROM
classes
WHERE
id IN ( SELECT class_id FROM class_teacher WHERE teacher_id = 1 )
有了这两个sql语句,我们就可以利用mybatis提供的查询来封装这个结果集,我们在老师类里面加入班级类集合
@Data
public class Teacher implements Serializable {
/**
*
*/
private Integer id;
/**
* 教师工作证编号
*/
private String teacherNo;
/**
* 教师姓名
*/
private String username;
/**
* 对应的班级
*/
private List<Classes> classesList;
private static final long serialVersionUID = 1L;
}
在teacher的mapper接口新增一个方法
/**
* 根据教师id查询所有老师和对应的班级
* @param tid 老师id
* @return
*/
List<Teacher> selectTAndCBytid(Long tid);
对应的xml
<select id="selectTAndCBytid" resultMap="BaseResultMap2" parameterType="java.lang.Long">
SELECT *
FROM teacher
WHERE id in
(SELECT t.id
FROM teacher t
INNER JOIN class_teacher ct ON t.id = ct.teacher_id
WHERE ct.class_id IN (SELECT class_id FROM class_teacher WHERE teacher_id = #{tid})
GROUP BY t.id)
</select>
<resultMap id="BaseResultMap2" type="Teacher">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="teacherNo" column="teacher_no" jdbcType="VARCHAR"/>
<result property="username" column="username" jdbcType="VARCHAR"/>
<collection property="classesList" ofType="com.bky.entity.Classes" column="id" select="com.bky.mapper.ClassesMapper.queryByTid">
</collection>
</resultMap>
那么还要在班级mapper接口添加方法
public interface ClassesMapper {
/**
* 根据老师id查询所有班级
* @param tid
* @return
*/
List<Classes> queryByTid(Long tid);
}
对应xml
<?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.bky.mapper.ClassesMapper">
<resultMap id="BaseResultMap" type="com.bky.entity.Classes">
<id property="id" column="id" jdbcType="BIGINT"/>
<result property="classesNo" column="classes_no" jdbcType="VARCHAR"/>
</resultMap>
<select id="queryByTid" resultMap="BaseResultMap" parameterType="java.lang.Long">
SELECT
*
FROM
classes
WHERE
id IN ( SELECT class_id FROM class_teacher WHERE teacher_id = #{tid} )
</select>
</mapper>
好了,这就搞定了。做个简单的测试
List<Teacher> teachers = this.teacherMapper.selectTAndCBytid(1l);
for (Teacher teacher : teachers) {
System.out.println("当前老师"+teacher);
System.out.println("对应的班级↓↓↓↓↓↓↓↓");
List<Classes> classesList = teacher.getClassesList();
for (Classes classes : classesList) {
System.out.println("classes = " + classes);
}
}
但是这个美中不足的是,在查询班级的时候会多次查询数据库。这个是mybatis机制问题。后续我们看看有没有办法一个sql语句将结果查询并且封装好。
mybatis批量查询
批量查询也是我们实际开发经常用的,比如现在通过id批量查询订单
先看下表数据吧
就两条,id为1,2
那么sql语句就是
SELECT * FROM my_order WHERE order_id IN (1,2)
实际开发我们肯定不是in后面的参数写死,而是动态生成的,怎么做呢?首先还是一样,在mapper接口创建方法,返回肯定是list结构,而方法的参数肯定也是id集合,因为是批量查询嘛。
public interface OrderMapper {
List<Order> selectByIds(List<Long> ids);
}
对应xml
<select id="selectByIds" resultMap="orderMap">
select * from my_order
where order_id in
<!--这里使用这个标签来动态生成()内容 开始(,分隔符用,最后结束用)
还是很容易明白的
-->
<foreach collection="ids" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
<resultMap id="orderMap" type="Order">
<result property="orderId" column="order_id"/>
<result property="orderItem" column="order_item"/>
<result property="createTime" column="create_time"/>
</resultMap>
好,我们来测试看看
List<Order> orders = this.orderMapper.selectByIds(Arrays.asList(1l, 2l));
for (Order order : orders) {
System.out.println("order = " + order);
}
运行代码,控制台发现报错了。。。。
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.apache.ibatis.binding.BindingException: Parameter 'ids' not found. Available parameters are [arg0, collection, list]
### Cause: org.apache.ibatis.binding.BindingException: Parameter 'ids' not found. Available parameters are [arg0, collection, list]
//整个堆栈省略
报错的内容好像是在告诉我们参数ids找不到?这是怎么回事呢?带着疑问,我们进行下一个知识点的学习。
@Param 使用
刚才留下了一个问题,就是为什么找不到我们传递的ids参数,原来是我们少加了一个注解,就是@Param 这个注解,加在什么地方呢?直接上代码
//加上这个注解,mybatis就能识别到你传递的参数了
List<Order> selectByIds(@Param("ids") List<Long> ids);
我们再次测试,发现控制台打印的sql语句也对了
很奇怪,为什么要加这个注解呢?这个以后有机会得看mybatis的源码了。现在我们得熟练使用mybatis。
其实这个注解应该在一上来就讲,但是总感觉不知道从哪里入口。正好批量查询必须使用这个注解。所以引用出来了。下面找几个代表性的用法来玩玩。
比如现在我要查询father表,根据姓名或者年龄查询,而姓名和年龄分别来自两个不同的对象。比如
/**
* 根据姓名或者年龄查询
* @param username 这个参数提供姓名
* @param age 这个参数提供年龄
* @return
*/
List<Father> selectByNameOrAge(Father username,Father age);
对应的xml
<select id="selectByNameOrAge" resultMap="BaseResultMap">
select *
from father
where username = #{username}
or age = #{age}
</select>
这是个错误的示范,因为mybatis被你搞晕了,我这是去哪个对象的username和age呢?所以这时候你得告诉mybatis,那么@Param注解的作用就来了。改造后的代码
/**
* 根据姓名或者年龄查询
* @param username 这个参数提供姓名
* @param age 这个参数提供年龄
* 注解中的参数名称随便起,但是在当前方法内不允许重复
* @return
*/
List<Father> selectByNameOrAge(@Param("p1") Father username,@Param("p2") Father age);
<select id="selectByNameOrAge" resultMap="BaseResultMap">
select *
from father
where username = #{p1.username}
or age = #{p2.age}
</select>
就是这么简单,我们测试一下
Father username = new Father();
username.setUsername("张飞");
Father age = new Father();
age.setAge(25);
List<Father> fathers = this.fatherMapper.selectByNameOrAge(username, age);
for (Father father : fathers) {
System.out.println("father = " + father);
}
建议在每个mapper方法中都使用这个注解
mybatis分页查询
关于分页查询呢,mybatis自身提供了一个组件,但是那个很少用,也麻烦。mybatis作为一个强大的持久层框架呢,提供了一个很牛逼的扩展点,插件机制。这个插件机制确实牛逼,他可以干很多事情。这个插件本质上就是拦截器,可以在sql执行之前进行拦截,也可以在sql执行之后进行拦截。如果开发者能够熟练使用插件。那么对你开发而言将事半功倍。好,我们先来使用这个分页插件。首先引入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.5.1</version>
</dependency>
然后在mybatis的xml配置文件中配置插件和相关参数
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!-- 配置哪种数据库的分页,因为很多数据库的分页写法不一样
所以得告诉插件我现在用的是什么数据库
可选的值有 mysql,mariadb,sqlite,oracle,hsqldb,postgresql
全部小写
-->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
在mapper接口中写个分页查询
/**
* 分页查询,这个page本质就是list,但是里面有分页参数
* @return
*/
Page<Father> selectPage();
贴下page的源码
本质上就是list,但是他里面有分页的参数,比如第几页,当前页的个数。
对应xml查询语句,也很简单
<select id="selectPage" resultType="com.bky.entity.Father">
select * from father
</select>
然后在我们进行查询之前,调用这个插件的api。
/**
* 第一个参数是第几页,这里我从第一页开始查询
* 第二个参数就是每页查询几条
*/
PageHelper.startPage(2,3);
Page<Father> fathers = this.fatherMapper.selectPage();
for (Father father : fathers) {
System.out.println("father = " + father);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构