Запрос Java Hibernate
1. Введение
Данная статья является ссылкой для некоторых вопросов связанных с Hibernate. Чтобы легче понять, вам стоит просмотреть статью:
2. Скачать библиотеки управляющие некоторые виды баз данных
Когда вы работаете с определенной базой данных, вам нужна библиотека, чтобы управлять этим видом базы данных.
- Oracle
- MySQL
- SQLServer
- HSQL
- ....
Смотрите так же:
Мы получаем результат:
3. Конфигурация Hibernate на разных видах баз данных.
Конфигурация Hibernate для Oracle.
Сперва вам нужно объявить библиотеки управляющие базой данных Oracle (Руководство выше).
Конфигурация Hibernate:
hibernate.cfg.xml (Oracle)
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:db11g</property>
<property name="connection.username">simplehr</property>
<property name="connection.password">1234</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">2</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</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.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="hibernate.hbm2ddl.auto">create-drop</property>
<mapping class="org.o7planning.tutorial.hibernate.entities.Department" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Employee" />
<mapping class="org.o7planning.tutorial.hibernate.entities.SalaryGrade" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Timekeeper" />
</session-factory>
</hibernate-configuration>
Конфигурация Hibernate для MySQL
Для начала вам нужно объявить библиотеки упраляющие базой данных MySQL (Руководство выше).
Конфигурация Hibernate
hibernate.cfg.xml (MySQL)
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://tran-vmware:3306/simplehr</property>
<property name="connection.username">root</property>
<property name="connection.password">1234</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</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.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping class="org.o7planning.tutorial.hibernate.entities.Department" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Employee" />
<mapping class="org.o7planning.tutorial.hibernate.entities.SalaryGrade" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Timekeeper" />
</session-factory>
</hibernate-configuration>
Конфигурация Hibernate для SQL Server
Для начала, вам нужно объявить библиотеку, которая управляет базой данных SQLServer (Руководство выше).
Конфигурация Hibernate (Используя библиотеку JTDS)
hibernate.cfg.xml (SQL Server)
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
<property name="connection.url">jdbc:jtds:sqlserver://localhost:1433/simplehr;instance=SQLEXPRESS</property>
<property name="connection.username">sa</property>
<property name="connection.password">1234</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.SQLServerDialect</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.internal.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping class="org.o7planning.tutorial.hibernate.entities.Department" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Employee" />
<mapping class="org.o7planning.tutorial.hibernate.entities.SalaryGrade" />
<mapping class="org.o7planning.tutorial.hibernate.entities.Timekeeper" />
</session-factory>
</hibernate-configuration>
4. Hibernate & Java Persistence Annotation
Hibernate использует Annotation чтобы описать информацию для Entity. Он может использовать annotation в API у hibernate расположенный в пакете org.hibernate.annotations. Или использовать Annotation расположенные в пакете javax.persistence у Java Persistence API. На самом деле все Annotation в Java Persistence API являются больше всего предпочитаемыми.
В этой части я перечислю все самые распространенные Annotation в Java Persistence API которые принимают участие в аннотации для Entity.
В этой части я перечислю все самые распространенные Annotation в Java Persistence API которые принимают участие в аннотации для Entity.
@Entity
@Entity используемый для аннотации класса является Entity.
// Phần tử (element) name của @Entity là không bắt buộc.
// Việc chỉ định rõ name của @Entity cho phép viết ngắn câu HSQL
@Entity
@Table(name = "ACCOUNT")
public class Account implements Serializable {
}
// Phần tử (element) name của @Entity là không bắt buộc.
// Entity khớp với một bảng lấy theo tên theo thứ tự ưu tiên:
// 1 - name trong @Table
// 2 - name trong @Entity
// 3 - name của class.
// Việc chỉ định rõ name của @Entity cho phép viết ngắn câu HSQL
@Entity(name="AccTransaction")
@Table(name = "ACC_TRANSACTION")
public class AccTransaction implements Serializable {
}
Ясное определение элемента name у @Entity помогает вам укоротить команду HSQL. Смотрите иллюстрированный пример:
// @Entity chú thích trên class Account không chỉ định rõ phần tử name.
// Vì vậy câu HSQL bắt buộc phải viết:
String hsql1 = "Select o from "+ Account.class.getName() +" o ";
// @Entity chú thích trên class AccTransaction
// chỉ định rõ phần tử name = "AccTransaction"
// Vì vậy câu HSQL có thể viết ngắn gọn:
String hsql2 = "Select o from AccTransaction o";
@Table
Table в базе данных может иметь много уникальных ограничений. @Table так же позволяет вам аннотировать это.
// @Table cho phép chú thích tên bảng
// Các giàng buộc duy nhất trong bảng.
// Phần tử name không bắt buộc.
// Nếu bạn không chỉ rõ tên bảng trong phần tử name ...
// .. Hibernate sẽ dựa vào phần tử name của @Entity sau đó mới
// tới tên của class.
@Table( name = "invoice_header",
uniqueConstraints = @UniqueConstraint(columnNames ={ "invoice_num" } )
)
@Entity
public class InvoiceHeader implements java.io.Serializable {
private String invoiceNum;
@Column(name = "invoice_num", nullable = false, length = 20)
public String getInvoiceNum() {
return this.invoiceNum;
}
}
@Id
Например @Id участвует в аннотации ID (Identity) в Entity, соответствует с пониманием, что этот столбец и есть главный ключ таблицы (Primary Key).
@Entity
@Table(name = "EMPLOYEE")
public class Employee implements Serializable {
private Integer empId;
// @Id chú thích đây là id của Entity.
// Và EMP_ID chính là khóa chính (Primary Key) của bảng.
@Id
@GeneratedValue
@Column(name = "EMP_ID")
public Integer getEmpId() {
return empId;
}
......
}
@GeneratedValue
@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeneratedValue {
// GenerationType: AUTO, TABLE, SEQUENCE, IDENTITY
GenerationType strategy() default AUTO;
String generator() default "";
}
@GeneratedValue аннотирован чтобы Hibernate автоматически генерировал значение и прикреплял его в столбец в случае insert (вставления) нового Entity в базу данных. Оно может быть прикреплено к столбцу ID или к другому определенному столбцу.
Иногда он также аннотирован с @Generator
Иногда он также аннотирован с @Generator
@Column
@Column аннотирует одному столбцу, включая информацию длины столбца, позволяя null или нет
// Đây là một cột kiểu chuỗi, vì thế length luôn có ý nghĩa và cần thiết
// nullable mặc định là true
// length mặc định là 255
@Column(name = "FIRST_NAME", length = 20, nullable = false)
public String getFirstName() {
return firstName;
}
// @Column không chỉ rõ phần tử length, mặc định nó là 255.
@Column(name = "DESCRIPTION", nullable = true )
public String getDescription() {
return firstName;
}
// Với các cột kiểu số hoặc Date bạn có thể bỏ qua length
// (Nó không có ý nghĩa trong trường hợp này).
@Column(name = "PENDING_BALANCE")
public Float getPendingBalance() {
return pendingBalance;
}
@Lob
@Lob обычно аннотируется с @Column чтобы сказать что этот столбец является видом BLOB или CLOB.
// Chú ý rằng trong một số Database có phân biệt TINY, MEDIUM, LARGE BLOB/CLOB.
// Còn một số database thì không.
// Phần tử length trong @Column trong trường hợp này sẽ quyết định nó map
// vào BLOB/CLOB nào.
// Trong trường hợp cho phép BLOB/CLOB tối đa hãy để length = Integer.MAX_VALUE
// Method này trả về byte[]
// @Lob trong trường hợp này chú thích cho cột BLOB
@Lob
@Column(name = "IMAGE_VALUE", nullable = true, length = Integer.MAX_VALUE)
public byte[] getImageValue() {
this.imageValue;
}
// Method này trả về String
// @Lob trong trường hợp này sẽ chú thích cho CLOB.
@Lob
@Column(name = "ARTICLE_CONTENT", nullable = true, length = Integer.MAX_VALUE)
public String getArticleContent() {
this.articleContent;
}
@Temporal
@Temporal используется для аннотации столбца даты и времени (date time).
// @Temporal sử dụng chú thích cho cột có kiểu dữ liệu ngày tháng.
// Có 3 giá trị cho TemporalType:
// 1 - TemporalType.DATE
// 2 - TemporalType.TIME
// 3 - TemporalType.TIMESTAMP
@Temporal(TemporalType.DATE)
@Column(name = "START_DATE", nullable = false)
public java.util.Date getStartDate() {
return startDate;
}
// TemporalType.DATE chú thích cột sẽ lưu trữ ngày tháng năm (bỏ đi thời gian)
// TemporalType.TIME chú thích cột sẽ lưu trữ thời gian (Giờ phút giây)
// TemporalType.TIMESTAMP chú thích cột sẽ lưu trữ ngày tháng và cả thời gian
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "FUNDS_AVAIL_DATE", nullable = false)
public java.util.Date getFundsAvailDate() {
return fundsAvailDate;
}
@ManyToOne
@ManyToOne описывает отношение N-1 (Много - один), обычно используется вместе с @JoinColumn.
@Entity
@Table(name = "ACCOUNT")
public class Account implements Serializable {
private Branch openBranch;
// Phần tử foreignKey giúp chỉ rõ tên Foreign Key trong DB.
// Điều này sẽ giúp Hibernate tạo ra DB từ các Entity java một cách chính xác hơn.
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "OPEN_BRANCH_ID", nullable = false,
foreignKey = @ForeignKey(name = "ACCOUNT_BRANCH_FK"))
public Branch getOpenBranch() {
return openBranch;
}
}
Hibernate имеет инструменты, которые позволяют вам генерировать классы Entity из таблиц в базе данных. И Hibernate так же позволяет вам генерировать таблицу из Entity, включая ограничения между таблицами (Foreign Key). Аннотация @ForeignKey позволяет определить имя Foreign Key который будет создан.
@ForeignKey введен в JPA с версии 2.1
// Phần tử fetch có 2 giá trị
// 1 - FetchType.LAZY
// 2 - FetchType.EAGER
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "OPEN_BRANCH_ID", nullable = false,
foreignKey = @ForeignKey(name = "ACCOUNT_BRANCH_FK"))
public Branch getOpenBranch() {
return openBranch;
}
LAZY:
LAZY говорит Hibernate, что вы можете скачать данные "ленивым" способом.
Например у вас есть объект Account, и вызывая метод getOpenBranch() он возвращает объект Branch, в объекте Branch только к полю (field) branchId прикреплено значение, а к другим полям нет.
На самом деле hibernate еще не скачивает данные из соответствующих записей таблицы BRANCH в этот объект. Он только выполняет запрос данных когда вы что-то делаете с объектом только что полученным Branch, например вызвать метод branch.getName().
На самом деле hibernate еще не скачивает данные из соответствующих записей таблицы BRANCH в этот объект. Он только выполняет запрос данных когда вы что-то делаете с объектом только что полученным Branch, например вызвать метод branch.getName().
EAGER:
EAGER говорит Hibernate сделать запрос всех связанных столбцов.
Например у вас есть объект Account, и вызываете метод getOpenBranch() возвращает Branch с готовыми значениями для полей (name, address, ...). На самом деле его данные получены в одном запросе с таблицей Account.
Вам стоит использовать LAZY вместо EAGER из-за производительности программы .
@OneToMany
@OneToMany это способ аннотации чтобы получить список дочерних записей настоящей записи (Это отношение один к многим). Является обратным @ManyToOne, поэтому основывается на аннотацию @ManyToOne чтобы определить @OneToMany.
@Entity
@Table(name = "EMPLOYEE")
public class Employee implements Serializable {
....
private Department department;
// Quan hệ N-1 (Nhiều - Một) định nghĩa department.
@JoinColumn(name = "DEPT_ID", nullable = true,
foreignKey = @ForeignKey(name = "EMPLOYEE_DEPARTMENT_FK"))
@ManyToOne(fetch = FetchType.LAZY)
public Department getDepartment() {
return department;
}
}
@Entity
@Table(name = "DEPARTMENT")
public class Department implements Serializable {
.....
private Set<Employee> employees = new HashSet<Employee>(0);
// Quan hệ 1-N (Một - Nhiều) sử dụng mappedBy = "department"
// đã định nghĩa ở quan hệ N-1 (phía trên).
@OneToMany(fetch = FetchType.LAZY, mappedBy = "department")
public Set<Employee> getEmployees() {
return employees;
}
}
@OrderBy
@OrderBy используется для организации коллекции, поэтому он используется вместе с @OneToMany:
@Entity
@Table(name = "DEPARTMENT")
public class Department implements Serializable {
.....
private Set<Employee> employees = new HashSet<Employee>(0);
// Mặc định @OrderBy("empNo") tương đương với @OrderBy("empNo asc").
// Nó tạo ra câu SQL: Select ... from Employee ... order by EMP_NO desc
@OrderBy("empNo desc")
@OneToMany(fetch = FetchType.LAZY, mappedBy = "department")
public Set<Employee> getEmployees() {
return employees;
}
}
@Transient
Рассмотрим ситуацию:
@Entity
@Table(name="Employee")
public class Employee implements Serializable {
.....
@Column(name="FIRST_NAME", nullable =false , length = 20 )
public String getFirstName() {
return this.firstName;
}
@Column(name="LAST_NAME", nullable =false , length = 20)
public String getLastName() {
return this.lastName;
}
public String getFullName() {
return this.firstName+ " "+ this.lastName;
}
}
Вы хотите написать метод getFullName(), этот метод просто является расчетом, не имеет отношения ни к каким столбцам ниже DB. Поэтому вам необходимо использовать @Transient чтобы объявить ваше намерение с Hibernate.
@Transient
public String getFullName() {
return this.firstName+ " " + this.lastName;
}
@Transient
public boolean isManagerEmployee() {
return this.manager != null;
}
@Inheritance
Руководства Java Hibernate
- Запрос Java Hibernate
- Установите JBoss Tools для Eclipse
- Используйте инструменты Hibernate для создания классов Entity из таблиц
- Создание таблиц из классов Entity в Hibernate
- Разбиение по страницам (Pagination) в Java Hibernate
- Руководство Java Hibernate для начинающих
Show More