您的位置:首页 > 编程语言 > Java开发

Struts2、Hibernate、Spring整合的泛型DAO,以及通用的分页技术

2009-07-03 22:40 661 查看
1.基本DAO泛型接口

package abu.csdn.dao;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
/**
* <p/>
* 使用泛型作为DAO的通用接口 这里没有提供按名称精确查找,和模糊查找 上述两个方法应该由各自的具体接口去定义
* <p/>
*
* @author Abu
* @param <T> :
* 持久化的实体Bean
* @param <ID> :
* 实体Bean的id
*/
public interface GenericDao<T, ID extends Serializable> {
/**
* 保存实体
*
* @param entity :
*               实体
* @return 保存后得到的id
*/
public ID save(T entity);
/**
* 在查找所有记录的时候,使用提供查询语句,查询匹配的记录,否则将使用默认的查询语句查询数据的所有记录.
*
* @param hql : 自定义的HQL语句
*/
public void setHql(String hql);
/**
*
* @return 自定义的HQL语句
*/
public String getHql();
/**
* <p>
* 删除实体
* </p>
*
* @param entity :
*               实体
*/
public void remove(T entity);
/**
* <p>
* 删除实体集合
* </p>
*
* @param entities :
*                 实体
*/
public void removeAll(Collection<T> entities);
/**
* <p>
* 修改实体
* </p>
*
* @param entity :
*               实体
*/
public void modify(T entity);
/**
* <p>
* 通过名字查找
* </p>
*
* @param id :
*           id
* @return 找到的实体
*/
public T findById(ID id);
/**
* <p/>
* 查找全部实体
* <p/>
*
* @return 所有实体的列表
*/
public List<T> findAll();
/**
* <p>
* 计算匹配查询条件的记录总数,如果没有注入或者设置hql语句,将使用默认的查询语句返回数据库中所有记录
* </p>
*
* @return 记录总数
*/
public int getTotalRows();
/**
* <p>
* 根据每页记录的数量,计算出总的分页数
* </p>
*
* @param size 每页记录的数量
* @return 分页总数
*/
public int getPageSize(int size);
/**
* <p/>
* 根据给定的页码进行分页查找,这是纯Hibernate分页.
* <p/>
*
* @param page : 要查询的页码
*             查询的hql语句
* @param size : 每页记录数
*             分页信息,参见PageInfo
* @return 匹配的实体列表
*/
public List<T> findByPage(final int page, final int size);
}


2.基本DAO泛型接口的实现

package abu.csdn.dao.impl;
import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import abu.csdn.dao.GenericDao;
/**
*
* @author Abu
*
* @param <T>
* @param <ID>
*/
public class GenericDaoImpl<T, ID extends Serializable> implements
GenericDao<T, ID> {
// 具体的实体类型
private Class<T> type;
// Spring提供的Hibernate工具类
private HibernateTemplate hibernateTemplate;
// 查询条件
private String hql;
/**
* <p>
* 必须提供的构造方法,以便创建实例的时候就知道具体实体的类型
* <p>
*
* @param type :
*            实体类型
*/
public GenericDaoImpl(Class<T> type) {
this.type = type;
this.hql = "from " + type.getName();
}
/**
* <p>
* 因为这个类没有继承HibernateDaoSupport,所以现在由Spring注入HibernateTemplate
* </p>
*
* @param hibernateTemplate :
*            Spring提供的Hibernate工具类
*/
public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
this.hibernateTemplate = hibernateTemplate;
}
public void setHql(String hql) {
this.hql = hql;
}
public HibernateTemplate getHibernateTemplate() {
return hibernateTemplate;
}
public String getHql() {
return hql;
}
@SuppressWarnings("unchecked")
public List<T> findAll() {
String hql = "from " + type.getName();
return (List<T>) hibernateTemplate.find(hql);
}

@SuppressWarnings("unchecked")
public T findById(ID id) {
return (T) hibernateTemplate.get(type, id);
}
public void modify(T entity) {
hibernateTemplate.update(entity);
}
public void remove(T entity) {
hibernateTemplate.delete(entity);
}

