HQL实现多对多关联查询(无关系表的映射)

HQL实现多对多关联查询(无关系表的映射)

目录:

  1. 应用场景
  2. 演示

[一]、应用场景

在用注解的方式(@ManyToMany @JoinTable)实现多对多映射时,并没有具体的多对多关系表的实体类,那么我们如何利用HQL实现关联查询呢?比如:学生和课程表之间的多对多关系。

[二]、演示

1.实体类

IdEntity.java

1package com.micmiu.hibernate.anno.entity;
2 
3import javax.persistence.Column;
4import javax.persistence.GeneratedValue;
5import javax.persistence.Id;
6import javax.persistence.MappedSuperclass;
7 
8/**
9 * 统一定义id的entity基类.
10 *
11 * 基类统一定义id的属性名称、数据类型、列名映射及生成策略. <br>
12 * 子类可重载getId()函数重定义id的列名映射和生成策略.
13 *
14 * @author <a href="http://www.micmiu.com">Michael Sun</a>
15 */
16@MappedSuperclass
17public abstract class IdEntity {
18 
19    protected Long id;
20 
21    @Id
22    @Column(name = "ID")
23    @GeneratedValue
24    // @GeneratedValue(strategy = GenerationType.SEQUENCE)
25    // @GeneratedValue(generator = "system-uuid")
26    // @GenericGenerator(name = "system-uuid", strategy = "uuid")
27    public Long getId() {
28        return id;
29    }
30 
31    public void setId(Long id) {
32        this.id = id;
33    }
34}

学生实体类:Student.java

1package com.micmiu.hibernate.anno.entity;
2 
3import java.util.Collection;
4import java.util.Date;
5 
6import javax.persistence.Column;
7import javax.persistence.Entity;
8import javax.persistence.JoinColumn;
9import javax.persistence.JoinTable;
10import javax.persistence.ManyToMany;
11import javax.persistence.OrderBy;
12import javax.persistence.Table;
13 
14import org.hibernate.annotations.Fetch;
15import org.hibernate.annotations.FetchMode;
16 
17/**
18 *
19 * Description:
20 *
21 * @author <a href="http://www.micmiu.com">Michael</a>
23 * @time Create on 2013-6-6 下午2:40:08
24 * @version 1.0
25 */
26@Entity
27@Table(name = "DEMO_T_STUDENT")
28public class Student extends IdEntity {
29 
30    @Column(name = "NAME")
31    private String name;
32 
33    @Column(name = "BIRTHDAY")
34    private Date birthday;
35 
36    private Collection<Course> courses;
37 
38    public String getName() {
39        return name;
40    }
41 
42    public void setName(String name) {
43        this.name = name;
44    }
45 
46    public Date getBirthday() {
47        return birthday;
48    }
49 
50    public void setBirthday(Date birthday) {
51        this.birthday = birthday;
52    }
53 
54    @ManyToMany
55    @JoinTable(name = "DEMO_R_S2C", joinColumns = { @JoinColumn(name = "SID") }, inverseJoinColumns = { @JoinColumn(name = "CID") })
56    @Fetch(FetchMode.SUBSELECT)
57    @OrderBy("id")
58    public Collection<Course> getCourses() {
59        return courses;
60    }
61 
62    public void setCourses(Collection<Course> courses) {
63        this.courses = courses;
64    }
65 
66    @Override
67    public String toString() {
68        return "Student [name=" + name + ", birthday=" + birthday + "]";
69    }
70 
71}

课程实体类:Course.java

1package com.micmiu.hibernate.anno.entity;
2 
3import javax.persistence.Column;
4import javax.persistence.Entity;
5import javax.persistence.Table;
6 
7/**
8 *
9 * Description:
10 *
11 * @author <a href="http://www.micmiu.com">Michael</a>
13 * @time Create on 2013-6-6 下午2:52:31
14 * @version 1.0
15 */
16@Entity
17@Table(name = "DEMO_T_COURSE")
18public class Course extends IdEntity {
19 
20    @Column(name = "NAME")
21    private String name;
22 
23    public String getName() {
24        return name;
25    }
26 
27    public void setName(String name) {
28        this.name = name;
29    }
30 
31    @Override
32    public String toString() {
33        return "Course [name=" + name + "]";
34    }
35 
36}

2.初始化数据:

利用dbunit初始化演示数据:

1<?xml version='1.0' encoding="utf-8"?>
2<dataset>
3    <demo_t_student id="101" name="micmiu.com" birthday="2012-12-12" />
4    <demo_t_student id="102" name="sjsky007@gmail.com" birthday="2008-08-08" />
5    <demo_t_student id="103" name="ctosun.com" birthday="2013-01-04" />
6 
7    <demo_t_course id="901" name="chinese" />
8    <demo_t_course id="902" name="english" />
9    <demo_t_course id="903" name="math" />
10 
11    <demo_r_s2c sid="101" cid="901" />
12    <demo_r_s2c sid="101" cid="902" />
13    <demo_r_s2c sid="101" cid="903" />
14    <demo_r_s2c sid="102" cid="902" />
15    <demo_r_s2c sid="102" cid="903" />
16    <demo_r_s2c sid="103" cid="903" />
17 
18</dataset>

