1. 程式人生 > >springboot2.0 使用aop實現PageHelper分頁

springboot2.0 使用aop實現PageHelper分頁

Java版本: jdk1.8
執行環境: Mac OS
IDE: IDEA

一 知識儲備

1. PageHelper

PageHelper是Mybatis的一款分頁外掛,利用ThreadLocal實現分頁功能。PageHelper先是根據你即將發出的SQL命令獲取count值(也就是資料總量),然後獲取當前執行緒上的執行緒變數進行分頁操作。

2. AOP

AOP稱為面向切面程式設計,在程式開發中主要用來解決一些系統層面上的問題,比如日誌,事務,許可權等待…。
一 AOP的基本概念

  1. Aspect(切面):通常是一個類,裡面可以定義切入點和通知
  2. JointPoint(連線點):程式執行過程中明確的點,一般是方法的呼叫
  3. Advice(通知):AOP在特定的切入點上執行的增強處理,有before,after,afterReturning,afterThrowing,around

二 程式碼思路

  1. 為什麼要使用AOP技術來進行PageHelper分頁,先來看一個普通的PageHelper分頁方法
	/**
     * @param page 當前頁
     * @param pageSize 每頁數量
     * @return
     */
    public PageInfo<User> findUserListWithPage(int page,int
pageSize){ //pageHelper幫助生成分頁語句 //底層實現 採用改寫語句 PageHelper.startPage(page,pageSize); List<User> userList = userMapper.findUserList(); PageInfo<User> userListPageInfo = new PageInfo<>(users); return userListPageInfo; }

不難發現 PageHelper常用的分頁方法邏輯程式碼就是

1. 用PageHelper設定 從第n頁開始查,每頁x條資料
2. 執行Dao(Mapper)層方法
3. 將查詢結果用PageInfo類包裝返回

當方法較少的時候不會有太多的感覺,但如果要寫好幾百個方法分頁查詢的方法,每個方法的程式碼都按照這個邏輯來來寫,就會顯得程式碼冗餘。
在這個執行邏輯中可以看出 只要給了pagepageSize引數,第1步和第3步是不變的,會變的只是第2步。於是乎就有了使用AOP技術來將第1步和第3步抽出來,減少程式碼量。

三 技術實現

已知model層


public class User {

    private Integer id;

    private String name;

    private Integer age;
}

Dao(Mapper)層


public interface UserMapper {

    @Select("select * from user")
    List<User> findUserList();

}

Service層的寫法是關鍵,根據是否使用AOP技術有不同的實現.

Controller層


@RestController
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/findUserList")
    public Object findUserList(int page, int pageSize){
        return userService.findUserList();

    }
}


在不使用aop時進行pageHelper分頁操作時,Service層程式碼如下

@Service
public class UserService {

    @Autowired
    UserMapper userMapper;
    
    /**
     * @param page 當前頁
     * @param pageSize 每頁數量
     * @return
     */
    public PageInfo<User> findUserListWithPage(int page,int pageSize){
        //pageHelper幫助生成分頁語句
        //底層實現 採用改寫語句
        PageHelper.startPage(page,pageSize);
        List<User> userList = userMapper.findUserList();
        PageInfo<User> userListPageInfo = new PageInfo<>(users);
        return userListPageInfo;
    }
}


使用aop技術進行pageHelper分頁操作時,Service層程式碼如下

@Service
@Slf4j
public class UserService {

    @Autowired
    UserMapper userMapper;

    /**
     *
     * @param page 當前頁
     * @param pageSize 每頁數量
     * @return
     */
    public Object findUserListWithPage(int page ,int pageSize){

        List<User> userList = userMapper.findUserList();
        return userList;
    }
}


AOP層 PageHelperAspect程式碼

/**
 * @author hyl
 * @date 18/12/18 下午10:38
 */
@Aspect
@Component
@Slf4j
public class PageHelperAspect {

    @Pointcut("execution(public * com.bootbase.service.*.*WithPage(..))")
    public void serviceFindFunction(){}
    /**
     * 使用around方法 在執行查詢方法前執行PageHelper.startWith
     * 在執行查詢方法後 將結果封裝到PageInfo中
     * @param proceedingJoinPoint
     * @return
     * @throws Throwable
     */
    @Around("serviceFindFunction()")
    public Object serviceImplAop(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        log.info("進入PageHelper AOP");

        //獲取連線點方法執行時的入參列表
        Object[] args = proceedingJoinPoint.getArgs();

        //獲取連線點的方法簽名物件
        Signature signature = proceedingJoinPoint.getSignature();
        
        //獲取連線點所在的類的物件(例項)
        Object target = proceedingJoinPoint.getTarget(); 
        
        PageHelper.startPage(Integer.parseInt(args[0].toString()),Integer.parseInt(args[1].toString()));

        log.info("方法[{}]開始執行...",signature.getName());
        Object object = proceedingJoinPoint.proceed();
        log.info("方法[{}]執行結束.",signature.getName());

        if(object instanceof List) {
            List objList = (List) object;
            PageInfo pageInfo = new PageInfo<>(objList);
            return pageInfo;
        }
        return object;

    }

}

四 結語

以上就是使用AOP進行PageHelper分頁的全部內容.其內容本身與springboot2.0無充分必要關係,只不過在springboot2.0中 可以省略AOP配置檔案的編寫 (說白了就是懶