利用模板操作來替換掉持久層的session,必須先將spring和hibernate之間進行整合,整合的applicationContext配置文件介紹在:
https://blog.csdn.net/IT_CREATE/article/details/86141823
那麼在持久層的代碼就如下面這樣寫:
1、對於增刪改(和session的操作差不多,也有save、update、delete三個方法)
@Repository
public class UserDaoImpl implements IUserDao {
@Resource
private HibernateTemplate hibernateTemplate;
@Override
public void saveUserBean(UserBean user) {
// TODO Auto-generated method stub
hibernateTemplate.save(user);
}
@Override
public void updateUserBean(UserBean user) {
// TODO Auto-generated method stub
hibernateTemplate.update(user);
}
@Override
public void deleteUserBean(UserBean user) {
// TODO Auto-generated method stub
hibernateTemplate.delete(user);
}
}
2、對於查詢(通過id查詢數據也有get和load兩個方法)
@Repository
public class UserDaoImpl implements IUserDao {
@Resource
private HibernateTemplate hibernateTemplate;
@Override
public UserBean getUserBeanById(int id) {
// TODO Auto-generated method stub
return (UserBean) hibernateTemplate.get(UserBean.class, id);
}
@Override
public UserBean loadUserBeanById(int id) {
// TODO Auto-generated method stub
/*
* get()和load()的區別: get()在查詢對象時,採用的是即時查詢方法,它從一級緩存開始,進行二級緩存,到達數據庫,它一定會得到一個最終的結果。
* load()在查詢對象時,採用的是延遲查詢方法,它從一級緩存開始,進行二級緩存,如果二級緩存中沒有對應的數據,它將默認數據庫中一定存在那條數據,
* 並返回該對象的代理對象, 直到程序發生調用時,纔去查詢,找到了就正常返回,找不到,拋異常:ObjectNotFoundException
*/
// 延遲加載對象,一定不能關閉Session
return (UserBean) hibernateTemplate.load(UserBean.class, id);
}
}
下面是自定義查詢條件:(具體的查詢方法可參考https://www.cnblogs.com/xrab/p/5586775.html)
1、利用hql語句進行查詢的一些方法
@Repository
public class UserDaoImpl implements IUserDao {
@Resource
private HibernateTemplate hibernateTemplate;
@Override
public Map<String, Object> queryUserBeanById(Integer id) {
// TODO Auto-generated method stub
String hql = "select new map(u.userName as userName,u.loginName as loginName,u.password as password) From UserBean as u where id = ?";
List<?> datas = hibernateTemplate.find(hql, new Object[] {id});
if (datas != null)
return (Map<String, Object>) datas.get(0);
return null;
}
@Override
public List<?> findUserBeanMapByObject(UserBean user) {
// TODO Auto-generated method stub
String hql = "select new map(u.loginName,u.userName,u.age) From UserBean as u where u.userName like concat(:userName,'%') and u.gender = :gender";
//要求user對象的屬性,必須包含HQL中參數名稱,“:”後面的名稱必須和對象屬性一致
return hibernateTemplate.findByValueBean(hql, user);
}
@Override
public UserBean findUserBeanByLoginNameAndPwd(String loginName, String pwd) {
// TODO Auto-generated method stub
/*按照位置進行設值 */
// String hql = "From UserBean as u where u.loginName = ? and u.password = ?";
// List<?> datas = hibernateTemplate.find(hql, new Object[] {loginName,pwd});
// if (datas != null) {
// return (UserBean) datas.get(0);
// }
// return null;
/*
* 按照參數別名進行設值
*/
String hql = "From UserBean as u where u.loginName = :ln and u.password = :pwd";
List<?> datas = hibernateTemplate.findByNamedParam(hql, new String[] {"ln","pwd"},new Object[] {loginName,pwd});
if (datas != null)
return (UserBean) datas.get(0);
return null;
}
@Override
public List<?> findUserBeanByObject(UserBean user) {
// TODO Auto-generated method stub
// --------------------------------------------------------
// ----------使用Query完成多條件查詢(明顯的缺陷:需要拼接語句)--------
// --------------------------------------------------------
/*
*
* */
//select 字段列表 from 表 where 條件
String hql = "select new UserBean(u.loginName,u.userName,u.age) From UserBean as u where u.userName like concat(:userName,'%') and u.gender = :gender";
return hibernateTemplate.findByValueBean(hql, user);
String hql = "select new map(u.loginName as loginName,u.userName as userName,u.age as age) From UserBean as u where u.userName like concat(:userName,'%') and u.gender = :gender";
return hibernateTemplate.findByValueBean(hql, user);
}
/**
*通過Map查詢用戶數據方法
*如果傳入的是map,那麼map中鍵的名字必須和hql語句中“:參數名”的參數名一致,才能在預編譯後賦值生效。在這裏,也就是說,map中有兩個鍵,userName和gender
*/
@Override
public List<?> findUserBeanByMap(Map map) {
// TODO Auto-generated method stub
String hql = "select new map(u.loginName as loginName,u.userName as userName,u.age as age) From UserBean as u where u.userName like concat(:userName,'%') and u.gender = :gender";
return hibernateTemplate.findByValueBean(hql, map);
}
/**
*得到分頁數據方法
*/
@SuppressWarnings("all")
@Override
public PageBean findUserBeanList2PageBean(PageBean page, UserBean user) {
// --------------------------------------------------------
// ----------使用Query完成多條件查詢(明顯的缺陷:需要拼接語句)--------
// --------------------------------------------------------
return (PageBean) hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
// TODO Auto-generated method stub
String hql = "select count(*) from UserBean as u where u.userName like concat(:userName,'%') and u.gender = :gender";
Query query = session.createQuery(hql);
query.setProperties(user);
//uniqueResult()表示返回一個唯一的結果
long totalRows = (long) query.uniqueResult();
List<?> datas = null;
if(totalRows > 0) {
hql = "from UserBean as u where u.userName like concat(:userName,'%') and u.gender = :gender";
query = session.createQuery(hql);
query.setProperties(user);
//設置數據庫中查詢起始位置、獲取的數據條數
query.setFirstResult(page.getIndex());
query.setMaxResults(page.getRows());
datas = query.list();
}
page.setTotalRows(totalRows);
page.setData(datas);
return page;
}
});
}
}
利用hibernateTemplate.execute方法可以直接操作session,方法內部用到了匿名內部類,這樣就和直接操作session一樣了。上面的到分頁數據中的方法用到的PageBean類在文章尾部。
2、利用Criteria進行查詢的方法
@Repository
public class UserDaoImpl implements IUserDao {
@Resource
private HibernateTemplate hibernateTemplate;
@Override
public List<?> findUserBeanByObject(UserBean user) {
// TODO Auto-generated method stub
// --------------------------------------------------------
// --------------使用Criteria完成多條件查詢---------------------
// --------------------------------------------------------
DetachedCriteria criteria = DetachedCriteria.forClass(UserBean.class);// From UserBean where 1=1
if (!StringUtils.isEmpty(user.getLoginName())) {
criteria.add(Restrictions.eq("loginName", user.getLoginName()));// and loginName = '"+user.getLoginName()+"'
}
if (!StringUtils.isEmpty(user.getUserName())) {
criteria.add(Restrictions.like("userName", user.getUserName(), MatchMode.START));// and userName like
}
criteria.add(Restrictions.or(Restrictions.eq("gender", 0), Restrictions.eq("gender", 1)));
criteria.add(Restrictions.between("age", 18, 60));// between …… and ……
criteria.addOrder(Order.desc("createTime"));// 按照創建時間降序排列
return hibernateTemplate.findByCriteria(criteria);
}
@SuppressWarnings("all")
@Override
public PageBean findUserBeanList2PageBean(PageBean page, UserBean user) {
// TODO Auto-generated method stub
// --------------------------------------------------------
// --------------使用Criteria完成多條件查詢---------------------
// --------------------------------------------------------
return (PageBean) hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
// TODO Auto-generated method stub
Criteria criteria = session.createCriteria(UserBean.class);
if (!StringUtils.isEmpty(user.getLoginName())) {
criteria.add(Restrictions.eq("loginName", user.getLoginName()));// and loginName = '"+user.getLoginName()+"'
}
if (!StringUtils.isEmpty(user.getUserName())) {
criteria.add(Restrictions.like("userName", user.getUserName(), MatchMode.START));// and userName like
}
if (user.getGender() != null) {
criteria.add(Restrictions.eq("gender", user.getGender()));
}
if (user.getBirthday() != null) {
criteria.add(Restrictions.ge("birthday", user.getBirthday()));
}
// 添加投影
criteria.setProjection(Projections.rowCount());// 我在From UserBean之上 添加了一個select count(*)
long totalRows = (long) criteria.uniqueResult();// 獲得多少條
List<?> datas = null;
if (totalRows > 0) {
// 去掉投影
criteria.setProjection(null);
criteria.setFirstResult(page.getIndex());
criteria.setMaxResults(page.getRows());
datas = criteria.list();
}
page.setTotalRows(totalRows);
page.setData(datas);
return page;
}
});
}
@Override
public List<?> findUserBeanByIdcardAndAddress(String idcard, String address) {
// TODO Auto-generated method stub
// --------------------------------------------------------
// --------------使用Criteria完成多條件查詢---------------------
// --------------------------------------------------------
DetachedCriteria criteria = DetachedCriteria.forClass(UserBean.class);//From UserBean as u where 1=1
//關聯對象查詢,給關聯對象取別名,並且完成兩個對象之間的關聯
criteria.createAlias("userInfo", "i",JoinType.LEFT_OUTER_JOIN);
criteria.createAlias("adds", "a",JoinType.LEFT_OUTER_JOIN);
if(!StringUtils.isEmpty(idcard)) {
criteria.add(Restrictions.like("i.idcard", idcard,MatchMode.START));
}
if(!StringUtils.isEmpty(address)) {
criteria.add(Restrictions.like("a.address", address,MatchMode.START));
}
return hibernateTemplate.findByCriteria(criteria);
}
}
上面代碼中的findUserBeanByObject() 和 findUserBeanByIdcardAndAddress()方法中用到了DetachedCriteria類,因爲hibernateTemplate.findByCriteria(DetachedCriteria criteria)方法必須傳入DetachedCriteria,
關於DetachedCriteria和Criteria的區別自行查閱。他們的用法差不多,只是DetachedCriteria相比Criteria少了一些方法。
Criteria由session的createCriteria(類.class)方法產生,
DetachedCriteria由它自帶的2個靜態方法forClass(Class) 或 forEntityName(Name) 進行DetachedCriteria 的實例創建。
- DetachedCriteria中去重複,並且將關聯對象裝配到主對象,用: criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
@Override
public List<?> findTeacherBeanByStudentName(String stuName) {
// TODO Auto-generated method stub
// String hql = "select DISTINCT(t) From TeacherBean as t left join fetch t.stus as s where s.stuName like concat(:stuName,'%')";
// return hibernateTemplate.findByNamedParam(hql, "stuName", stuName);
DetachedCriteria criteria = DetachedCriteria.forClass(TeacherBean.class);
criteria.createAlias("stus", "s",JoinType.LEFT_OUTER_JOIN);
if(!StringUtils.isEmpty(stuName)) {
criteria.add(Restrictions.like("s.stuName", stuName, MatchMode.START));
}
//去重複,並且將關聯對象,裝配到主對象身上去,相當於hql與劇中的DISTINCT()加上fetch的作用
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return hibernateTemplate.findByCriteria(criteria);
}
下面簡單列舉兩個返回分頁數據的例子:
1、利用Criteria
@Repository
public class StudentDaoImpl implements IStudentDao {
@Resource
private HibernateTemplate hibernateTemplate;
@SuppressWarnings("all")
@Override
public void findStudentBeanByTeacherName2PageBean(PageBean page, String teacherName) {
// TODO Auto-generated method stub
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
// TODO Auto-generated method stub
Criteria criteria = session.createCriteria(StudentBean.class);
criteria.createAlias("teacher", "t",JoinType.LEFT_OUTER_JOIN);
if(!StringUtils.isEmpty(teacherName)) {
criteria.add(Restrictions.like("t.teacherName", teacherName, MatchMode.START));
}
//添加投影
criteria.setProjection(Projections.rowCount());
long totalRows = (long) criteria.uniqueResult();
List<?> datas = null;
if(totalRows > 0) {
criteria.setProjection(null);
criteria.setFirstResult(page.getIndex());
criteria.setMaxResults(page.getRows());
criteria.setResultTransformer(Criteria.ROOT_ENTITY);//這句話的作用 === HQL中編寫的fetch
datas = criteria.list();
}
page.setTotalRows(totalRows);
page.setData(datas);
return page;
}
});
}
}
2、利用hql
@Repository
public class StudentDaoImpl implements IStudentDao {
@Resource
private HibernateTemplate hibernateTemplate;
@SuppressWarnings("all")
@Override
public void findStudentBeanByTeacherName2PageBean(PageBean page, String teacherName) {
// TODO Auto-generated method stub
hibernateTemplate.execute(new HibernateCallback() {
@Override
public Object doInHibernate(Session session) throws HibernateException {
// TODO Auto-generated method stub
String hql = "select count(*) From StudentBean as s left join s.teacher as t where t.teacherName like concat(:teacherName,'%')";
Query query = session.createQuery(hql);
query.setString("teacherName", teacherName);
long totalRows = (long) query.uniqueResult();
List<?> datas = null;
if(totalRows > 0) {
hql = "From StudentBean as s left join fetch s.teacher as t where t.teacherName like concat(:teacherName,'%')";
query = session.createQuery(hql);
query.setString("teacherName", teacherName);
query.setFirstResult(page.getIndex());
query.setMaxResults(page.getRows());
datas = query.list();
}
page.setTotalRows(totalRows);
page.setData(datas);
return page;
}
});
}
}
PageBean類:
package com.ge.hibernatexml.bean;
import java.util.List;
/**
* 分頁對象
* @author Administrator
*
*/
public class PageBean {
private int page;//當前頁碼
private int rows;//每頁顯示數據的行數
private int index;//數據獲取的起始位置(數據庫中)
private long totalRows;//數據總條數
private long totalPage;//總共有多少頁
private String sort;//排序字段
private String order;//排序方式
//具體的數據
private List<?> data;
public PageBean() {
super();
// TODO Auto-generated constructor stub
}
public PageBean(int page, int rows) {
super();
this.page = page;
this.rows = rows;
//計算數據獲取的起始位置
this.index = (page - 1) * rows;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public long getTotalRows() {
return totalRows;
}
public void setTotalRows(long totalRows) {
this.totalRows = totalRows;
//總頁碼
this.totalPage = totalRows % rows == 0 ? totalRows / rows : totalRows / rows + 1;
}
public String getSort() {
return sort;
}
public void setSort(String sort) {
this.sort = sort;
}
public String getOrder() {
return order;
}
public void setOrder(String order) {
this.order = order;
}
public long getTotalPage() {
return totalPage;
}
public void setTotalPage(long totalPage) {
this.totalPage = totalPage;
}
public List<?> getData() {
return data;
}
public void setData(List<?> data) {
this.data = data;
}
@Override
public String toString() {
return "PageBean [page=" + page + ", rows=" + rows + ", index=" + index + ", totalRows=" + totalRows
+ ", totalPage=" + totalPage + ", sort=" + sort + ", order=" + order + ", data=" + data + "]";
}
}