In the above article, we have completed the implementation of the EasyUI menu. Click here to view it. In this section, we will mainly write about the CategoryServiceImpl implementation class to complete the cascading query of the database. Generally, the project is done from the back to the front, first do the service (we did not extract Dao, and finally extracted), and then do the upper layer after finishing.
Before writing, let’s take a look at the tables in the database:
drop database if exists shop; /*Create database and set encoding*/ create database shop default character set utf8; use shop; /*Delete administrator table*/ drop table if exists account; /*Delete product category table*/ drop table if exists category; /*============================================================================================================================================================================================================================================================================================================================================================================================================================================================ Administrator login name*/ login varchar(20), /* Administrator name*/ name varchar(20), /* Administrator password*/ pass varchar(20) ); /*======================================================================================================================================================================================================================================================================================================================================================================================================================================================================= false, /* foreign key, which administrator manages this category*/ account_id int, constraint aid_FK foreign key(account_id) references account(id) );
There are mainly two tables, the product category table and the administrator table, and a foreign key associated administrator table is provided in the product category table. That is, the product and the administrator are a many-to-one relationship. Now we start writing category information for querying products, and we need a cascading administrator.
1. Implement cascading query method
First, define this method in the CategoryService interface:
public interface CategoryService extends BaseService<Category> { //Query category information, cascading administrator public List<Category> queryJoinAccount(String type); //Query with the name of the category} Then we implement this method in the implementation class CategoryServiceImpl of CategoryService:
@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(); } } Among the two models, we will assign a link to the annotation:
// @ManyToOne(fetch = FetchType.EAGER) @JoinColumn(name = "account_id") public Account getAccount() { return this.account; } // @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "account") public Set<Category> getCategories() { return this.categories; } Then we test it in the test class:
@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. Problems with cascading queries
If we look at the output of the console, we can see that it has sent more than one SQL statement, but we have only queryed it once, so why do we send so many statements? This is the common 1+N problem. The so-called 1+N problem is to first issue a statement to query the current object, and then issue N statements to query the associated object, so the efficiency becomes very low. There are only two objects here. If there are more objects, the efficiency will be greatly reduced. How should we solve this problem?
Maybe you will think that if you set fetch to generate FetchType.LAZY, you won’t post multiple statements, but this is definitely not possible, because after setting it to LAZY, we can’t get the Account object. The better solution is to write the hql statement ourselves and use join fetch. For details, look at the modified CategoryServiceImpl implementation class:
@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 means to query together with Account, fetch means to add the Account object to Category, so that only one SQL statement will be sent, and the Category returned also contains the Account object.
3. Complete the paging function
The pagination in Hibernate is very simple. You only need to call two methods setFirstResult and setMaxResults: Let's modify the CategoryService interface and its implementation class CategoryServiceImpl:
//CategoryService public interface CategoryService extends BaseService<Category> { //Query category information, cascading administrator public List<Category> queryJoinAccount(String type, int page, int size); // and implement pagination} //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) //Show .setMaxResults(size) //Show several .list(); } } Let's test it in the test class:
@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)) { //Show the first page, 2 pieces of data per page System.out.println(c + "," + c.getAccount()); } } } To this end, we have finished writing the Service method and completed the cascading query and paging functions of product categories.
(Note: In the end, I will provide the source code download of the entire project! Everyone is welcome to collect or share)
Original address: http://blog.csdn.net/eson_15/article/details/51320212
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.