При использовании hibernate в случае сложных запросов возникает необходимость использовать sql.
Поэтому на помощь приходят sqlRestrictions. Однако использование sql-ограничений для псевдонима таблицы соединения немного сложно.
Там будет три таблицы:
- Фирменный стол.
- Стол сотрудника.
Каждый сотрудник принадлежит одной компании, поэтому у нас есть отношения многие к одному. - Таблица преимуществ.
У каждой компании есть много преимуществ, поэтому у нас есть отношения один ко многим.
Postgresql будет использоваться для этого примера.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
CREATE DATABASE example;CREATE TABLE company ( company_id SERIAL PRIMARY KEY, name TEXT NOT NULL);CREATE TABLE employee ( employee_id SERIAL PRIMARY KEY, first_name TEXT, last_name TEXT, company_id integer, CONSTRAINT fk_company FOREIGN KEY (company_id) REFERENCES company (company_id) MATCH SIMPLE);CREATE TABLE benefit ( benefit_id SERIAL PRIMARY KEY, name TEXT, company_id integer, CONSTRAINT fk_company FOREIGN KEY (company_id) REFERENCES company (company_id) MATCH SIMPLE);INSERT INTO company (name) VALUES ('TestCompany');INSERT INTO employee (first_name, last_name, company_id) VALUES ('Emmanouil','Gkatziouras',1);INSERT INTO benefit (name,company_id) VALUES ('gym',1); |
JPA будет использоваться для конфигурации объекта.
Субъект компании.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
package com.gkatzioura.example.entity;import javax.persistence.*;import java.util.HashSet;import java.util.Set;/** * Created by gkatziourasemmanouil on 7/12/15. */@Entity@Table(name = "company")public class Company { @Id @GeneratedValue @Column(name = "company_id") private Long Id; @Column String name; @OneToMany(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy = "company") private Set<Benefit> benefits = new HashSet<Benefit>(); public Long getId() { return Id; } public void setId(Long id) { Id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Set<Benefit> getBenefits() { return benefits; } public void setBenefits(Set<Benefit> benefits) { this.benefits = benefits; }} |
Сотрудник юридического лица.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
package com.gkatzioura.example.entity;import javax.persistence.*;/** * Created by gkatziourasemmanouil on 8/2/15. */@Entity@Table(name = "employee")public class Employee { @Id @GeneratedValue @Column(name = "employee_id") private Long id; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; @ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY) @JoinColumn(name = "company_id",referencedColumnName = "company_id") private Company company; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Company getCompany() { return company; } public void setCompany(Company company) { this.company = company; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; }} |
Выгода субъекта.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
package com.gkatzioura.example.entity;import javax.persistence.*;/** * Created by gkatziourasemmanouil on 8/9/15. */@Entity@Table(name = "benefit")public class Benefit { @Id @GeneratedValue @Column(name = "benefit_id") private Long id; @Column(name = "name") private String name; @ManyToOne @JoinColumn(name = "company_id") private Company company; public String getName() { return name; } public void setName(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Company getCompany() { return company; } public void setCompany(Company company) { this.company = company; }} |
Конфигурация гибернации
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
<?xml version='1.0' encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN"<hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">org.postgresql.Driver</property> <property name="connection.url">jdbc:postgresql://127.0.0.1:5432/example</property> <property name="connection.username">postgres</property> <property name="connection.password">postgres</property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">1</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.PostgreSQL9Dialect</property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thread</property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">update</property> <mapping class="com.gkatzioura.example.entity.Company"/> <mapping class="com.gkatzioura.example.entity.Employee"/> <mapping class="com.gkatzioura.example.entity.Benefit"/> </session-factory></hibernate-configuration> |
Основной класс, создающий фабрику сессий Hibernate
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
package com.gkatzioura.example;import com.gkatzioura.example.entity.Employee;import org.hibernate.Criteria;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.cfg.Configuration;import org.hibernate.criterion.Restrictions;import org.hibernate.sql.JoinType;import org.hibernate.type.StringType;import java.util.List;import org.slf4j.Logger;import org.slf4j.LoggerFactory;/** * Created by gkatziourasemmanouil on 7/12/15. */public class Main { private static SessionFactory sessionFactory; private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(SessionFactory.class); public static void main(String args[]) { sessionFactory = buildSessionFactory(); getByCompanyAndBenefit("TestCompany","gym"); sessionFactory.close(); } public static SessionFactory buildSessionFactory() { return new Configuration() .configure() .buildSessionFactory(); } } |
Предположим, что мы хотим получать сотрудников по названию компании и конкретному названию льготы, мы добавим функцию getByCompanyAndBenefit.
Название компании будет отфильтровано по обычному ограничению.
Однако имя выгоды будет отфильтровано sqlRestriction.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
|
private static List<Employee> getByCompanyAndBenefit(String companyName,String benefitName) { Session session = sessionFactory.openSession(); Criteria criteria = session.createCriteria(Employee.class,"employee"); Criteria companyCriteria = criteria.createCriteria("company",JoinType.INNER_JOIN); companyCriteria.add(Restrictions.eq("name", companyName)); Criteria benefitsAlias = companyCriteria.createCriteria("benefits",JoinType.LEFT_OUTER_JOIN); benefitsAlias.add(Restrictions.sqlRestriction("{alias}.name = ?",benefitName, StringType.INSTANCE)); List<Employee> employees = criteria.list(); for(Employee employee:employees) { LOGGER.error("The employee is "+employee.getFirstName()); } session.close(); return employees; } |
При использовании функции createCriteria критерия для отношения {псевдоним} представляет связанный объект новых критериев.
Это невозможно с классом критериев, полученным после использования createAlias.
Последний, но не менее важный файл.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
group 'com.gkatzioura.example'version '1.0-SNAPSHOT'apply plugin: 'application'apply plugin: 'java'apply plugin: 'idea'mainClassName = "com.gkatzioura.example.Main"sourceCompatibility = 1.8repositories { mavenLocal() mavenCentral()}dependencies { testCompile group: 'junit', name: 'junit', version: '4.11' compile 'org.ancoron.postgresql:org.postgresql.net:9.1.901.jdbc4.1-rc9' compile 'org.slf4j:slf4j-api:1.6.6' compile 'ch.qos.logback:logback-classic:1.0.13' compile 'org.hibernate:hibernate-core:4.3.6.Final' compile 'org.hibernate:hibernate-entitymanager:4.3.6.Final' compile 'org.hibernate:hibernate-validator:5.1.1.Final' compile 'dom4j:dom4j:1.6.1' compile 'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final' testCompile group: 'junit', name: 'junit', version:'3.8.1'} |
| Ссылка: | Hibernate: используйте псевдоним таблицы соединений на sqlRestriction от нашего партнера по JCG Эммануила Гкациоураса в блоге gkatzioura . |