spring+springmvc+mybatis 之前台高级条件分页查询 及 问题解决

本文介绍在MyBatis框架下如何配置分页插件,实现多表查询及高级条件分页查询。详细讲解了配置文件设置、SQL查询技巧、分页插件使用方法以及常见问题解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景:

在项目中负责的模块,数据都是从其他两张表格,需要展示到前台和高级条件查询

一、mybatis配置

配置位置:多模块开发 mapper模块 中applicationContext-mapper.xml

分页必配置分页拦截和 mybatis 的包

在这里插入图片描述

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/tx">


    <!--配置包注解扫描,只扫描service层和mapper层,目的是为了降低资源占用-->
    <context:component-scan base-package="com.rpms.iteam.mapper"/>

    <!--加载配置文件-->
    <context:property-placeholder location="classpath*:jdbc.properties"/>

    <!--配置数据源-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>

    <!--Mybatis核心对象-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据源 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置mybatis (mapper)映射器路径 -->
        <property name="mapperLocations" value="classpath*:com/rpms/iteam/mapper/*Mapper.xml"/>
        <!-- 配置mybatis 类型别名 -->
        <property name="typeAliasesPackage">
            <value>
                com.rpms.iteam.domain
                com.rpms.iteam.query
            </value>
        </property>
        ***<!--分页拦截器-->
        <property name="plugins">
            <array>
            <bean class="com.github.pagehelper.PageInterceptor">
              <property name="properties">
            <value>helperDialect=mysql</value>
        </property>
    </bean>
            </array>
        </property>***

</bean>
    <!--注入映射器,一劳永逸的做法-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.rpms.iteam.mapper"/>
    </bean>

    <!--我们需要配置一个事务管理器
       以前学习JPA ,是有一个类JpaTransactionManager的事务对象
       mybatis用的是:DataSourceTransactionManager
   -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置标签支持事务-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

    <import resource="classpath*:applicationContext-core.xml"/>
</beans>

二、查询的sql

在不使用mybatis 关联映射 查询的条件下,使用普通的spl 多表关联查询一张中间的临时表 ,这张表命名 commonVo .java, 表示查询出来的数据 ,展示到前台

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。

在使用left jion时,on和where条件的区别如下:

1、 on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。

2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

三、使用查询结果,展示到前台,并且做高级条件分页查询

1、方法:

两个查询方法:一个无条件查询所有的, 一个 带有 拼接 的多条件 查询
在 两张表的 中 任意一个的mapper.xml 下 配置 这 两个查询方法
多条件查询 的数据封装在一个 query中

 private String q;//关键字
    private int page = 0;//页数
    private int rows = 10;//每页的条目数

    public String getQ() {
        return q;
    }

    public void setQ(String q) {
        this.q = q;
    }

    public int getPage() {
        return page;
    }

    public void setPage(int page) {
        this.page = page;
    }

    public int getRows() {
        return rows;
    }

    public void setRows(int rows) {
        this.rows = rows;
    }

2、公共的pageList 用于返回页面分页数据

 private long total; //总条数

    private List<T> rows; //这一行的数据

    public Pagination(Page<T> page) {
        this.total = page.getTotal();
        this.rows = page.getResult();
    }

    public long getTotal() {
        return total;
    }

    public void setTotal(long total) {
        this.total = total;
    }

    public List<T> getRows() {
        return rows;
    }

    public void setRows(List<T> rows) {
        this.rows = rows;
    }

3、mapper , IserviceImpl 中方法的处理

mapper :
// 基本的分页条件 查所有的数据
pageList selectAll(BaseQuery query);
// 多条件查询 ,返回page 时插件里 分页对象
Page selectByQuery (CommonQuery query);

IserviceImpl :

 @Override
    public  Pagination<SettedVo>selectAll(SettedQuery query) {

       //配置分页的值
       //分页插件工具  (对后面的一个查询方法结果分页)  ,把符合条件的先查出来,封装到页面分页数据中   ,最后由selectAll  分页
       PageHelper.startPage(query.getPage(),query.getRows());
       Page<CommonVo> page =commonMapper. selectByQuery(query);
          return   new pageList<CommonVo>(page);

    }

4、使用分页插件的注意事项:

只有紧跟在 PageHelper.startPage 方法后的第一个 MyBatis 的查询(select)方法会被分页。
请不要在系统中配置多个分页插件(使用 spring 时,mybatis-config.xml 和 Spring 配置方式,请选择其中一种,不要同时配置多个分页插件)。
对于带有 for update 的 sql,会抛出运行时异常,对于这样的 sql 建议手动分页,毕竟这样的 sql 需要重视。
由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。

四、过程中的问题

1、类型不匹配

java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.github.pagehelper.Page

在使用分页插件时,方法使用错误,如果只用一种查询方法,会提示强转成page 类,
其实强转并不起作用,只是解决不报错,运行时就会出上面的问题

解决办法 :用上述方式封装

2、启动Tomcat失败

Connected to server
[2019-04-14 10:15:25,726] Artifact rpms-web:war exploded: Artifact is being deployed, please wait…
14-Apr-2019 10:15:28.148 严重 [RMI TCP Connection(3)-127.0.0.1] org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:
org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]

解决:
(1)重新部署项目,可以消除这个错误;

(2)clean一下项目,重新启动服务器

3、项目中类的丢失

在父模块下 ,重新 编译全部(点击compile ) ,或者删除子模块的编译文件夹 target
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值