3.演示关联查询

在Student中配置了多对多关系,在Course没有配置多对多关系,下面将分别演示关联查询这两个实体的方法:

测试基础类 HibernateBaseTest.java

1package com.micmiu.hibernate;
2 
3import org.hibernate.SessionFactory;
4import org.hibernate.cfg.Configuration;
5import org.hibernate.service.ServiceRegistry;
6import org.hibernate.service.ServiceRegistryBuilder;
7import org.junit.AfterClass;
8import org.junit.BeforeClass;
9import org.junit.Test;
10 
11/**
12 *
13 * Description:
14 *
15 * @author <a href="http://www.micmiu.com">Michael</a>
17 * @time Create on 2013-6-6 下午7:31:02
18 * @version 1.0
19 */
20public abstract class HibernateBaseTest {
21 
22    protected static SessionFactory sessionFactory;
23 
24    @BeforeClass
25    public static void beforeClass() {
26        Configuration configuration = new Configuration().configure();
27        ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
28                .applySettings(configuration.getProperties())
29                .buildServiceRegistry();
30        sessionFactory = configuration.buildSessionFactory(serviceRegistry);
31 
32    }
33 
34    @AfterClass
35    public static void afterClass() {
36        sessionFactory.close();
37    }
38 
39    @Test
40    public abstract void testMethod();
41 
42}

测试HQL查询:ManyToManyTest.java

1package com.micmiu.hibernate;
2 
3import java.util.List;
4 
5import org.hibernate.Query;
6import org.hibernate.Session;
7import org.junit.Assert;
8import org.junit.Test;
9 
10import com.micmiu.hibernate.anno.entity.Course;
11import com.micmiu.hibernate.anno.entity.Student;
12 
13/**
14 *
15 * Description:测试 注解配置多对多关系的表之间的联合查询
16 *
17 * @author <a href="http://www.micmiu.com">Michael</a>
19 * @time Create on 2013-6-7 上午11:38:49
20 * @version 1.0
21 */
22public class ManyToManyTest extends HibernateBaseTest {
23 
24    @Override
25    @Test
26    public void testMethod() {
27        // 测试查询有配置多对多关系的对象
28        test1();
29        // 测试查询无配置多对多关系的对象
30        test2();
31 
32    }
33 
34    /**
35     * 测试查询有配置多对多关系的对象
36     */
37    @SuppressWarnings("unchecked")
38    public void test1() {
39        Session session = sessionFactory.openSession();
40 
41        session.beginTransaction();
42        String hql = "select s from Student s join s.courses c where s.name like '%micmiu.com%' and c.name ='math'";
43        String hql2 = "select s from Student s,Course c where c.id in elements (s.courses) and s.name like '%micmiu.com%' and c.name ='math'";
44        Query query = session.createQuery(hql);
45 
46        List<Student> list = query.list();
47        System.out.println("----------- size:" + list.size());
48        Assert.assertEquals(1, list.size());
49 
50        for (Student s : list) {
51            Assert.assertEquals("micmiu.com", s.getName());
52            System.out.println(s);
53        }
54 
55        session.getTransaction().commit();
56        session.close();
57    }
58 
59    /**
60     * 测试查询无配置多对多关系的对象
61     */
62    @SuppressWarnings("unchecked")
63    public void test2() {
64        Session session = sessionFactory.openSession();
65 
66        session.beginTransaction();
67        String hql = "select distinct c from Student s,Course c where c.id in elements (s.courses) and s.name like '%micmiu.com%' and c.name ='math'";
68 
69        Query query = session.createQuery(hql);
70 
71        List<Course> list = query.list();
72        System.out.println("----------- size:" + list.size());
73        Assert.assertEquals(1, list.size());
74        for (Course c : list) {
75            Assert.assertEquals("math", c.getName());
76            System.out.println(c);
77        }
78 
79        session.getTransaction().commit();
80        session.close();
81    }
82}

执行结果:单元测试通过,运行日志如下:

Hibernate:

select

student0_.ID as ID1_,

student0_.birthday as birthday1_,

student0_.name as name1_

from

DEMO_T_STUDENT student0_

inner join

DEMO_R_S2C courses1_

on student0_.ID=courses1_.SID

inner join

DEMO_T_COURSE course2_

on courses1_.CID=course2_.ID

where

(

student0_.name like ‘%micmiu.com%’

)

and course2_.name=’math’

———– size:1

Student [name=micmiu.com, birthday=2012-12-12 00:00:00.0]

Hibernate:

select

distinct course1_.ID as ID0_,

course1_.name as name0_

from

DEMO_T_STUDENT student0_ cross

join

DEMO_T_COURSE course1_

where

(

course1_.ID in (

select

courses2_.CID

from

DEMO_R_S2C courses2_

where

student0_.ID=courses2_.SID

)

)

and (

student0_.name like ‘%micmiu.com%’

)

and course1_.name=’math’

———– size:1

Course [name=math]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值