Mybatis-plus SQL性能优化(分页数据获取)

举报
真爱无敌 发表于 2020/03/20 09:07:42 2020/03/20
【摘要】 相信大部分人都会遇到:在数据库的数据量很大时,分页需要几秒钟才会全部完成;包括分页list的获取和count的获取。那我们完全可以将这两步放到一次sql去执行获取,减少一半的查询时间。这里get到sql_calc_found_rows和SELECT FOUND_ROWS()这两个知识点。看代码:select SQL_CALC_FOUND_ROWS col_name1 as colNam...


image.png

相信大部分人都会遇到:在数据库的数据量很大时,分页需要几秒钟才会全部完成;包括分页list的获取和count的获取。

那我们完全可以将这两步放到一次sql去执行获取,减少一半的查询时间。

这里get到sql_calc_found_rows和SELECT FOUND_ROWS()这两个知识点。

看代码:

select SQL_CALC_FOUND_ROWS

    col_name1 as colName1,

    col_name2 as colName2

from table_name limit 0,10;

select FOUND_ROWS() as count;

在SELECT语句中加上修饰SQL_CALC_FOUND_ROWS 之后,SELECT FOUND_ROWS() 会返回满足条件记录的总数。

这样,你执行完 select SQL_CALC_FOUND_ROWS 之后,再取一下记录总数就行了。

现在,你会获取到如下数据:

image.png

image.png

 看到没有,两个结果:第一个是分页list,第二个是总数count。接下来怎么办?


接下来我们就将相关代码放到JAVA中,可是我们会发现:在数据库中能够成功执行语句,但是放到代码中却会报错。


原来,mybatis在我们使用链接连接数据库时,需要我们手动在连接上加上代码:

&allowMultiQueries=true   //允许执行多条sql

写全就是:spring.datasource.url=jdbc:mysql://localhost/atage?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true

这样,mybatis就可以成功通过多条sql语句get到多个数据集了。


那么现在问题来了:

我们在xml中如何去接收sql查询到的多数据集呢?


废话不多说,直接上代码:


1.xml代码:

<!-- 获取学生列表数据-分页-+count数据 -->
<select id="getStudentManagePage" resultMap="StudentManageVoMap,count">
   SELECT sql_calc_found_rows 这里是字段 FROM
        tbl_student_infomation AS tsi
        LEFT JOIN tbl_college AS tco ON tsi.college_id=tco.id
        LEFT JOIN tbl_profession AS tp ON tsi.profession_id=tp.id
        LEFT JOIN tbl_class AS tcl ON tsi.class_id=tcl.id
        WHERE 1=1
        ORDER BY tcs.score DESC,tsi.is_track DESC,tsi.sno DESC limit #{offset},#{limit};
   SELECT found_rows() as count;
</select>
<!--接收count数据集-->
<resultMap type="Integer" id="count">
    <result column="count" jdbcType="INTEGER" javaType="Integer" />
</resultMap>
<!--接收分页数据集-->
<resultMap type="com.atage.entity.vo.StudentManageVo" id="StudentManageVoMap">
        <result column="sno" jdbcType="VARCHAR" property="sno" />
        <result column="name" jdbcType="VARCHAR" property="name" />
        <result column="sex" jdbcType="INTEGER" property="sex" />
        <result column="imgUrl" jdbcType="VARCHAR" property="imgUrl" />
        <result column="brithday" jdbcType="DATE" property="brithday" />
        <result column="sourcePlace" jdbcType="VARCHAR" property="sourcePlace" />
        <result column="singleton" jdbcType="INTEGER" property="singleton" />
        <result column="parentFamily" jdbcType="INTEGER" property="parentFamily" />
        <result column="enrollment" jdbcType="VARCHAR" property="enrollment" />
        <result column="collegeId" jdbcType="VARCHAR" property="collegeId" />
        <result column="professionId" jdbcType="VARCHAR" property="professionId" />
        <result column="classId" jdbcType="VARCHAR" property="classId" />
        <result column="isTrack" jdbcType="INTEGER" property="isTrack" />
        <result column="score" jdbcType="DOUBLE" property="score" />
        <result column="gradeC" jdbcType="DOUBLE" property="gradeC" />
        <result column="gradeQ" jdbcType="DOUBLE" property="gradeQ" />
        <result column="gradeId" jdbcType="VARCHAR" property="gradeId" />
        <result column="clollegeName" jdbcType="VARCHAR" property="clollegeName" />
        <result column="yearName" jdbcType="VARCHAR" property="yearName" />
        <result column="professionName" jdbcType="VARCHAR" property="professionName" />
        <result column="className" jdbcType="VARCHAR" property="className" />
        <result column="teacherId" jdbcType="VARCHAR" property="teacherId" />
    </resultMap>


2.Mapper代码

//接收用list<?>
List<?> getStudentManagePage(这里是传递的条件参数);


3.service代码

//接收用list<?>
List<?> getStudentManagePage(这里是传递的条件参数);


4.serviceImpl代码

@Override
    public List<?> getStudentManagePage(参数) {
        return tblStudentInfomationMapper.getStudentManagePage(参数);
    }


5.controller代码

//这里是接收数据
List<?> list = tblStudentInfomationService.getStudentManagePage(参数);
List<StudentManageVo> studentManageVoList = new ArrayList<StudentManageVo>();
//接收分页数据
studentManageVoList = (List<StudentManageVo>)list.get(0);
//接收count数据
count = ((List<Integer>) list.get(1)).get(0);


好,按照以上配置,你就会发现SQL执行效率就大大提高了。



☆重点提示


强调下必须修改数据库连接 

1、修改数据库连接参数加上allowMultiQueries=true,如: 

hikariConfig.security.jdbcUrl=jdbc:mysql://xx.xx.xx:3306/xxxxx?characterEncoding=utf-8&autoReconnect=true&failOverReadOnly=false&allowMultiQueries=true



2、直接写多条语句,用“;”隔开即可

<delete id="deleteUserById" parameterType="String">
delete from sec_user_role where userId=#{id};
delete from sec_user where id=#{id};
</delete>



【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。