在 2 Hibernate:入門簡介 中介紹了 hibernate 開發步驟:java
(1) 導入 Hibernate 庫文件及開發所用數據庫的驅動文件mysql
(2) 建立 Hibernate 配置文件:hibernate.cfg.xmlsql
(3) 建立持久化類數據庫
(4) 建立對象-關係映射文件:*.hbm.xmlapache
(5) 將對象-關係映射文件加入 Hibernate 配置文件緩存
(6) 經過 Hibernate API 編寫訪問數據庫的代碼session
若是在步驟(3)建立持久化類中使用註解,則步驟(4)和(5)能夠省略。如下展現使用註解的Hibernate完整開發步驟:app
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>lesson</groupId> <artifactId>hibernate</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.2.10.Final</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency> </dependencies> </project>
hibernate.cfg.xml
具體步驟能夠參看 2 Hibernate:入門簡介,如下是配置文件內容:less
<?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> <!-- 數據庫鏈接設置 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.password">123456</property> <property name="connection.url">jdbc:mysql://localhost:3306/test</property> <property name="connection.username">root</property> <!-- Hibernate內置的JDBC鏈接池,由於缺乏某些關鍵特性,只用於學習和演示,不建議商用 --> <property name="connection.pool_size">1</property> <!-- SQL方言 --> <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- 禁用二級緩存 --> <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> <!-- 將已執行SQL打印到輸出 --> <property name="show_sql">true</property> <!-- 格式化打印的SQL,不然所有顯示在一行中 --> <property name="format_sql">true</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">create</property> </session-factory> </hibernate-configuration>
package hibernate; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name = "person") public class Person { private int id; private String account; private String name; private Date birth; public Person() {} public Person(String account, String name, Date birth) { this.account = account; this.name = name; this.birth = birth; } @Id // 實體惟一標識 @GeneratedValue(generator = "increment") // 使用名爲「increment」的生成器 @GenericGenerator(name = "increment", strategy = "increment") // 定義名爲「increment」的生成器,使用Hibernate的"increment"生成策略,即自增 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getAccount() { return account; } public void setAccount(String account) { this.account = account; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Temporal(TemporalType.TIMESTAMP) @Column(name = "birth_date") public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } @Override public String toString() { return "Person [id=" + id + ", account=" + account + ", name=" + name + ", birth=" + birth + "]"; } }
註解說明:maven
@Entity 標識當前類爲實體類,使用默認 ORM 規則,即類名映射數據庫中對應的表名,屬性名映射數據表中列名。
@Table 若是類名和數據表名不一致,使用 @Table(name = "數據表名") 標識當前類對應的數據表名。
@Id 當前實體類的惟一性標識,一般映射到數據表主鍵。
@GeneratedValue 實體類惟一標識生成規則(後續會專門撰文進行詳細說明)
@GenericGenerator 惟一標識生成器(後續會專門撰文進行詳細說明)
@Temporal 限制時間格式。 TemporalType.DATE -- 只記錄日期,不記錄時間 TemporalType.TIME -- 只記錄時間,不記錄日期 TemporalType.TIMESTAMP -- 日期時間都記錄(默認)
@Column 若是當前類中屬性名與對應數據表中的列名不一致,使用 @Column(name = "數據表列名") 標識此屬性對應的數據表列名,此外能夠使用 @Column(length = 30) 限制字符串長度。
@Transient 標識當前屬性不映射任何數據表列。
這裏只使用了部分註解,更多註解及詳細說明後續補充。
hibernate.cfg.xml
<?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> <!-- 數據庫鏈接設置 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="connection.password">123456</property> <property name="connection.url">jdbc:mysql://localhost:3306/test</property> <property name="connection.username">root</property> <!-- Hibernate內置的JDBC鏈接池,由於缺乏某些關鍵特性,只用於學習和演示,不建議商用 --> <property name="connection.pool_size">1</property> <!-- SQL方言 --> <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> <!-- 禁用二級緩存 --> <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> <!-- 將已執行SQL打印到輸出 --> <property name="show_sql">true</property> <!-- 格式化打印的SQL,不然所有顯示在一行中 --> <property name="format_sql">true</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">create</property> <!-- 使用註解的實體類映射 --> <mapping class="hibernate.Person"/> </session-factory> </hibernate-configuration>
沿用 3 Hibernate:本地 API 單元測試優化 中代碼進行測試演示
package hibernate; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.List; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; import org.junit.After; import org.junit.Before; import org.junit.Test; public class NativeApiIllustrationTest { private SessionFactory sessionFactory; @Before public void setUp() throws Exception { final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build(); try { sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory(); } catch (Exception e) { // 若是構建SessionFactory出現異常,須要手動銷燬StandardServiceRegistry StandardServiceRegistryBuilder.destroy(registry); } } @After public void tearDown() throws Exception { if (null != sessionFactory) { sessionFactory.close(); } } @Test public void test() throws ParseException { Session session = sessionFactory.openSession(); session.beginTransaction(); session.save(new Person("tom", "Tommy", new SimpleDateFormat("yyyy-MM-dd").parse("1985-01-01"))); session.save(new Person("mix", "Mercy", new SimpleDateFormat("yyyy-MM-dd").parse("1990-10-01"))); session.getTransaction().commit(); session.close(); session = sessionFactory.openSession(); session.beginTransaction(); @SuppressWarnings("unchecked") List<Person> result = session.createQuery(" FROM Person").list(); for (Person person : result) { System.out.println(person); } session.getTransaction().commit(); session.close(); } }
單元測試日誌:
六月 25, 2017 9:18:09 上午 org.hibernate.Version logVersion INFO: HHH000412: Hibernate Core {5.2.10.Final} 六月 25, 2017 9:18:09 上午 org.hibernate.cfg.Environment <clinit> INFO: HHH000206: hibernate.properties not found 六月 25, 2017 9:18:09 上午 org.hibernate.annotations.common.reflection.java.JavaReflectionManager <clinit> INFO: HCANN000001: Hibernate Commons Annotations {5.0.1.Final} 六月 25, 2017 9:18:10 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure WARN: HHH10001002: Using Hibernate built-in connection pool (not for production use!) 六月 25, 2017 9:18:10 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001005: using driver [com.mysql.jdbc.Driver] at URL [jdbc:mysql://localhost:3306/test] 六月 25, 2017 9:18:10 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001001: Connection properties: {user=root, password=****} 六月 25, 2017 9:18:10 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001003: Autocommit mode: false 六月 25, 2017 9:18:10 上午 org.hibernate.engine.jdbc.connections.internal.PooledConnections <init> INFO: HHH000115: Hibernate connection pool size: 1 (min=1) Sun Jun 25 09:18:10 CST 2017 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification. 六月 25, 2017 9:18:10 上午 org.hibernate.dialect.Dialect <init> INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect Hibernate: drop table if exists person 六月 25, 2017 9:18:12 上午 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@42463763] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode. Hibernate: create table person ( id integer not null, account varchar(255), birth_date datetime, name varchar(255), primary key (id) ) engine=MyISAM 六月 25, 2017 9:18:12 上午 org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@fc258b1] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode. 六月 25, 2017 9:18:12 上午 org.hibernate.tool.schema.internal.SchemaCreatorImpl applyImportSources INFO: HHH000476: Executing import script 'org.hibernate.tool.schema.internal.exec.ScriptSourceInputNonExistentImpl@acdb094' Hibernate: select max(id) from person Hibernate: insert into person (account, birth_date, name, id) values (?, ?, ?, ?) Hibernate: insert into person (account, birth_date, name, id) values (?, ?, ?, ?) 六月 25, 2017 9:18:12 上午 org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService INFO: HHH000397: Using ASTQueryTranslatorFactory Hibernate: select person0_.id as id1_0_, person0_.account as account2_0_, person0_.birth_date as birth_da3_0_, person0_.name as name4_0_ from person person0_ Person [id=1, account=tom, name=Tommy, birth=1985-01-01 00:00:00.0] Person [id=2, account=mix, name=Mercy, birth=1990-10-01 00:00:00.0] 六月 25, 2017 9:18:13 上午 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl stop INFO: HHH10001008: Cleaning up connection pool [jdbc:mysql://localhost:3306/test]
Hibernate 生成的數據表 person 結構: