博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【SSH网上商城项目实战05】完成数据库的级联查询和分页
阅读量:5787 次
发布时间:2019-06-18

本文共 10184 字,大约阅读时间需要 33 分钟。

转自:https://blog.csdn.net/eson_15/article/details/51320212

上一节我们完成了EasyUI菜单的实现。这一节我们主要来写一下CategoryServiceImpl实现类,完成数据库的级联查询。一般项目从后往前做,先做service(我们没有抽取Dao,最后再抽取),做完了再做上面层。

        在写之前,先看一下数据库中的表的情况:

 

1 drop database if exists shop; 2 /*创建数据库,并设置编码*/ 3 create database shop default character set utf8; 4  5 use shop; 6 /*删除管理员表*/ 7 drop table if exists account; 8 /*删除商品类别表*/ 9 drop table if exists category;10 11 /*============================*/12 /* Table:管理员表结构 */13 /*============================*/14 create table account15 (16 /* 管理员编号,自动增长 */17 id int primary key not null auto_increment,18 /* 管理员登录名 */19 login varchar(20),20 /* 管理员姓名 */21 name varchar(20),22 /* 管理员密码 */23 pass varchar(20)24 );25 26 /*============================*/27 /* Table:商品类别表结构 */28 /*============================*/29 create table category30 (31 /* 类别编号,自动增长 */32 id int primary key not null auto_increment,33 /* 类别名称 */34 type varchar(20),35 /* 类别是否为热点类别,热点类别才有可能显示在首页*/36 hot bool default false,37 /* 外键,此类别由哪位管理员管理 */38 account_id int,39 constraint aid_FK foreign key(account_id) references account(id)40 );

 

        主要有两张表,商品类别表和管理员表,并且商品类别表中提供了一个外键关联管理员表。也就是商品和管理员是多对一的关系。现在我们开始编写查询商品的类别信息,需要级联管理员。

 

1. 实现级联查询方法

        首先在CategoryService接口中定义该方法:

1 public interface CategoryService extends BaseService
{ 2 //查询类别信息,级联管理员 3 public List
queryJoinAccount(String type); //使用类别的名称查询 4 } 5 然后我们在CategoryService的实现类CategoryServiceImpl中实现这个方法: 6 7 8 9 10 11 @Service("categoryService")12 public class CategoryServiceImpl extends BaseServiceImpl
implements CategoryService {13 14 @Override15 public List
queryJoinAccount(String type) {16 String hql = "from Category c where c.type like :type";17 return getSession().createQuery(hql)18 .setString("type", "%" + type + "%").list();19 }20 }

 

        在两个Model中我们配一下关联注解:

 

 

//Category类中

1 package cn.it.shop.model;  2   3 import java.util.Set;  4   5 import javax.persistence.Column;  6 import javax.persistence.Entity;  7 import javax.persistence.FetchType;  8 import javax.persistence.GeneratedValue;  9 import javax.persistence.Id; 10 import javax.persistence.JoinColumn; 11 import javax.persistence.ManyToOne; 12  13  14 /** 15  * Category entity. @author MyEclipse Persistence Tools 16  */ 17 @Entity 18 public class Category implements java.io.Serializable { 19  20     // Fields 21  22     private Integer id; 23     private Account account; 24     private String type; 25     private Boolean hot; 26 //    private Set
products = new HashSet
(0); 27 28 29 // Constructors 30 31 /** default constructor */ 32 public Category() { 33 } 34 35 @Override 36 public String toString() { 37 return "Category [id=" + id + ", account=" + account + ", type=" + type 38 + ", hot=" + hot + "]"; 39 } 40 41 /** full constructor */ 42 public Category(Account account, String type, Boolean hot, 43 Set
products) { 44 this.account = account; 45 this.type = type; 46 this.hot = hot; 47 // this.products = products; 48 } 49 50 public Category(Integer id, String type, Boolean hot) { 51 super(); 52 this.id = id; 53 this.type = type; 54 this.hot = hot; 55 } 56 57 public Category(String type, Boolean hot) { 58 super(); 59 this.type = type; 60 this.hot = hot; 61 } 62 63 // Property accessors 64 @Id 65 @GeneratedValue 66 @Column(name = "id", unique = true, nullable = false) 67 public Integer getId() { 68 return this.id; 69 } 70 71 public void setId(Integer id) { 72 this.id = id; 73 } 74 75 @ManyToOne(fetch = FetchType.LAZY) 76 @JoinColumn(name = "aid") 77 public Account getAccount() { 78 return this.account; 79 } 80 81 public void setAccount(Account account) { 82 this.account = account; 83 } 84 85 @Column(name = "type", length = 20) 86 public String getType() { 87 return this.type; 88 } 89 90 public void setType(String type) { 91 this.type = type; 92 } 93 94 @Column(name = "hot") 95 public Boolean getHot() { 96 return this.hot; 97 } 98 99 public void setHot(Boolean hot) {100 this.hot = hot;101 }102 103 // @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "category")104 // public Set
getProducts() {105 // return this.products;106 // }107 //108 // public void setProducts(Set
products) {109 // this.products = products;110 // }111 112 }

 

//Account类中

1 package cn.it.shop.model;  2   3 import java.util.HashSet;  4 import java.util.Set;  5   6 import javax.persistence.CascadeType;  7 import javax.persistence.Column;  8 import javax.persistence.Entity;  9 import javax.persistence.FetchType; 10 import javax.persistence.GeneratedValue; 11 import javax.persistence.Id; 12 import javax.persistence.OneToMany; 13 import javax.persistence.Table; 14  15 /** 16  * Account entity. @author MyEclipse Persistence Tools 17  */ 18 @Entity 19 public class Account implements java.io.Serializable { 20  21     // Fields 22  23     private Integer id; 24     private String login; 25     private String name; 26     private String pass; 27 //    private Set
categories = new HashSet
(0); 28 29 30 // Constructors 31 32 /** default constructor */ 33 public Account() { 34 } 35 36 @Override 37 public String toString() { 38 return "Account [id=" + id + ", login=" + login + ", name=" + name 39 + ", pass=" + pass + "]"; 40 } 41 42 /** full constructor */ 43 public Account(String login, String name, String pass, 44 Set
categories) { 45 this.login = login; 46 this.name = name; 47 this.pass = pass; 48 // this.categories = categories; 49 } 50 51 52 public Account(String login, String name, String pass) { 53 super(); 54 this.login = login; 55 this.name = name; 56 this.pass = pass; 57 } 58 59 // Property accessors 60 @Id 61 @GeneratedValue 62 @Column(name = "id", unique = true, nullable = false) 63 public Integer getId() { 64 return this.id; 65 } 66 67 public void setId(Integer id) { 68 this.id = id; 69 } 70 71 @Column(name = "login", length = 20) 72 public String getLogin() { 73 return this.login; 74 } 75 76 public void setLogin(String login) { 77 this.login = login; 78 } 79 80 @Column(name = "name", length = 20) 81 public String getName() { 82 return this.name; 83 } 84 85 public void setName(String name) { 86 this.name = name; 87 } 88 89 @Column(name = "pass", length = 20) 90 public String getPass() { 91 return this.pass; 92 } 93 94 public void setPass(String pass) { 95 this.pass = pass; 96 } 97 98 // @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "account") 99 // public Set
getCategories() {100 // return this.categories;101 // }102 //103 // public void setCategories(Set
categories) {104 // this.categories = categories;105 // }106 107 }

 

        然后我们在测试类中测试一下:

 

 

1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration(locations="classpath:beans.xml") 3 public class CategoryServiceImplTest { 4  5 @Resource 6 private CategoryService categoryService; 7  8 @Test 9 public void testQueryJoinAccount() {10 for(Category c : categoryService.queryJoinAccount("")) {11 System.out.println(c);12 System.out.println(c.getAccount());13 }14 }15 }

 

2. 级联查询存在的问题

        我们看一下控制台的输出可以看出,它发了不止一条SQL语句,但是我们明明只查询了一次,为什么会发这么多语句呢?这就是常见的1+N问题。所谓的1+N问题,就是首先发出一条语句查询当前对象,然后发出N条语句查询关联对象,因此效率变得很低。这里就两个对象,如果有更多的对象,那效率就会大打折扣了,我们该如何解决这个问题呢?

        可能大家会想到将fetch设置生FetchType.LAZY就不会发多条语句了,但是这肯定不行,因为设置成LAZY后,我们就拿不到Account对象了,比较好的解决方法是我们自己写hql语句,使用join fetch。具体看修改后的CategoryServiceImpl实现类:

 

1 @Service("categoryService") 2 public class CategoryServiceImpl extends BaseServiceImpl
implements CategoryService { 3 4 @Override 5 public List
queryJoinAccount(String type) { 6 String hql = "from Category c left join fetch c.account where c.type like :type"; 7 return getSession().createQuery(hql) 8 .setString("type", "%" + type + "%").list(); 9 }10 }

 

        left join表示关联Account一起查询,fetch表示将Account对象加到Category中去,这样就只会发一条SQL语句了,并且返回的Category中也包含了Account对象了。

 

3. 完成分页功能

        Hibernate中的分页很简单,只需要调用两个方法setFirstResult和setMaxResults即可:我们修改一下CategoryService接口和它的实现类CategoryServiceImpl:

 

1 //CategoryService 2 public interface CategoryService extends BaseService
{ 3 //查询类别信息,级联管理员 4 public List
queryJoinAccount(String type, int page, int size); //并实现分页 5 } 6 7 //CategoryServiceImpl 8 @Service("categoryService") 9 public class CategoryServiceImpl extends BaseServiceImpl
implements CategoryService {10 11 @Override12 public List
queryJoinAccount(String type, int page, int size) {13 String hql = "from Category c left join fetch c.account where c.type like :type";14 return getSession().createQuery(hql)15 .setString("type", "%" + type + "%")16 .setFirstResult((page-1) * size) //从第几个开始显示17 .setMaxResults(size) //显示几个18 .list();19 }20 }

 

        我们在测试类中测试一下:

1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration(locations="classpath:beans.xml") 3 public class CategoryServiceImplTest { 4  5 @Resource 6 private CategoryService categoryService; 7  8 @Test 9 public void testQueryJoinAccount() {10 for(Category c : categoryService.queryJoinAccount("",1,2)) { //显示第一页,每页2条数据11 System.out.println(c + "," + c.getAccount());12 }13 }14 }

 

        为此,我们写完了Service的方法了,完成了对商品类别的级联查询和分页功能。

转载于:https://www.cnblogs.com/sharpest/p/9789940.html

你可能感兴趣的文章
jetty9优化的两处地方
查看>>
Android APK文件解析
查看>>
【MyBatis框架】MyBatis入门程序第二部分
查看>>
一分钟了解阿里云产品:网络安全专家服务
查看>>
自定义View以及事件分发总结
查看>>
人生第一个过万 Star 的 GitHub 项目诞生
查看>>
Mac下配置多个SSH-Key (gitLab)
查看>>
Gradle之module间依赖版本同步
查看>>
一些kindle资源
查看>>
Node第一天
查看>>
【开源】多多客发布 3.0.0-alpha.6,Koa+Vue+Taro最佳实践
查看>>
页面搭建工具总结及扩展架构思考
查看>>
java springcloud版b2b2c社交电商spring cloud分布式微服务(十五)Springboot整合RabbitMQ...
查看>>
SpringCloud使用Prometheus监控(基于Eureka)
查看>>
10g手动创建数据库
查看>>
集群之RHCS
查看>>
auto_install_zabbix.sh
查看>>
Linux—文件系统
查看>>
运用Loadrunner测试Mysql数据库性能
查看>>
mysql ERROR 1396 (HY000): Operation CREATE USER failed 解决办法
查看>>