SSH框架網(wǎng)上商城項(xiàng)目第5戰(zhàn)之商品類別級(jí)聯(lián)查詢和分頁(yè)功能
上文我們完成了EasyUI菜單的實(shí)現(xiàn),點(diǎn)擊這里查看,這一節(jié)我們主要來寫一下CategoryServiceImpl實(shí)現(xiàn)類,完成數(shù)據(jù)庫(kù)的級(jí)聯(lián)查詢。一般項(xiàng)目從后往前做,先做service(我們沒有抽取Dao,最后再抽?。鐾炅嗽僮錾厦鎸?。
在寫之前,先看一下數(shù)據(jù)庫(kù)中的表的情況:
drop database if exists shop; /*創(chuàng)建數(shù)據(jù)庫(kù),并設(shè)置編碼*/ create database shop default character set utf8; use shop; /*刪除管理員表*/ drop table if exists account; /*刪除商品類別表*/ drop table if exists category; /*============================*/ /* Table:管理員表結(jié)構(gòu) */ /*============================*/ create table account ( /* 管理員編號(hào),自動(dòng)增長(zhǎng) */ id int primary key not null auto_increment, /* 管理員登錄名 */ login varchar(20), /* 管理員姓名 */ name varchar(20), /* 管理員密碼 */ pass varchar(20) ); /*============================*/ /* Table:商品類別表結(jié)構(gòu) */ /*============================*/ create table category ( /* 類別編號(hào),自動(dòng)增長(zhǎng) */ id int primary key not null auto_increment, /* 類別名稱 */ type varchar(20), /* 類別是否為熱點(diǎn)類別,熱點(diǎn)類別才有可能顯示在首頁(yè)*/ hot bool default false, /* 外鍵,此類別由哪位管理員管理 */ account_id int, constraint aid_FK foreign key(account_id) references account(id) );
主要有兩張表,商品類別表和管理員表,并且商品類別表中提供了一個(gè)外鍵關(guān)聯(lián)管理員表。也就是商品和管理員是多對(duì)一的關(guān)系?,F(xiàn)在我們開始編寫查詢商品的類別信息,需要級(jí)聯(lián)管理員。
1. 實(shí)現(xiàn)級(jí)聯(lián)查詢方法
首先在CategoryService接口中定義該方法:
public interface CategoryService extends BaseService<Category> { //查詢類別信息,級(jí)聯(lián)管理員 public List<Category> queryJoinAccount(String type); //使用類別的名稱查詢 }
然后我們?cè)贑ategoryService的實(shí)現(xiàn)類CategoryServiceImpl中實(shí)現(xiàn)這個(gè)方法:
@Service("categoryService") public class CategoryServiceImpl extends BaseServiceImpl<Category> implements CategoryService { @Override public List<Category> queryJoinAccount(String type) { String hql = "from Category c where c.type like :type"; return getSession().createQuery(hql) .setString("type", "%" + type + "%").list(); } }
在兩個(gè)Model中我們配一下關(guān)聯(lián)注解:
//Category類中 @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "account_id") public Account getAccount() { return this.account; } //Account類中 @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "account") public Set<Category> getCategories() { return this.categories; }
然后我們?cè)跍y(cè)試類中測(cè)試一下:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:beans.xml") public class CategoryServiceImplTest { @Resource private CategoryService categoryService; @Test public void testQueryJoinAccount() { for(Category c : categoryService.queryJoinAccount("")) { System.out.println(c); System.out.println(c.getAccount()); } } }
2. 級(jí)聯(lián)查詢存在的問題
我們看一下控制臺(tái)的輸出可以看出,它發(fā)了不止一條SQL語句,但是我們明明只查詢了一次,為什么會(huì)發(fā)這么多語句呢?這就是常見的1+N問題。所謂的1+N問題,就是首先發(fā)出一條語句查詢當(dāng)前對(duì)象,然后發(fā)出N條語句查詢關(guān)聯(lián)對(duì)象,因此效率變得很低。這里就兩個(gè)對(duì)象,如果有更多的對(duì)象,那效率就會(huì)大打折扣了,我們?cè)撊绾谓鉀Q這個(gè)問題呢?
可能大家會(huì)想到將fetch設(shè)置生FetchType.LAZY就不會(huì)發(fā)多條語句了,但是這肯定不行,因?yàn)樵O(shè)置成LAZY后,我們就拿不到Account對(duì)象了,比較好的解決方法是我們自己寫hql語句,使用join fetch。具體看修改后的CategoryServiceImpl實(shí)現(xiàn)類:
@Service("categoryService") public class CategoryServiceImpl extends BaseServiceImpl<Category> implements CategoryService { @Override public List<Category> queryJoinAccount(String type) { String hql = "from Category c left join fetch c.account where c.type like :type"; return getSession().createQuery(hql) .setString("type", "%" + type + "%").list(); } }
left join表示關(guān)聯(lián)Account一起查詢,fetch表示將Account對(duì)象加到Category中去,這樣就只會(huì)發(fā)一條SQL語句了,并且返回的Category中也包含了Account對(duì)象了。
3. 完成分頁(yè)功能
Hibernate中的分頁(yè)很簡(jiǎn)單,只需要調(diào)用兩個(gè)方法setFirstResult和setMaxResults即可:我們修改一下CategoryService接口和它的實(shí)現(xiàn)類CategoryServiceImpl:
//CategoryService public interface CategoryService extends BaseService<Category> { //查詢類別信息,級(jí)聯(lián)管理員 public List<Category> queryJoinAccount(String type, int page, int size); //并實(shí)現(xiàn)分頁(yè) } //CategoryServiceImpl @Service("categoryService") public class CategoryServiceImpl extends BaseServiceImpl<Category> implements CategoryService { @Override public List<Category> queryJoinAccount(String type, int page, int size) { String hql = "from Category c left join fetch c.account where c.type like :type"; return getSession().createQuery(hql) .setString("type", "%" + type + "%") .setFirstResult((page-1) * size) //從第幾個(gè)開始顯示 .setMaxResults(size) //顯示幾個(gè) .list(); } }
我們?cè)跍y(cè)試類中測(cè)試一下:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="classpath:beans.xml") public class CategoryServiceImplTest { @Resource private CategoryService categoryService; @Test public void testQueryJoinAccount() { for(Category c : categoryService.queryJoinAccount("",1,2)) { //顯示第一頁(yè),每頁(yè)2條數(shù)據(jù) System.out.println(c + "," + c.getAccount()); } } }
為此,我們寫完了Service的方法了,完成了對(duì)商品類別的級(jí)聯(lián)查詢和分頁(yè)功能。
(注:到最后我會(huì)提供整個(gè)項(xiàng)目的源碼下載!歡迎大家收藏或分享)
原文地址:http://blog.csdn.net/eson_15/article/details/51320212
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- php網(wǎng)上商城購(gòu)物車設(shè)計(jì)代碼分享
- php 網(wǎng)上商城促銷設(shè)計(jì)實(shí)例代碼
- struts2中action實(shí)現(xiàn)ModelDriven后無法返回json的解決方法
- java中struts2實(shí)現(xiàn)文件上傳下載功能實(shí)例解析
- SSH網(wǎng)上商城之使用ajax完成用戶名是否存在異步校驗(yàn)
- java網(wǎng)上商城開發(fā)之郵件發(fā)送功能(全)
- SSH框架網(wǎng)上商城項(xiàng)目第1戰(zhàn)之整合Struts2、Hibernate4.3和Spring4.2
- SSH框架網(wǎng)上商城項(xiàng)目第4戰(zhàn)之EasyUI菜單的實(shí)現(xiàn)
- SSH框架網(wǎng)上商城項(xiàng)目第8戰(zhàn)之查詢和刪除商品類別功能實(shí)現(xiàn)
- SSH框架網(wǎng)上商城項(xiàng)目第24戰(zhàn)之Struts2中處理多個(gè)Model請(qǐng)求的方法
相關(guān)文章
SpringBoot多模塊項(xiàng)目框架搭建過程解析
這篇文章主要介紹了SpringBoot多模塊項(xiàng)目框架搭建過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-01-01springboot+maven快速構(gòu)建項(xiàng)目的示例代碼
本篇文章主要介紹了springboot+maven快速構(gòu)建項(xiàng)目的示例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08Java用freemarker導(dǎo)出word實(shí)用示例
本篇文章主要介紹了Java用freemarker導(dǎo)出word實(shí)用示例,使用freemarker的模板來實(shí)現(xiàn)功能,有需要的可以了解一下。2016-11-11使用XSD校驗(yàn)Mybatis的SqlMapper配置文件的方法(1)
這篇文章以前面對(duì)SqlSessionFactoryBean的重構(gòu)為基礎(chǔ),簡(jiǎn)單的介紹了相關(guān)操作知識(shí),然后在給大家分享使用XSD校驗(yàn)Mybatis的SqlMapper配置文件的方法,感興趣的朋友參考下吧2016-11-11Spring Boot中擴(kuò)展XML請(qǐng)求與響應(yīng)的支持詳解
這篇文章主要給大家介紹了關(guān)于Spring Boot中擴(kuò)展XML請(qǐng)求與響應(yīng)的支持的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09Java詳解ScriptEngine接口動(dòng)態(tài)執(zhí)行JS腳本
ScriptEngine是基本接口,其方法必須在本規(guī)范的每個(gè)實(shí)現(xiàn)中完全起作用。這些方法提供基本腳本功能。 寫入這個(gè)簡(jiǎn)單接口的應(yīng)用程序可以在每個(gè)實(shí)現(xiàn)中進(jìn)行最少的修改。 它包括執(zhí)行腳本的方法,以及設(shè)置和獲取值的方法2022-08-08