public void removeAll(Collection<T> entities) {
hibernateTemplate.deleteAll(entities);
}
@SuppressWarnings("unchecked")
public ID save(T entity) {
return (ID) hibernateTemplate.save(entity);
}
public int getTotalRows() {
String actualHql = "select count(*) "
+ hql.substring(hql.indexOf("from"));
return ((Long) this.hibernateTemplate.find(actualHql).get(0))
.intValue();
}
public int getPageSize(int size) {
// 最大页数
int pageSize;
// 实际每页数据条数
int actualSize;
// 总记录数
int totalRows = this.getTotalRows();
// 计算实际每页的条数,如果请求的每页数据条数大于总条数, 则等于总条数
actualSize = (size > totalRows) ? totalRows : size;
if (totalRows > 0) {
pageSize = (totalRows % size == 0) ? (totalRows / actualSize)
: (totalRows / actualSize + 1);
} else {
pageSize = 0;
}
return pageSize;
}
@SuppressWarnings("unchecked")
public List<T> findByPage(final int page, final int size) {
final int pageSize = this.getPageSize(size);
final int totalRows = this.getTotalRows();
return hibernateTemplate.executeFind(new HibernateCallback() {
public List<T> doInHibernate(Session session)
throws HibernateException, SQLException {
// 实际页码
int actualPage = (page > pageSize) ? pageSize : page;
// 计算实际每页的条数,如果请求的每页数据条数大于总条数, 则等于总条数
int actualSize = (size > totalRows) ? totalRows : size;
// 计算请求页码的第一条记录的索引值,如果
int startRow = (actualPage > 0) ? (actualPage - 1) * actualSize
: 0;
Query query = session.createQuery(hql);
// 设置第一条记录
query.setFirstResult(startRow);
query.setMaxResults(actualSize);
return (List<T>) query.list();
}
});
}
}


3.具体的DAO接口

package abu.csdn.dao;
import abu.csdn.bean.User;
/**
*
* @author Abu
*
*/
public interface UserDao extends GenericDao<User, Long> {
/**
* <p>
* 根据用户名精确查找
* </p>
* @param uname : 用户名
* @return : 匹配的实体
*/
public User findByNameExact(String uname);
}


4.具体DAO接口的实现

package abu.csdn.dao.impl;
import java.util.List;
import abu.csdn.bean.User;
import abu.csdn.dao.UserDao;
/**
*
* @author Abu
*
*/
public class UserDaoImpl extends GenericDaoImpl<User, Long> implements UserDao {
public UserDaoImpl(Class<User> type) {
super(type);
}
@SuppressWarnings("unchecked")
public User findByNameExact(String uname) {
List<User> list = (List<User>) this.getHibernateTemplate().find(
"from User u where u.uname = ?", uname).get(0);
return (!list.isEmpty() && list.size() == 1) ? null : list.get(0);
}
}


5.基本泛型服务接口

package abu.csdn.service;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
/**
* <p>
* 基本上与泛型DAO的通用接口一致,请参见GenericDao
* <p>
*
* @author Abu
*
* @param <T> :
*            持久化的实体Bean
* @param <ID> :
*            实体Bean的id
*/
public interface GenericService<T, ID extends Serializable> {
/**
* 保存实体
*
* @param entity :
*            实体
* @return 保存后得到的id
*/
public ID save(T entity);
/**
* <p>
* 删除实体
* </p>
*
* @param entity :
*            实体
*/
public void remove(T entity);

/**
* <p>
* 删除实体集合
* </p>
*
* @param entities :
*            实体
*/
public void removeAll(Collection<T> entities);
/**
* <p>
* 修改实体
* </p>
*
* @param entity :
*            实体
*/
public void modify(T entity);
/**
* <p>
* 通过名字查找
* </p>
*
* @param id :
*            id
* @return 找到的实体
*/
public T findById(ID id);
/**
* <p>
* 查找全部实体
* <p>
*
* @return 所有实体的列表
*/
public List<T> findAll();
/**
* <p>
* 根据给定的hql语句进行分页查找
* <p>
*
* @param page :
*            要查询的页码
* @param size :
*            每页记录条数
* @return 匹配的实体列表
*/
public List<T> findByPage(final int page, final int size);
/**
* <p>
* 计算匹配查询条件的记录总数,如果没有注入或者设置hql语句,将使用默认的查询语句返回数据库中所有记录
* </p>
*
* @return 记录总数
*/
public int getTotalRows();
/**
* <p>
* 根据每页记录的数量,计算出总的分页数
* </p>
*
* @param size
*            每页记录的数量
* @return 分页总数
*/
public int getPageSize(int size);
}


6.基本泛型服务接口的实现

