2.3.1. 使用HibernateDao

2023-07-03 16:55 更新

1.1.準(zhǔn)備

首先,新建一個(gè)com.bstek.demo.hibernamteDao包,在這個(gè)包中添加一個(gè)繼承com.bstek.bdf2.core.orm.hibernate.HibernateDao類的子類HibernateDaoTest和一個(gè)視圖文件HibernateDaoTest.view.xml。然后,在HibernateDaoTest.view.xml文件中添加一個(gè)name為dataTypeDemoUser的DataType,并設(shè)置creationType屬性為com.bstek.demo.model.DemoUser。再在視圖view節(jié)點(diǎn)下添加一個(gè)id為dataSetDemoUser的DataSet,并設(shè)置dataType屬性為我們前面添加的name為dataTypeDemoUser的DataType,選擇DataType時(shí),勾選Collection選項(xiàng)。最后,在視圖view節(jié)點(diǎn)下添加一個(gè)id為gridDemoUser的DataGrid。接下來,在dorado-home文件夾下,找到context.xml,添加如下配置:
context.xml部分配置源碼
<bean id="hibernateDaoTest" class="com.bstek.demo.hibernamteDao.HibernateDaoTest">
</bean>context.xml部分配置源碼
<bean id="hibernateDaoTest" class="com.bstek.demo.hibernamteDao.HibernateDaoTest">
</bean>

1.2.使用HibernateDao實(shí)現(xiàn)增、刪、改

首先,在視圖文件的view節(jié)點(diǎn)添加id為updateActionDemoUser的UpdateAction,將其dataResolver屬性設(shè)為hibernateDaoTest#saveDemoUsers,并將為其添加一個(gè)屬性dataSet為dataSetDemoUser的UpdateItem子項(xiàng)。然后,在view節(jié)點(diǎn)添加一個(gè)ToolBar,并為其添加三個(gè)按鈕ToolBarBotton,分別是添加按鈕、刪除按鈕和保存按鈕,其中,在添加按鈕的onClick事件中添加如下代碼:
var data=view.get("#dataSetDemoUser.data");
data.insert();
在刪除按鈕的onClick事件中添加如下代碼:
var entity=view.get("#dataSetDemoUser.data:#");
var updateActionDemoUser=view.get("#updateActionDemoUser");
if(entity){
 entity.remove();
}else{
 dorado.MessageBox.alert("必須選中一行記錄!");
}
在保存按鈕的onClick事件中添加如下代碼:
var updateActionDemoUser=view.get("#updateActionDemoUser");
updateActionDemoUser.execute();
最后,我們需要完成后臺(tái)服務(wù)方法的編寫,就是在HibernateDaoTest類中添加如下代碼:
@DataResolver
public void saveDemoUsers(Collection<DemoUser> users){
 Session session = this.getSessionFactory().openSession();
 try{
 for (DemoUser user : users) {
 EntityState state=EntityUtils.getState(user);
 if (state.equals(EntityState.NEW)) {
 session.save(user);
 } else if (state.equals(EntityState.MODIFIED)) {
 session.update(user);
 } else if (state.equals(EntityState.DELETED)) {
 session.delete(user);
 }
 }
 }finally{
 session.flush();
 session.close();
 }
}
這樣,我們就完成了對(duì)數(shù)據(jù)的增刪改了。

1.3.doInHibernateSession的使用

首先,將視圖文件的view節(jié)點(diǎn)下id為updateActionDemoUser的UpdateAction的dataResolver屬性設(shè)為hibernateDaoTest#saveDemoUsers2,最后,我們需要完成后臺(tái)服務(wù)方法的編寫,就是在HibernateDaoTest類中添加如下代碼:
@DataResolver
public void saveDemoUsers2(final Collection<DemoUser> users){
 this.doInHibernateSession(new ISessionCallback<Object>(){
 @Override
 public Object doInSession(Session session) {
 for (DemoUser user : users) {
 EntityState state = EntityUtils.getState(user);
 if (state.equals(EntityState.NEW)) {
 session.save(user);
 } else if (state.equals(EntityState.MODIFIED)) {
 session.update(user);
 } else if (state.equals(EntityState.DELETED)) {
 session.delete(user);
 }
 }
 return null;
 }
 });
}
代碼說明:使用doInHibernateSession方法的好處就是我們不用手動(dòng)提交事務(wù)和關(guān)閉Session,這些工作都交由doInHibernateSession方法幫我做了,這樣就可以防止程序員忘記或使用不安全可靠的方式提交事務(wù)和關(guān)閉Session。另外,我們就用doInHibernateSession方法實(shí)現(xiàn)了數(shù)據(jù)的增刪改,看起來更加簡(jiǎn)潔和可靠,減少了重復(fù)易錯(cuò)代碼的編寫。

1.4.使用HibernateDao實(shí)現(xiàn)各類查詢

1.4.1.無查詢條件的查詢

將dataSetDemoUser的dataProvider屬性設(shè)置為hibernateDaoTest#query1。接下來,在HibernateDaoTest類里添加如下方法:
@DataProvider
public Collection<DefaultPosition> query1(){
 return this.query("from "+DemoUser.class.getName());
}
代碼說明:HibernateDao對(duì)象的query(Stringhql)方法,通過傳入一個(gè)hql語句進(jìn)行查詢。該代碼的結(jié)果是查詢DemoUser對(duì)應(yīng)表的所有的記錄。

1.4.2.帶Map參數(shù)的條件查詢

首先,在HibernateDaoTest.view.xml視圖的view節(jié)點(diǎn)中,添加一個(gè)id為將textUsername的TextEditor和一個(gè)查詢按鈕,并在查詢按鈕的onClick事件中添加如下代碼:
var username=view.get("#textUsername.value");
var dataSetDemoUser=view.get("#dataSetDemoUser");
if(username){
 dataSetDemoUser.set("parameter",{username:username}).flushAsync();
}
然后,我們需要將dataSetDemoUser的dataProvider屬性設(shè)置為hibernateDaoTest#query2。最后,在HibernateDaoTest類里添加如下方法:
@DataProvider
public Collection<DefaultPosition> query2(String username){
 Map<String,Object> map =new HashMap<String,Object>();
 String sql="from "+DomeUser.class.getName()+" du ";
 if(username!=null&&!"".equals(username)){
 map.put("username", username);
 sql+=" where du.username=:username";
 }
 return this.query(sql, map);
}
代碼說明:HibernateDao對(duì)象的query(Stringhql,Map<String,Object>parameterMap)方法,可以實(shí)現(xiàn)帶參數(shù)的查詢,參數(shù)放到Map集合當(dāng)中,可以放入多查詢參數(shù)。

1.4.3.帶Map參數(shù)的like條件查詢

首先,我們需要將dataSetDemoUser的dataProvider屬性設(shè)置為hibernateDaoTest#query3。最后,在HibernateDaoTest類里添加如下方法:
@DataProvider
public Collection<DomeUser> query3(String username){
 Map<String,Object> map =new HashMap<String,Object>();
 String sql="from "+DomeUser.class.getName()+" du ";
 if(username!=null&&!"".equals(username)){
 map.put("username", "%"+username+"%");
 sql+="where du.username like :username";
 }
 return this.query(sql, map);
}

1.4.4.帶DetachedCriteria參數(shù)的條件查詢

將dataSetDemoUser的dataProvider屬性設(shè)置為hibernateDaoTest#query4。最后,在HibernateDaoTest類里添加如下方法:
@DataProvider
public Collection<DemoUser> query4(String username){
 DetachedCriteria detachedCriteria=DetachedCriteria.forClass(DemoUser.class);
 if(username!=null&&!"".equals(username)){
 detachedCriteria.add(Restrictions.eq("username", username));
 }
 return (Collection<DemoUser>)this.query(detachedCriteria);
}
代碼說明:此段代碼的功能和上一節(jié)代碼的功能是一樣的,只是這里構(gòu)造查詢語句是通過DetachedCriteria對(duì)象來實(shí)現(xiàn),這種方式更面向?qū)ο螅勺x性更強(qiáng)。

1.4.5.無查詢條件的分頁查詢

首先,我們要將dataSetDemoUser的dataProvider屬性設(shè)置為hibernateDaoTest#query5,并將dataSetDemoUser的pageSize設(shè)置為10,再添加一個(gè)分頁工具DataPilot,并設(shè)置dataSet屬性為dataSetDemoUser,最后,在HibernateDaoTest類里添加如下方法:
@DataProvider
public void query5(Page<DemoUser> page) throws Exception{
 this.pagingQuery(page, "from "+DemoUser.class.getName(), "select count(*) from
"+DemoUser.class.getName());
}
代碼說明:HibernateDao對(duì)象的pagingQuery(Page<?>page,StringqueryString,StringcountQueryString)方法,可以實(shí)現(xiàn)無查詢條件的查詢。

1.4.6.帶Map參數(shù)的條件分頁查詢

將dataSetDemoUser的dataProvider屬性設(shè)置為hibernateDaoTest#query6,接下來,在HibernateDaoTest類里添加如下方法:
@DataProvider
public void query6(Page<DemoUser> page,String username) throws Exception{
 Map<String,Object> map =new HashMap<String,Object>();
 String sql="from "+DomeUser.class.getName()+" du ";
 String sqlCount="select count(*) from "+DomeUser.class.getName()+" du ";
 if(username!=null&&!"".equals(username)){
 map.put("username", username);
 sql+=" where du.username=:username";
 sqlCount+=" where du.username=:username";
 }
 this.pagingQuery(page, sql,sqlCount,map);
}
代碼說明:HibernateDao對(duì)象的pagingQuery(Page<?>page,StringqueryString,StringcountQueryString,Map<String,Object>parametersMap)方法,可以實(shí)現(xiàn)帶查詢條件的分頁查詢,條件參數(shù)放在Map集合中。

1.4.7.帶DetachedCriteria參數(shù)的條件分頁查詢

將dataSetDemoUser的dataProvider屬性設(shè)置為hibernateDaoTest#query7,接下來,在HibernateDaoTest類里添加如下方法:
@DataProvider
public void query7(Page<DemoUser> page,String username) throws Exception{
 DetachedCriteria detachedCriteria=DetachedCriteria.forClass(DemoUser.class);
 if(username!=null&&!"".equals(username)){
 detachedCriteria.add(Restrictions.eq("username", username));
 }
 this.pagingQuery(page, detachedCriteria);
}
代碼說明:HibernateDao對(duì)象的pagingQuery(Page<?>page,DetachedCriteriadetachedCriteria)方法,可以實(shí)現(xiàn)帶條件分頁查詢,條件參數(shù)放在DetachedCriteria集合中。

1.4.8.結(jié)合DataGrid的過濾工具欄實(shí)現(xiàn)分頁查詢

將dataSetDemoUser的dataProvider屬性設(shè)置為hibernateDaoTest#query8,并將gridDemoUser的filterMode和showFilterBar屬性分別設(shè)置為serverSide和true。接下來,在HibernateDaoTest類里添加如下方法:
@DataProvider
public void query8(Page<DemoUser> page,Criteria criteria) throws Exception{
 DetachedCriteria detachedCriteria=this.buildDetachedCriteria(criteria, DemoUser.class);
 this.pagingQuery(page, detachedCriteria);
}
代碼說明:query7的criteria參數(shù)是由視圖中的DataGrid的filterBar生成傳回來的,通過HibernateDao的buildDetachedCariteria方法,可以把criteria類型的對(duì)象轉(zhuǎn)換為hibernate能識(shí)別的DetachedCariteria對(duì)象。

1.4.9.單值查詢queryForInt的使用

接下來,我們將通過queryForInt方法實(shí)現(xiàn)username唯一性驗(yàn)證功能需求。首先,將我們?yōu)閐ataTypeDemoUser的username屬性添加一個(gè)AjaxVilidator驗(yàn)證,設(shè)置其server屬性值為hibernateDaoTest#hasUsername,最后,在HibernateDaoTest類里添加如下方法:
@Expose
public String hasUsername(String username){
 Map<String,Object> map =new HashMap<String,Object>();
 map.put("username", username);
 String sql="select count(du) from "+DemoUser.class.getName()+" du where du.username=:username";
 int count=this.queryForInt(sql, map);
 if(count>0){
 return "用戶名已經(jīng)存在了!";
 }
 return null;
}
完成后,當(dāng)我們編輯username列時(shí),如果改username的值數(shù)據(jù)庫中已經(jīng)存在,將會(huì)出現(xiàn)驗(yàn)證不通過。

1.4.10. 大數(shù)據(jù)量的優(yōu)化分頁查詢單實(shí)現(xiàn)

在數(shù)據(jù)量很大的時(shí)候,普通的分頁查詢的性能瓶頸就是計(jì)算機(jī)數(shù)據(jù)的總條數(shù),這時(shí)候我們就可以通過query(DetachedCriteriadetachedCriteria,int pageIndex,int pageSize)和queryCount(DetachedCriteria detachedCriteria,int pageIndex,int pageSize)相結(jié)合來優(yōu)化我們的分頁查詢。主要原理:先通過query把用戶關(guān)心的當(dāng)前頁數(shù)據(jù)查詢出來并返回給客戶端供用戶使用,當(dāng)當(dāng)前頁數(shù)據(jù)加載完成后,我們通過AjaxAction向后臺(tái)發(fā)出異步請(qǐng)求,取得數(shù)據(jù)的總記錄數(shù),并更新分頁控件。為了實(shí)現(xiàn)上述功能,首先,在視圖文件的view節(jié)點(diǎn)下添加一個(gè)id為ajaxActionQueryCount的AjaxAction控件,并設(shè)置屬性service的值為hibernateDaoTest#queryCount,接著給dataSetDemoUser的onLoadData事件添加如下代碼:
var ajaxActionQueryCount=view.get("#ajaxActionQueryCount");
var entityList=self.getData();
ajaxActionQueryCount.execute(function(count){
 entityList.pageCount=count;
});
完成后,將dataSetDemoUser的dataProvider屬性設(shè)置為hibernateDaoTest#query9。接下來,在HibernateDaoTest類里添加如下方法:
@DataProvider
public void query9(Page<DemoUser> page,Criteria criteria){
 HttpSession session=DoradoContext.getAttachedRequest().getSession();
 DetachedCriteria detachedCriteria=this.buildDetachedCriteria(criteria, DemoUser.class);
 session.setAttribute("criteria", criteria);
 Collection<DemoUser> users=
(Collection<DemoUser>)this.query(detachedCriteria,page.getPageNo(),page.getPageSize());
 page.setEntities(users);
}
@Expose
public int queryCount(){
 HttpSession session=DoradoContext.getAttachedRequest().getSession();
 Criteria criteria=(Criteria)session.getAttribute("criteria");
 DetachedCriteria detachedCriteriaCount=this.buildDetachedCriteria(criteria, DemoUser.class);
 int count=this.queryCount(detachedCriteriaCount,0,0);
 session.removeAttribute("criteria");
 return count;
}
注意事項(xiàng):在對(duì)數(shù)據(jù)總記錄條數(shù)進(jìn)行查詢的時(shí)候,一定要用Criteria對(duì)象通過buildDetachedCriteria方法重新生產(chǎn)DetachedCriteria對(duì)象傳給queryCount的相應(yīng)的形成。
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)