目录
引言
一、Spring集成MyBatis
1.1.pom依赖
1.2.配置文件
1.3.Spring整合MyBatis
1.3.1.配置自动扫描JavaBean
1.3.2.配置数据源
1.3.3.配置session工厂
1.3.4.配置mapper扫描接口
1.3.5.配置事物管理器
1.3.6.配置AOP自动代理
1.4.测试
二、Spring集成PageHeper
2.1.面向切面解决冗余代码
三、总结
3.1.注解解释
在Web应用程序开发中,数据持久化和分页查询是两个非常重要的环节。MyBatis是一个优秀的持久化框架,而PageHelper则是Spring平台上一个轻量级的分页插件。然而,在实际的开发过程中,我们经常需要将这两个框架进行整合,以实现更高效的开发效率。本文将详细介绍如何将Spring与MyBatis集成,以及如何将PageHelper集成到Spring项目中,从而帮助我们更好地应对实际开发中的挑战。
UTF-8
1.8
1.8
3.7.0
5.0.2.RELEASE
3.4.5
5.1.44
5.1.2
1.3.1
2.1.1
2.4.3
2.9.1
4.12
4.0.0
1.18.2
org.springframework
spring-context
${spring.version}
org.springframework
spring-orm
${spring.version}
org.springframework
spring-tx
${spring.version}
org.springframework
spring-aspects
${spring.version}
org.springframework
spring-web
${spring.version}
org.springframework
spring-test
${spring.version}
org.mybatis
mybatis
${mybatis.version}
mysql
mysql-connector-java
${mysql.version}
com.github.pagehelper
pagehelper
${pagehelper.version}
org.mybatis
mybatis-spring
${mybatis.spring.version}
org.apache.commons
commons-dbcp2
${commons.dbcp2.version}
org.apache.commons
commons-pool2
${commons.pool2.version}
org.apache.logging.log4j
log4j-core
${log4j2.version}
org.apache.logging.log4j
log4j-api
${log4j2.version}
org.apache.logging.log4j
log4j-web
${log4j2.version}
junit
junit
${junit.version}
test
javax.servlet
javax.servlet-api
${servlet.version}
provided
org.projectlombok
lombok
${lombok.version}
provided
src/main/java
**/*.xml
src/main/resources
jdbc.properties
*.xml
org.apache.maven.plugins
maven-compiler-plugin
${maven.compiler.plugin.version}
${maven.compiler.target}
${project.build.sourceEncoding}
org.mybatis.generator
mybatis-generator-maven-plugin
1.3.2
mysql
mysql-connector-java
${mysql.version}
true
①将
②
可以确保mybatis-generator-maven-plugin在运行时能够正确地将所需的文件复制到目标文件夹中,避免出现缺少文件或配置错误的问题。
③Maven插件的配置,用于使用MyBatis Generator插件
小贴士:
dbcp2连接池介绍
连接池的主要作用是减少数据库连接的创建和销毁次数,从而提高应用程序的性能。除此之外,连接池还有以下优点:1、简化的编程模式在使用连接池的时候,每一个单独的线程能够像创建了一个自己的 JDBC 连接一样操作,允许用户直接使用JDBC编程技术;2、受控的资源使用如果用户不使用连接池,而是每当线程需要时创建一个新的连接,那么用户的应用程序的资源使用会产生非常大的浪费并且可能会导致高负载下的异常发生;3、减少连接创建时间 。
除了dbcp2以外还有druid、c3p0都是连接池。
lombok介绍
Lombok是一个Java库,能自动插入编辑器并构建工具,简化Java开发。通过添加注解的方式,不需要为类编写getter或eques方法,同时可以自动化日志变量 。Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率 。
将我们的配置文件加入到项目中。
generatorConfig.xml
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://47.100.191.44:3308/mybatis_ssm?useUnicode=true&characterEncoding=UTF-8
jdbc.username=123
jdbc.password=123
log4j2.xml
/root/workspace/lucenedemo/logs
/root/workspace/lucenedemo/logs/error
/root/workspace/lucenedemo/logs/warn
%d{yyyy-MM-dd HH:mm:ss.SSS} [%t-%L] %-5level %logger{36} - %msg%n
在该目录下继续新建两个xml文件spring-context.xml、spring-mybatis.xml,因为我们的spring-context.xml才是核心文件所以要将spring-mybatis.xml导入到核心文件中。
spring-context.xml
在没有整合Spring框架的时候,我们所编写的是Mybatis.cfg.xml配置文件,而Spring整合MyBatis后,Mybatis.cfg.xml等同于spring-mybatis.xml,可以直接使用Spring的配置文件来配置MyBatis 。下面我来带领大家一起整合!!
spring-mybatis.xml
helperDialect=mysql
将代码中的路径改成自己的即可。
在MyBatis生产的Mapper类上加上@Repository注解,相当有在spring里面做
bookbizimpl加上@Service注解,属性BookMapper加上@Autowired注解
BookBizImplTest测试类也是如此,并将bookbiz也加上 @Autowired注解
前面我们提到过lombok依赖现在我们就来实操演示一下
Book.java
package com.csdn.xw.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//set/get/tostring方法
@Data
//有参构造器
@AllArgsConstructor
//空参构造器
@NoArgsConstructor
public class Book {
private Integer bid;
private String bname;
private Float price;
}
现在调用一下查询的方法查看结果
@Test
public void selectByPrimaryKey() {
System.out.println(this.bookbiz.selectByPrimaryKeyws(55));
}
到这里看到结果就说明我们已经将Spring与MyBatis进行整合了。
我们先来看一下没有集成之前的代码是怎么样的?
BookMapper.xml
BookMapper
List listpager(Book book);
BookBiz
List listpager(Book book, PageBean pageBean);
BookBizImpl
@Override
public List listpager(Book book, PageBean pageBean) {
if(pageBean!=null&&pageBean.isPagination())
PageHelper.startPage(pageBean.getPage(),pageBean.getRows());
List listpager = bookMapper.listpager(book);
if(pageBean!=null&&pageBean.isPagination()){
PageInfo pageInfo = new PageInfo<>(listpager);
pageBean.setTotal((int) pageInfo.getTotal());
}
return listpager;
}
如果PageBean不为空并且isPagination为true说明要分页,那么就是用PageHeper插件
BookBizImplTest
@Test
public void listpager() {
Book book=new Book();
PageBean pageBean=new PageBean();
pageBean.setPage(2);
pageBean.setRows(5);
book.setBname("斗破");
this.bookbiz.listpager(book,pageBean).forEach(System.out::println);
}
这样的代码复用性不是很高而且耦合性比较高,在我们在我们开发过程中是非常不友好的,那么怎么将分页的代码进行优化呢?我们可以用到Spring里面的aop面向切面技术做处理。
编写一个切面类专门来做分页
PageAspect
package com.csdn.xw.aspect;
import com.csdn.xw.util.PageBean;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author Java方文山
* @compay csdn_Java方文山
* @create 2023-08-25-20:33
*/
@Aspect
//代表当前类是切面类
@Component
//代表这个是交给Spring管理
public class PageAspect {
/**
* *:返回值
* *..:无限包
* *Biz:以Biz结尾的接口名
* .pager:以pager方法
* 只要同时匹配上诉四个条件,就会被列为目标对象
* 上诉配置要生效,代理注释一定要打开:
* @param args
* @return
* @throws Throwable
*/
@Around("execution(* *..*Biz.*pager(..))")
public Object invoke(ProceedingJoinPoint args) throws Throwable {
Object[] params = args.getArgs();
PageBean pageBean = null;
for (Object param : params) {
if(param instanceof PageBean){
pageBean = (PageBean)param;
break;
}
}
if(pageBean != null && pageBean.isPagination())
PageHelper.startPage(pageBean.getPage(),pageBean.getRows());
Object list = args.proceed(params);
if(null != pageBean && pageBean.isPagination()){
PageInfo pageInfo = new PageInfo((List) list);
pageBean.setTotal(pageInfo.getTotal()+"");
}
return list;
}
}
小贴士:
这段代码是一个使用AOP(面向切面编程)的示例,它的作用是在执行方法之前和之后添加一些额外的逻辑。具体来说,这段代码定义了一个切面,用于拦截所有使用了`Biz.pager()`方法的方法。
1. @Around("execution(* *..*Biz.*pager(..))")`:这是一个注解,表示这个切面将会拦截所有使用了`Biz.pager()`方法的方法。
2. `public Object invoke(ProceedingJoinPoint args) throws Throwable`:这是切面的核心方法,它会在被拦截的方法执行前后执行。`ProceedingJoinPoint`参数包含了被拦截方法的信息,如方法名、参数等。
3. `Object[] params = args.getArgs();`:从`ProceedingJoinPoint`参数中获取被拦截方法的参数。
4. `PageBean pageBean = null;`:声明一个`PageBean`类型的变量`pageBean`,用于存储`Biz.pager()`方法的返回值。
5. `for (Object param : params) { if(param instanceof PageBean){ pageBean = (PageBean)param; break; } }`:遍历参数数组,找到第一个`PageBean`类型的参数,并将其赋值给`pageBean`。
6. `if(pageBean != null && pageBean.isPagination()) PageHelper.startPage(pageBean.getPage(),pageBean.getRows());`:如果`pageBean`不为空且`pageBean`的分页属性为`true`,则使用`PageHelper.startPage()`方法设置分页信息。
7. `Object list = args.proceed(params);`:调用被拦截方法,并将结果赋值给`list`。
8. `if(null != pageBean && pageBean.isPagination()){ PageInfo pageInfo = new PageInfo((List) list); pageBean.setTotal(pageInfo.getTotal()+""); }`:如果`pageBean`不为空且分页属性为`true`,则将分页信息设置到`pageBean`中。
9. `return list;`:返回被拦截方法的结果。
下面我注释掉我们刚刚在Impl所写的分页代码试试,看这个切面类会不会捕捉到我们的方法。
测试结果:
结果也出来了,说明我们的捕捉成功了。
@Data
: 这个注解是Lombok库提供的,它可以自动为类生成常用的方法,如getter、setter、equals、hashCode等,从而简化了代码编写过程。
@AllArgsConstructor
: 这个注解是Lombok库提供的,它会自动生成一个包含所有成员变量的构造函数,方便创建对象时初始化所有字段。
@NoArgsConstructor
: 这个注解也是Lombok库提供的,它会自动生成一个无参构造函数,方便创建对象时不进行初始化。
@Repository
: 这个注解是Spring框架提供的,用于标记数据访问组件,即DAO(Data Access Object)层的接口。Spring会自动扫描带有该注解的接口,并将其作为Bean进行管理。
@Service
: 这个注解也是Spring框架提供的,与@Repository
类似,用于标记服务层的接口。同样,Spring会自动扫描带有该注解的接口,并将其作为Bean进行管理。
@Autowired
: 这个注解是Spring框架提供的,用于自动注入依赖关系。当使用@Autowired
注解在字段、构造函数或方法上时,Spring会自动将匹配的Bean注入到对应的位置。
@RunWith(SpringJUnit4ClassRunner.class)
: 这个注解是JUnit框架提供的,用于指定测试运行器。@RunWith
注解可以与不同的测试运行器组合使用,这里使用的是SpringJUnit4ClassRunner,它会加载Spring的配置并执行测试。
@ContextConfiguration(locations={"classpath:spring-context.xml"})
: 这个注解是JUnit框架提供的,用于指定测试运行器的上下文配置。通过指定locations
属性,可以告诉测试运行器从指定的文件加载Spring的配置文件。
@Component
: 这个注解是Spring框架提供的,用于标记一个类为Spring的组件。当一个类被标记为@Component
时,Spring会自动扫描并将其作为Bean进行管理。
到这里我的分享就结束了,欢迎到评论区探讨交流!!
如果觉得有用的话还请点个赞吧 ♥ ♥