Mybatis分页和Spring的集成,强大简单易上手

来源:互联网 发布:神代利世cos淘宝 编辑:程序博客网 时间:2024/06/05 03:30

1.在Maven中加入依赖:

<dependencies>  ...    <dependency>        <groupId>com.github.miemiedev</groupId>        <artifactId>mybatis-paginator</artifactId>        <version>1.2.17</version>    </dependency> ...</dependencies>

2.Mybatis配置文件(mybatis-config.xml)添加分页插件:

<configuration>    <plugins>        <plugin interceptor="com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor">            <property name="dialectClass" value="com.github.miemiedev.mybatis.paginator.dialect.OracleDialect"/>        </plugin>    </plugins></configuration>
3.Dao层方法:

public interface ProductDao {    PageList<Product> getList(Map params, PageBounds pageBounds);}
Service层方法:

@Servicepublic class ProductService implements ProductDao {    @Autowired    private ProductDao productDao;    @Override    public PageList<Product> getList(Map params, PageBounds pageBounds) {        return productDao.getList(params,pageBounds);    }}
Mapper文件:

<select id="getList" parameterType="Map" resultMap="getProductListMap">        SELECT            A.prod_id,            A.prod_name,            A.prod_price,            B.vend_id,            B.vend_name,            B.vend_address,            B.vend_city        FROM            products A        LEFT JOIN vendors B ON A.vend_id = B.vend_id        <where>            <if test="vendId!=null and vendId!=''">                and A.vend_id like concat('%',#{vendId},'%')            </if>        </where>    </select>

调用查询:

public class PageTest {    private ApplicationContext applicationContext;    @Before    public void setUp() throws Exception {        applicationContext = new FileSystemXmlApplicationContext("classpath:spring/applicationContext.xml");    }    @Test    public void test(){        ProductDao productDao = (ProductDao) applicationContext.getBean("productService");        Map<String,Object> params = new HashMap<>();        params.put("vendId",0);//map传参,与分页插件无关        int page = 2;//分页插件页数,第几页        int pageSize = 5;//分页插件一页显示的条数        String sortString = "vend_city.desc,prod_price.asc";//分页插件中的排序Order.formString(sortString)        PageBounds pageBounds = new PageBounds(page,pageSize, Order.formString(sortString));//构造分页插件传参对象        PageList<Product> products = productDao.getList(params,pageBounds);        System.out.println(products.getPaginator().getTotalCount());//得到总条数        System.out.println(products.getPaginator().getTotalPages());//得到总页数        System.out.println("-------------------------------------------------------");        for(Product product:products){            System.out.println(product);        }    }}

调用方式详解:

PageList类是继承于ArrayList

使用PageBounds这个对象来控制结果的输出,常用的使用方式一般都可以通过构造函数来配置。

new PageBounds();//默认构造函数不提供分页,返回ArrayListnew PageBounds(int limit);//取TOPN操作,返回ArrayListnew PageBounds(Order... order);//只排序不分页,返回ArrayListnew PageBounds(int page, int limit);//默认分页,返回PageListnew PageBounds(int page, int limit, Order... order);//分页加排序,返回PageListnew PageBounds(int page, int limit, List<Order> orders, boolean containsTotalCount);//使用containsTotalCount来决定查不查询totalCount,即返回ArrayList还是PageList

如果用如下方法设置pageBounds,当前这个查询就可以用两个线程同时查询list和totalCount

pageBounds.setAsyncTotalCount(true);

如果所有的分页查询都是用异步的方式查询list和totalCount,可以在插件配置加入asyncTotalCount属性

<plugin interceptor="com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor">    <property name="dialectClass" value="com.github.miemiedev.mybatis.paginator.dialect.OracleDialect"/>    <property name="asyncTotalCount" value="true"/></plugin>

但是你仍然可以用下面代码强制让这个查询不用异步

pageBounds.setAsyncTotalCount(false);


当然需要注意的是,只要你用到了异步查询,由于里面使用了线程池,所以在使用时就要加入清理监听器,以便在停止服务时关闭线程池。需要在web.xml中加入

<listener>    <listener-class>com.github.miemiedev.mybatis.paginator.CleanupMybatisPaginatorListener</listener-class></listener>




【以上即可完成开发中的所有分页需求 】

其他配置:

如果用的是SpringMVC的话可以把JSON的配置写成这样:

<mvc:annotation-driven>    <mvc:message-converters register-defaults="true">        <bean class="org.springframework.http.converter.StringHttpMessageConverter">             <constructor-arg value="UTF-8" />                </bean>        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">            <property name="objectMapper">                <bean class="com.github.miemiedev.mybatis.paginator.jackson2.PageListJsonMapper" />            </property>        </bean>    </mvc:message-converters></mvc:annotation-driven>

那么在Controller就可以这样用了:

@ResponseBody@RequestMapping(value = "/findByCity.json")public List findByCity(@RequestParam String city,                 @RequestParam(required = false,defaultValue = "1") int page,                 @RequestParam(required = false,defaultValue = "30") int limit,                 @RequestParam(required = false) String sort,                 @RequestParam(required = false) String dir) {    return userService.findByCity(city, new PageBounds(page, limit, Order.create(sort,dir)));}

然后序列化后的JSON字符串就会变成这样的:

{    "items":[        {"NAME":"xiaoma","AGE":30,"GENDER":1,"ID":3,"CITY":"BeiJing"},        {"NAME":"xiaoli","AGE":30,"SCORE":85,"GENDER":1,"ID":1,"CITY":"BeiJing"},        {"NAME":"xiaowang","AGE":30,"SCORE":92,"GENDER":0,"ID":2,"CITY":"BeiJing"},        {"NAME":"xiaoshao","AGE":30,"SCORE":99,"GENDER":0,"ID":4,"CITY":"BeiJing"}    ],    "slider": [1, 2, 3, 4, 5, 6, 7],    "hasPrePage": false,    "startRow": 1,    "offset": 0,    "lastPage": false,    "prePage": 1,    "hasNextPage": true,    "nextPage": 2,    "endRow": 30,    "totalCount": 40351,    "firstPage": true,    "totalPages": 1346,    "limit": 30,    "page": 1}

在SpringMVC中使用JSTL的话可以参考一下步骤(懒人用法)

在Spring配置文件中加入拦截器,或则参考拦截器实现定义自己的拦截器

<mvc:interceptors>    <mvc:interceptor>        <mvc:mapping path="/**" />        <bean class="com.github.miemiedev.mybatis.paginator.springmvc.PageListAttrHandlerInterceptor" />    </mvc:interceptor></mvc:interceptors>
然后Controller方法可以这样写

@RequestMapping(value = "/userView.action")public ModelAndView userView(@RequestParam String city,                 @RequestParam(required = false,defaultValue = "1") int page,                 @RequestParam(required = false,defaultValue = "30") int limit,                 @RequestParam(required = false) String sort,                 @RequestParam(required = false) String dir) {    List users = userService.findByCity(city, new PageBounds(page, limit, Order.create(sort,dir)));    return new ModelAndView("account/user","users", users);}
JSP中就可以这样用了,拦截器会将PageList分拆添加Paginator属性,默认命名规则为"原属性名称"+"Paginator"

<table>    <c:forEach items="${users}" var="user">        <tr>            <td>${user['ID']}</td>            <td>${user['NAME']}</td>            <td>${user['AGE']}</td>        </tr>    </c:forEach></table>上一页: ${usersPaginator.prePage} 当前页: ${usersPaginator.page} 下一页: ${usersPaginator.nextPage} 总页数: ${usersPaginator.totalPages} 总条数: ${usersPaginator.totalCount} 更多属性参考Paginator类提供的方法

【end】



原创粉丝点击