package abu.csdn.service.impl;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import abu.csdn.dao.GenericDao;
import abu.csdn.service.GenericService;
/**
*
* @author Abu
*
* @param <T>
* @param <ID>
*/
public class GenericServiceImpl<T, ID extends Serializable> implements
GenericService<T, ID> {
private GenericDao<T,ID> genericDao;

public List<T> findAll() {
return genericDao.findAll();
}
public T findById(ID id) {
return genericDao.findById(id);
}
public List<T> findByPage(int page, int size) {
return genericDao.findByPage(page, size);
}
public int getPageSize(int size) {
return genericDao.getPageSize(size);
}
public int getTotalRows() {
return genericDao.getTotalRows();
}
public void modify(T entity) {
genericDao.modify(entity);
}
public void remove(T entity) {
genericDao.remove(entity);
}
public void removeAll(Collection<T> entities) {
genericDao.removeAll(entities);
}

public ID save(T entity) {
return genericDao.save(entity);
}
public void setGenericDao(GenericDao<T, ID> genericDao) {
this.genericDao = genericDao;
}
}


7.具体的服务接口

package abu.csdn.service;
import abu.csdn.bean.User;
/**
*
* @author Abu
*
*/
public interface UserService extends GenericService<User, Long> {
/**
* <p>
* 用户登录验证, 登录成功将返回该用户实体,失败则为空
* </p>
*
* @param uname :
*            用户名
* @param upass :
*            密码
* @return 用户实体
*/
public User login(String uname, String upass);

public void removeByUids(long [] uids);
}


8.具体的服务接口的实现

package abu.csdn.service.impl;
import java.util.Collection;
import java.util.List;
import abu.csdn.bean.User;
import abu.csdn.dao.UserDao;
import abu.csdn.dao.impl.UserDaoImpl;
import abu.csdn.service.UserService;
/**
*
* @author Abu
*
*/
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public UserDao getUserDao() {
return this.userDao;
}
public List<User> findAll() {
return userDao.findAll();
}
public User findById(Long id) {
return userDao.findById(id);
}
public List<User> findByPage(int page, int size) {
return userDao.findByPage(page, size);
}
public int getPageSize(int size) {
return userDao.getPageSize(size);
}
public int getTotalRows() {
return userDao.getTotalRows();
}
public void modify(User entity) {
userDao.modify(entity);
}
public void removeAll(Collection<User> entities) {
userDao.removeAll(entities);
}
public void remove(User entity) {
userDao.remove(entity);
}
public Long save(User entity) {
return userDao.save(entity);
}
@SuppressWarnings("unchecked")
public User login(String uname, String upass) {
String hql = "from User u where u.uname = '" + uname + "'"
+ " and u.upass = '" + upass + "'";
userDao.setHql(hql);
List<User> list = userDao.findAll();
User user =  (list.isEmpty() && list.size() != 1) ? null : list.get(0);
// 千万要记住,一旦修改了默认值,则业务结束后要重新改回默认值
userDao.setHql(" from " + User.class.getName());

return  user;
}
public void removeByUids(long[] uids) {
StringBuffer hqlSb = new StringBuffer();
hqlSb.append(" from User u where u.uid in (");
for (int i = 0; i < uids.length; i++) {
if (i != uids.length - 1) {
hqlSb.append(uids[i]).append(",");
} else {
hqlSb.append(uids[i]);
}
}
hqlSb.append(")");
userDao.setHql(hqlSb.toString());
Collection<User> entities = userDao.findAll();
if (entities != null) {
userDao.removeAll(entities);
}
}
}


9.分页数据信息类

