二、Spring集成PageHeper
我们先来看一下没有集成之前的代码是怎么样的?
BookMapper.xml
<select id="listpager" resultType="com.csdn.xw.model.Book" parameterType="com.csdn.xw.model.Book" > select <include refid="Base_Column_List" /> from t_mvc_book <if test=" bname!=null"> where bname like concat('%',#{bname},'%') </if> </select>
BookMapper
List<Book> listpager(Book book);
BookBiz
List<Book> listpager(Book book, PageBean pageBean);
BookBizImpl
@Override public List<Book> listpager(Book book, PageBean pageBean) { if(pageBean!=null&&pageBean.isPagination()) PageHelper.startPage(pageBean.getPage(),pageBean.getRows()); List<Book> listpager = bookMapper.listpager(book); if(pageBean!=null&&pageBean.isPagination()){ PageInfo<Book> 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面向切面技术做处理。
2.1.面向切面解决冗余代码
编写一个切面类专门来做分页
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方法 * 只要同时匹配上诉四个条件,就会被列为目标对象 * 上诉配置要生效,代理注释一定要打开:<aop:aspectj-autoproxy/> * @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所写的分页代码试试,看这个切面类会不会捕捉到我们的方法。
测试结果:
结果也出来了,说明我们的捕捉成功了。
三、总结
3.1.注解解释
@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进行管理。
到这里我的分享就结束了,欢迎到评论区探讨交流!!
如果觉得有用的话还请点个赞吧 ♥ ♥