基于spring-jdbc的BaseDao(包含分页)

网上找一下spring jdbc的分页,基本都是一个类型,不知道为啥,都是在Page对象中再进行查询,这样Page对象不就和数据库操作混一起了嘛?看过其他的项目,有的是只在Dao层查出个list(分页结果集),其他的Page属性在action中再封装,我觉得每次都这样,用着不方便,就自己再搞个轮子吧。下面开整。

1、先上Page对象吧

这里有两个构造方法,看需不需要总计录数,如果不需要的话,后面查询会少查一次,更方便,但是以防万一,再给出一个有总记录数的构造方法

package com.mos.base.sql;

import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

/**
 * Package Name: com.mos.base.sql
 * User: grq
 * Date: 2016/3/25
 * Time: 9:08
 * Description:some des here!
 */
public class Page<T> {

    //一页显示的记录数
    private int numPerPage;
    //记录总数
    private int totalRows;
    //总页数
    private int totalPages;
    //当前页码
    private int currentPage;
    //起始行数
    private int startIndex;
    //结束行数
    private int lastIndex;
    //结果集存放List
    private List<T> resultList;

    public Page(int currentPage,int numPerPage,List<T> list){

        //设置每页显示记录数
        setNumPerPage(numPerPage);
        //设置要显示的页数
        setCurrentPage(currentPage);
        //总记录数
//        setTotalRows(list.isEmpty() ? 0 : list.size());
        //计算总页数
        setTotalPages();
        //计算起始行数
        setStartIndex();
        //计算结束行数
        setLastIndex();
        System.out.println("lastIndex="+lastIndex);
        //装入结果集
        setResultList(list);
    }
    public Page(int currentPage,int numPerPage,int totalRows,List<T> list){

        //设置每页显示记录数
        setNumPerPage(numPerPage);
        //设置要显示的页数
        setCurrentPage(currentPage);
        //总记录数
        setTotalRows(totalRows);
        //计算总页数
        setTotalPages();
        //计算起始行数
        setStartIndex();
        //计算结束行数
        setLastIndex();
        System.out.println("lastIndex="+lastIndex);
        //装入结果集
        setResultList(list);
    }

    public int getNumPerPage() {
        return numPerPage;
    }

    public void setNumPerPage(int numPerPage) {
        this.numPerPage = numPerPage;
    }

    public int getTotalRows() {
        return totalRows;
    }

    public void setTotalRows(int totalRows) {
        this.totalRows = totalRows;
    }

    public int getTotalPages() {
        return totalPages;
    }

    public void setTotalPages() {
        if(totalRows % numPerPage == 0){
            this.totalPages = totalRows / numPerPage;
        }else{
            this.totalPages = (totalRows / numPerPage) + 1;
        }
    }

    public int getCurrentPage() {
        return currentPage;
    }

    public void setCurrentPage(int currentPage) {
        this.currentPage = currentPage;
    }

    public int getStartIndex() {
        return startIndex;
    }

    public void setStartIndex() {
        this.startIndex = (currentPage - 1) * numPerPage;
    }

    public int getLastIndex() {
        return lastIndex;
    }

    public void setLastIndex() {
        if( totalRows < numPerPage){
            this.lastIndex = totalRows;
        }else if((totalRows % numPerPage == 0) || (totalRows % numPerPage != 0 && currentPage < totalPages)){
            this.lastIndex = currentPage * numPerPage;
        }else if(totalRows % numPerPage != 0 && currentPage == totalPages){//最后一页
            this.lastIndex = totalRows ;
        }
    }

    public List<T> getResultList() {
        return resultList;
    }

    public void setResultList(List<T> resultList) {
        this.resultList = resultList;
    }
}
2、SQLPageHandle

这个的作用是处理分页的,比如mysql和oracle的不同,分别做一个实现就好了,细心的童鞋可能会发现上一篇的applicationContext.xml中注入了一个sQLPageHandle,其实就是这个,需要同时支持mysql和oracle的时候,用工厂注入就行了。

package com.mos.base.sql;

/**
 * 分页处理接口
 * */
public interface SQLPageHandle {

    /**
     * 将传入的SQL做分页处理
     * 
     * @param String
     *            oldSql 原SQL
     * @param int pageNo 第几页,用来计算first 这个值由(pageNo-1)*pageSize
     * @param int pageSize 每页数量
     * */
    public String handlerPagingSQL(String oldSql, int pageNo, int pageSize);

}
3、MysqlSQLPageHandleImpl

其实就是对sql进行重新拼接处理。

package com.mos.base.sql;

import org.apache.log4j.Logger;

/**
 * mysql数据库的分页实现
 * 
 * */
public class MysqlSQLPageHandleImpl implements SQLPageHandle {

    private Logger logger=Logger.getLogger(MysqlSQLPageHandleImpl.class);

    public String handlerPagingSQL(String oldSQL, int pageNo, int pageSize) {
        StringBuffer sql = new StringBuffer(oldSQL);
        if (pageSize > 0) {
            int firstResult = (pageNo - 1)*pageSize;
            if (firstResult <= 0) {
                sql.append(" limit ").append(pageSize);
            } else {
                sql.append(" limit ").append(firstResult).append(",")
                        .append(pageSize);
            }
        }
        return sql.toString();
    }

}
4、BaseDao

个人觉得这几个最常用的就可以了,其他的可以再扩展,比如批量操作,我一直的想法就是先会走再会跑,单个的搞定了,批量的还远吗?

package com.mos.base.sql;


import java.util.List;
import java.util.Map;

/**
 * Package Name: com.mos.base
 * User: grq
 * Date: 2016/3/24
 * Time: 16:02
 * Description:some des here!
 */
public interface BaseDao {

    public <T> List<T> find(String sql, Object[] params, Class<T> tClass);

    public <T> int addOrUpdateOrDelete(String sql, Object[] params, Class<T> tClass);

    public <T> Page<T> queryPagination(String sql, Object[] parameters,int pageNo, int pageSize,  Class<T> entity);

    public <T> T findForObject(String sql, Object[] args, Class<T> classT);

    public Map<String,Object> find(String sql,Object[] params);

    public List<Map<String,Object>> queryList(String sql,Object[] params);
}
5、BaseDaoImpl

这个里面好多坑。

  1. queryPagination(…….)方法中有个totalList,这个就是对应前面Page对象的totalRows,如果不需要,那就不用查询了。
  2. 传入参数提示Class< T>,我以为比如User对象,传入User.class就行了,然并卵,spring jdbc不支持自定义复杂对象,需要转换,参考代码。
  3. 查询的时候如果没有查询条件,必须用没条件的方法查询,如果条件传个null,sorry,等着catch exception吧。
package com.mos.base.sql;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

/**
 * Package Name: com.mos.base
 * User: grq
 * Date: 2016/3/24
 * Time: 16:06
 * Description:some des here!
 */
@Repository
public class BaseDaoImpl implements BaseDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Resource
    protected SQLPageHandle sQLPageHandle;

    public <T> List<T> find(String sql, Object[] params, Class<T> tClass) {
        List<T> resultList = null;
        try {
            if (params != null && params.length > 0)
                resultList = jdbcTemplate.query(sql, params, new BeanPropertyRowMapper<T>(tClass));
            else
                // BeanPropertyRowMapper是自动映射实体类的
                resultList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<T>(tClass));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultList;
    }

    public <T> int addOrUpdateOrDelete(String sql, final Object[] params, Class<T> tClass) {
        int num = 0;
        try {
            if (params == null || params.length == 0)
                num = jdbcTemplate.update(sql);
            else
                num = jdbcTemplate.update(sql, new PreparedStatementSetter() {
                    public void setValues(PreparedStatement ps) throws SQLException {
                        for (int i = 0; i < params.length; i++)
                            ps.setObject(i + 1, params[i]);
                    }
                });
        } catch (Exception e) {
            e.printStackTrace();
            num = -1;
        }
        return num;

    }

    /**
     * @param sql
     * @param parameters
     * @param pageNo
     * @param pageSize
     * @param entity     jdbcTemplate.query由于需要返回自定义对象,调用此方法时候需要传入new BeanPropertyRowMapper<T>(entity)
     * @param <T>
     * @return
     */
    public <T> Page<T> queryPagination(String sql, Object[] parameters, int pageNo, int pageSize, Class<T> entity) {
        // 将SQL语句进行分页处理
        String newSql = sQLPageHandle.handlerPagingSQL(sql, pageNo, pageSize);
        List<T> list = null;
        List<T> totalList = null;
        if (parameters == null || parameters.length <= 0) {
            totalList = jdbcTemplate.query(sql, new BeanPropertyRowMapper<T>(entity));
            list = jdbcTemplate.query(newSql, new BeanPropertyRowMapper<T>(entity));
        } else {
            totalList = jdbcTemplate.query(sql, parameters, new BeanPropertyRowMapper<T>(entity));
            list = jdbcTemplate.query(newSql, parameters, new BeanPropertyRowMapper<T>(entity));
        }
        // 根据参数的个数进行差别查询
        Page<T> page = new Page<T>(pageNo, pageSize, totalList.isEmpty() ? 0 : totalList.size(), list);

        return page;
    }

    /**
     * @param sql
     * @param args
     * @param classT 注意该参数,jdbcTemplate.queryForObject传入的不能是自定义的classType,
     *               如果是自定义的,需要经过new BeanPropertyRowMapper<T>(classT)转换,默认支持的只有比如String,int等类型
     * @param <T>
     * @return
     */
    public <T> T findForObject(String sql, Object[] args, Class<T> classT) {
        if (sql == null || sql.length() <= 0) {
            return null;
        }
        if (args == null || args.length <= 0) {
            return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<T>(classT));
        }
        return jdbcTemplate.queryForObject(sql, args, new BeanPropertyRowMapper<T>(classT));
    }

    public Map<String, Object> find(String sql, Object[] params) {
        return jdbcTemplate.queryForMap(sql,params);
    }

    public List<Map<String, Object>> queryList(String sql, Object[] params) {
        return jdbcTemplate.queryForList(sql,params);
    }
}

附上项目地址:https://git.oschina.net/chemors/mosMVC.git

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值