package abu.csdn.util;
/**
* 这个分页信息工具类,只用来保存从HibernateDao中取得的分页信息
* @author Abu
*
*/
public class PageData {
// 总记录数
private int totalRows;
// 每页记录数
private int size;
// 当前页
private int page;
// 页面总数
private int pageSize;
public int getTotalRows() {
return totalRows;
}
public void setTotalRows(int totalRows) {
this.totalRows = totalRows;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
}


10.分页工具类,用来生成客户端的分页代码

package abu.csdn.util;
/**
* <p>
* 生成分页代码,传给目标页面
* </p>
*
* @author Abu
*
*/
public class PageUtil {
// 显示列表显示的页数,默认为5
private final int listSize = 4;
// 当前页面位于列表的位置
private final int halfListSize = 2;
// 分页信息
private PageData pageData;
// 页面url
private String url;
// 生成的hmtl
private String html;
/**
* <p>
* 默认构造方法,提供给Spring注入使用,建议使用带参数的构造方法
* </p>
*/
public PageUtil() {
}
/**
* <p>
* 构造方法,必须提供分页信息和页面URL
*
* @param pageInfo :
*            分页信息
* @param url :
*            页面URL,像这样:
*
* <pre>
* /user/userList.do?page=
* </pre>
*/
public PageUtil(PageData pageInfo, String url) {
this.pageData = pageInfo;
this.url = url;
}
public void setPageData(PageData pageData) {
this.pageData = pageData;
}
public void setUrl(String url) {
this.url = url;
}
/**
* 根据分页信息生成分页代码
*
* @return 分页代码
*/
public String getHtml() {
StringBuffer htmlSb = new StringBuffer();
// 分页样式单
String pageStyle = "<mce:style><!--
.ptbl {border:1px solid #CEDBEF;font-size:12px;padding:0;font-family:Arial;width:auto} .ptbl a {text-decoration:none;color:#555555} .ptbl td {padding-top:0px;padding-bottom:0px;padding-left:4px;padding-right:4px}    .strong {background:#CEDBEF;font-weight:800;color:#FF7D00}    .strong a{color:#FF7D00} .page_input {background:#ffffff;border:1px solid #CEDBEF;border-top:none;border-bottom:none;color:#FF7D00;width:30px;margin:0px }
--></mce:style><style mce_bogus="1"> .ptbl {border:1px solid #CEDBEF;font-size:12px;padding:0;font-family:Arial;width:auto} .ptbl a {text-decoration:none;color:#555555} .ptbl td {padding-top:0px;padding-bottom:0px;padding-left:4px;padding-right:4px}    .strong {background:#CEDBEF;font-weight:800;color:#FF7D00}    .strong a{color:#FF7D00} .page_input {background:#ffffff;border:1px solid #CEDBEF;border-top:none;border-bottom:none;color:#FF7D00;width:30px;margin:0px } </style>";
// 表格样式单
String pageTable = "<table border='0'cellpadding='0' cellspacing='0' bgcolor='#CEDBEF' class='ptbl'><tr align='center' bgcolor='#FFFBFF'>";
// 当前页
int page = pageData.getPage();
// 总页数
int pageSize = pageData.getPageSize();
// 上一页
int prePage = page - 1;
// 判断是否到达了首页,如果是则等于首页
prePage = prePage <= 0 ? 1 : prePage;
// 下一页
int nextPage = page + 1;
// 判断是否到达了末页,如果是则等于末页
nextPage = nextPage >= pageSize ? pageSize : nextPage;
/**
* 以下开始正式生成页面代码
*/
// 首先加入样式单
htmlSb.append(pageStyle).append(pageTable);
// 显示记录总数
htmlSb.append("<td>共<font color='red'>" + pageData.getTotalRows()
+ "</font>条</td>");
if (page != prePage) {
// 首页
htmlSb.append("<td><a href="" + url + "1" mce_href="" + url + "1">首页</a></td>");
// 上一页
htmlSb.append("<td><a href="" + url + prePage + "" mce_href="" + url + prePage + "">上一页</a></td>");
}
// 控制输出列表,仅显示规定的条数
if (pageSize <= listSize) {
for (int i = 1; i <= pageSize; i++) {
if (i == page)
htmlSb.append("<td class='strong'>" + i + "</td>");
else {
// <td><a href="/user/userList.do?page=1" mce_href="user/userList.do?page=1">1</a></td>
htmlSb.append("<td><a href="" + url + i + "" mce_href="" + url + i + "">" + i
+ "</a></td>");
}
}
} else {
int begin = page - halfListSize;
begin = (begin <= 0) ? 1 : begin;
begin = ((halfListSize + page) > pageSize) ? (pageSize - listSize + 1)
: begin;
for (int i = begin; i <= listSize + begin - 1; i++) {
if (i == page) {
htmlSb.append("<td class='strong'>" + i + "</td>");
htmlSb.append("/n");
} else {
htmlSb.append("<td><a href="" + url + i + "" mce_href="" + url + i + "">" + i
+ "</a></td>");
htmlSb.append("/n");
}
}
}
// 下一页
if (page != pageSize) {
htmlSb.append("<td><a href="" + url + nextPage + "" mce_href="" + url + nextPage + "">下一页</a></td>");
// 末页
htmlSb.append("<td><a href="" + url + pageSize + "" mce_href="" + url + pageSize + "">末页</a></td>");
}
htmlSb.append("<td>共<font color='red'>" + pageSize
+ "</font>页</td></tr></table>");
return htmlSb.toString();
}
}


11.分页效果图

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: