场景:
在项目中负责的模块,数据都是从其他两张表格,需要展示到前台和高级条件查询
一、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