One annotation can handle pagination. Why is yours so complicated
Even a Java programmer can’t avoid adding, deleting, modifying, and checking, and these days it’s starting to write interfaces to add, deleting, modifying and checking. You can’t avoid doing data pagination at this point.
So writing down these days, I found that even using the PageHelper paging plug-in, to physically page data. Although the PageHelper plugin is simple to use.
But I’m a very lazy programmer, and I don’t want to write more than one line of non-business code. When a function comes down, the incoming business program will have four or five lines, and the non-business code will take up three 1’s in one operation. I am very uncomfortable with this kind of irrelevant business too much code embedded in the function.
One of them is: the code is not clear to read, the code structure is redundant, I particularly like to see is concise, organized and clear.
So they encapsulated a pagination tool based on PageHelper, that is, simple, easy to use.
1, the train of thought
Using the Spring interceptor and AspectJ’s capabilities, methodInterceptor. Java intercepts the Mapper interface and adds a custom pagination annotation @startPage to the method. Pagination with ** pageHelper.startPage ()**, and then continue to execute the method to encapsulate the query results into the Page. Page interception can be implemented without modifying pageHelper operations. This avoids writing redundant code in the business of the service layer.
The pageHelper.start () method has also been pre-executed to avoid misoperations in the business service function. The actual paging method doesn’t work.
Such as:
PageHelper.start(1.10); . cityMapper.selectById(id); . userMaper.selectList(); .Copy the code
In this case usermaper.selectList (); Is data that needs to be paginated, but before that citymapper.selectByID (id) is executed; So citymapper.selectById (ID); To take effect. userMaper.selectList(); Paging does not work.
With this annotation, there is no need to deal with this situation because paging is handled directly on the current Mapper function.
1. Create a New SpringBoot project and make it a starter.
2. Introduction of relevant documents
Encapsulate a paging object:
- 1, Page. Java
public class Page<T> implements IPage<T>
{
private int pageNum = 1;
private int pageSize = 15;
private int pages;
private long total;
private int[] navigatepageNums = new int[] {0};
private List<T> rows = Collections.emptyList();
private boolean START_PAGE_ED = false;
private OrderBy[] orderBys = new OrderBy[0];
// omit set get
}
Copy the code
- OrderBy: Sort query objects
/**
* <br>
*
* @authorHealth forever *@sinceThe 2020-06-16 15:02 * /
public class OrderBy
{
private String[] columns;
private Direction direction;
public OrderBy(OrderBy.Direction direction, String... properties) {
this.columns = properties;
this.direction = direction;
}
// set get
public enum Direction {
ASC,
DESC;
Direction()
{
}
public boolean isAscending(a)
{
return this.equals(ASC);
}
public boolean isDescending(a)
{
return this.equals(DESC); }}}Copy the code
- PageHelperAutoConfiguration. Java SpringBoot automatic configuration, the key to the starter
@Configuration
/ / load SqlSessionFactory
@ConditionalOnBean({SqlSessionFactory.class})
// Allow automatic reading of configuration files
@EnableConfigurationProperties({PageHelperProperties.class})
// Load the configured class
@AutoConfigureAfter({MybatisAutoConfiguration.class})
// Load the custom Config configuration class
@Import(PageHelperConfig.class)
public class PageHelperAutoConfiguration
{
@Autowired
private List<SqlSessionFactory> sqlSessionFactoryList;
/** * Automatic configuration of SpringBoot parameters */
@Autowired
private PageHelperProperties properties;
public PageHelperAutoConfiguration(a)
{}/** * Register Pagehelper interceptor */
@PostConstruct
public void addPageInterceptor(a)
{
PageInterceptor interceptor = new PageInterceptor();
Properties properties = new Properties();
properties.putAll(this.properties.getProperties());
interceptor.setProperties(properties);
Iterator var3 = this.sqlSessionFactoryList.iterator();
while(var3.hasNext()) { SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) var3.next(); sqlSessionFactory.getConfiguration().addInterceptor(interceptor); }}}Copy the code
- PageHelperProperties. Java is read PageHelper plug-in configuration class. The attributes are as follows:
- Pagehelperconfig. Java custom configuration class, mainly to configure Spring’s enhanced class DefaultPointcutAdvisor
/**
* <br>
*
* @authorHealth forever *@sinceThe 2020-11-11 11:19 * /
@Configuration
public class PageHelperConfig
{
/** * expression * intercepts all methods under which package */
private static final String EXECUTION = "execution(* %s.. *. * (..) )";
@Bean
public DefaultPointcutAdvisor defaultPointcutAdvisor2(PageHelperProperties pageHelperProperties) {
/ / the interceptor
PageMethodInterceptor interceptor = new PageMethodInterceptor();
/ / point of tangency
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
String mapperPackage = pageHelperProperties.getMapperPackage();
pointcut.setExpression(String.format(EXECUTION,mapperPackage));
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut,interceptor);
returnadvisor; }}Copy the code
- PageMethodInterceptor. Java key: interceptors
/** * core method */
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable
{
Method method = methodInvocation.getMethod();
StartPage annotation = method.getAnnotation(StartPage.class);
if(annotation ! =null)
{
LOGGER.info("start page mapper"); } Page<? > page = getPage(methodInvocation);if(page ! =null)
{
if(! page.isStartPageEd()) { PageHelper.startPage(page.getPageNum(), page.getPageSize(),PageUtils.filterSql(page.getOrderBy())); Object proceed = methodInvocation.proceed(); page.setRows(proceed);returnproceed; }}return methodInvocation.proceed();
}
Copy the code
- @startPage.java pagination annotations
/**
* <p>
*
* </p>
*
* @authorHealth forever *@sinceThe 2020-11-11 that * / he
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface StartPage
{
}
Copy the code
.
Project set up! Import the project implementation JAR file into another SpringBoot project.
3, use,
Use it in another project.
<dependency>
<groupId>cn.yj.pagehelper</groupId>
<artifactId>annotation-pagehelper</artifactId>
<version>0.01.-SNAPSHOT</version>
</dependency>
Copy the code
1. Pagehelper configuration file
# The following configuration files add a mapper-package attribute, and all other pageHelper configurations keep the original function.
pagehelper:
helper-dialect: mysql
mapper-package: com.ex.das.mapper Package under mapper interface
reasonable: false PageSize >pages = 1; pageSize>pages = 1; pageSize>pages = 1
supportMethodsArguments: false Parameter interface paging is not supported
Copy the code
2. Annotate methods in Citymapper. Java with @startPage
/**
* <br>
*
* @authorHealth forever *@sinceThe 2020-11-11 15:02 * /
public interface CityMapper
{
/ * * * *@paramPage page parameter *@return* /
@StartPage
@Select("select * from city")
List<City> selectPage(IPage<City> page);
/ * * * *@paramPage page parameter *@paramCity Query object *@return* /
@StartPage
List<City> selectList(IPage<City> page,@Param("params") City city);
}
Copy the code
3. Service and Controller
public interface ICityService
{
// Can have a return value
Page<City> getCityPage(Page<City> page);
// There is no return value
void getCitysPage(Page<City> page);
// With query parameters
Page<City> getCitysPage3(Page<City> page,City city);
Page<City> getCitysPage4(Page<City> page,City city);
}
Copy the code
CityServiceImpl.java
@Service
public class CityServiceImpl implements ICityService
{
private final CityMapper cityMapper;
@Autowired
public CityServiceImpl(CityMapper cityMapper)
{
this.cityMapper = cityMapper;
}
/** ** annotation page *@paramPage page parameter *@return* /
@Override
public Page<City> getCityPage(Page<City> page)
{
return page.setRows(cityMapper.selectPage(page));
}
/** * Use annotation pages with no return value, the result has been wrapped in the page *@param page
*/
@Override
public void getCitysPage(Page<City> page)
{
cityMapper.selectPage(page);
}
/** * Do not use middle annotation pages *@paramPage page parameter *@paramCity Query parameter *@return* /
@Override
public Page<City> getCitysPage3(Page<City> page, City city)
{
return page.startPage().setRows(cityMapper.selectList(page, city));
}
/** * use annotation pagination *@paramPage page parameter *@paramCity Query parameter *@return* /
@Override
public Page<City> getCitysPage4(Page<City> page, City city)
{
cityMapper.selectList(page, city);
returnpage; }}Copy the code
SpringController.java
/**
* <br>
*
* @authorHealth forever *@since2020-04-22 09:30 * /
@RestController
public class SpringController extends BaseController<City>
{
@Autowired
ICityService cityService;
@GetMapping("/list")
public R page1(a)
{
return success(cityService.getCityPage(page()));
}
@GetMapping("/list2")
public R page2(a)
{
Page<City> page = page(new OrderBy(OrderBy.Direction.ASC, "id"));
cityService.getCitysPage(page);
return success(page);
}
@GetMapping("/list3")
public R page3(City city)
{
return success(cityService.getCitysPage3(page(new OrderBy(OrderBy.Direction.ASC, "id")), city));
}
@GetMapping("/list4")
public R page4(City city)
{
return success(cityService.getCitysPage4(page(new OrderBy(OrderBy.Direction.ASC, "id")), city)); }}Copy the code
Controller to further separate paging parameters from query parameters. Extracting a common BaseController can also encapsulate the unified return object to the client, which is uniform specification and easy to manage, concise and convenient. Can also put some current user information what….
So basecontroller.java is responsible for getting the paging parameters and encapsulating the paging objects. Including the unified response client object, you don’t have to go to the new object directly from the parent class
public class BaseController<T>
{
//...
protected Page<T> page(a)
{
int pageNumber = getParamsInt("pageNum");
int pageSize = getParamsInt("pageSize");
return new Page<>(pageNumber, pageSize);
}
/ * * * *@paramOrderBy sorts objects *@return* /
protected Page<T> page(OrderBy... orderBy)
{
int pageNumber = getParamsInt("pageNum");
int pageSize = getParamsInt("pageSize");
return new Page<>(pageNumber==0?1:pageNumber, pageSize==0?15:pageSize, orderBy);
}
private HttpServletRequest getRequest(a)
{
RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
return ((ServletRequestAttributes) attributes).getRequest();
}
private int getParamsInt(String name)
{
String parameter = getRequest().getParameter(name);
if (parameter == null || "".equals(parameter.trim()))
{
return 0;
}
returnInteger.valueOf(parameter); }}Copy the code
4. Verify paging results
The project starts access to get data.
- The list interface
Interceptors have been activated.
-
List3 page annotation page with parameters
When you’re done with it, a simple annotation will take care of pagination, mysql pagination. Are you still writing those extra lines of non-business related code ????
Of course, if you don’t use this annotation pagination method, you can also use PageHelper for pagination. The two are not in conflict. Introduce your own set of rules to your project that are tailored to your needs. Nothing is fixed, whatever is right for your project is good.
Because I am lazy, I love to use my brain and my hands to ease the pain of development and write a more suitable component for my personal development. I will remove it for my personal use in the future and do not need to write repeatedly. Direct reference to this set of code, more can improve the efficiency of personal development.
Above generation code can improve a lot of places, interested, can continue to expand the use of learning to use…
If your company asked you to encapsulate the use of a paging plug-in, how would you encapsulate it?
For more information about how to use PageHelper, please visit the official website
Github.com/pagehelper/…