Hibernate用來操做數據庫,它對開發人員隱藏了底層JDBC的操做及不一樣數據庫的差別,經過它,開發人員基本上只用關心本身的對象就能夠了java
構建一個最基本的Hibernate應用須要四個部分:mysql
1.數據類。數據類同數據庫的表存在對應關係,使用Hibernate操做數據類時,Hibernate會將之轉換爲對數據庫中對應表的操做;sql
2.ORM配置文件,用於配置數據類及數據庫中表的對應關係;數據庫
3.Hibernate配置文件,用於配置JDBC數據源、ORM配置文件路徑等信息;session
4.程序啓動類,用於加載Hibernate並啓動整個應用;數據結構
以一個基於maven的項目爲例,其項目結構示例以下,該項目將建立一個電影表用來管理電影數據app
首先,在pom.xml中配置Hibernate相關的依賴maven
1 <dependencies> 2 <!-- Hibernate依賴 --> 3 <dependency> 4 <groupId>org.hibernate</groupId> 5 <artifactId>hibernate-core</artifactId> 6 <version>5.2.11.Final</version> 7 </dependency> 8 9 <!-- JDBC驅動的依賴,不使用mysql換成對應的驅動 --> 10 <dependency> 11 <groupId>mysql</groupId> 12 <artifactId>mysql-connector-java</artifactId> 13 <version>8.0.8-dmr</version> 14 </dependency> 15 </dependencies> 16 17 <build> 18 <resources> 19 <resource> 20 <directory>${basedir}/src/main/resources</directory> 21 </resource> 22 <!-- 因爲ORM配置文件放在src/main/java目錄下,maven默認不會將該目錄下非java文件打包,還需作該配置 --> 23 <resource> 24 <directory>${basedir}/src/main/java</directory> 25 <includes> 26 <include>**/*.hbm.xml</include> 27 </includes> 28 </resource> 29 </resources> 30 </build>
其次,編寫數據類Movie.java,其內包含ID、電影名稱及描述信息ide
1 package study.hibernate.model; 2 3 /** 4 * 電影數據類 5 * @author yaoyao 6 * 7 */ 8 public class Movie { 9 private int id; 10 11 private String name; 12 13 private String description; 14 15 public int getId() { 16 return id; 17 } 18 19 public void setId(int id) { 20 this.id = id; 21 } 22 23 public String getName() { 24 return name; 25 } 26 27 public void setName(String name) { 28 this.name = name; 29 } 30 31 public String getDescription() { 32 return description; 33 } 34 35 public void setDescription(String description) { 36 this.description = description; 37 } 38 39 }
接着,編寫ORM配置文件Movie.hbm.xml,用於告訴Hibernate,該數據類同數據庫中哪一個表對應,該表的數據結構是什麼樣的學習
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="study.hibernate.model"> <!-- 此處配置的class name與上面的package合併獲得完整的類名 --> <class name="Movie" table="Movie"> <!-- MOVIE_ID列做爲MOVIE表的主鍵,同Movie類的id屬性關聯 --> <id name="id" column="MOVIE_ID" /> <!-- string類型對應的數據庫類型爲VARCHAR(255),能夠存儲255個字符 --> <property name="name" type="string" column="NAME" /> <!-- desc屬性比較長,字段類型需設置爲text,最多能夠存儲2^32 - 1個字符 --> <property name="description" type="text" column="DESCRIPTION" /> </class> </hibernate-mapping>
接下來,編寫Hibernate配置文件,配置JDBC、ORM配置文件 路徑等相關信息
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 5 6 <hibernate-configuration> 7 <session-factory> 8 <!-- 數據庫JDBC配置 --> 9 <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property> 10 <property name="connection.url">jdbc:mysql://localhost:3306/MOVIE_DB?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8</property> 11 <property name="connection.username">root</property> 12 <property name="connection.password">root</property> 13 14 <!-- JDBC數據庫鏈接池大小 --> 15 <property name="connection.pool_size">10</property> 16 17 <!-- SQL dialect --> 18 <!-- <property name="dialect">org.hibernate.dialect.H2Dialect</property> --> 19 <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> 20 21 <!-- Disable the second-level cache --> 22 <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> 23 24 <!-- Echo all executed SQL to stdout --> 25 <property name="show_sql">true</property> 26 27 <!-- 每次啓動的時候,會把表先刪除從新建立 --> 28 <property name="hbm2ddl.auto">create</property> 29 30 <!-- 數據類和表關聯關係文件存放路徑,Hibernate會在整個classpath下查找該文件 --> 31 <mapping resource="study/hibernate/model/Movie.hbm.xml"/> 32 33 </session-factory>
最後,編寫程序啓動類Launcher.java,加載Hibernate並啓動應用程序
1 package study.hibernate; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.hibernate.boot.MetadataSources; 6 import org.hibernate.boot.registry.StandardServiceRegistry; 7 import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 8 9 import study.hibernate.model.Movie; 10 11 public class Launcher { 12 public static void main(String[] args) { 13 StandardServiceRegistry registry = new StandardServiceRegistryBuilder() 14 .configure() 15 .build(); 16 SessionFactory sessionFactory = null; 17 Session session = null; 18 try { 19 sessionFactory = new MetadataSources( registry ).buildMetadata().buildSessionFactory(); 20 session = sessionFactory.openSession(); 21 22 Movie movie = new Movie(); 23 movie.setId(1); 24 movie.setName("速度與激情8"); 25 movie.setDescription("多米尼克(範·迪塞爾 Vin Diesel 飾)與萊蒂(米歇爾·羅德里格茲 Michelle Rodriguez 飾)共度蜜月,布萊恩與米婭退出了賽車界,這支曾環遊世界的頂級飛車家族隊伍的生活正漸趨平淡。然而,一位神祕女子Cipher(查理茲·塞隆 Charlize T heron 飾)的出現,令整個隊伍捲入信任與背叛的危機,面臨史無前例的考驗。"); 26 27 session.beginTransaction(); 28 session.save(movie); 29 session.getTransaction().commit(); 30 } catch (Exception e) { 31 e.printStackTrace(); 32 } finally { 33 if (session != null) { 34 session.close(); 35 } 36 37 if(sessionFactory != null) { 38 sessionFactory.close(); 39 } 40 } 41 } 42 }
運行程序,並查看數據,發現數據庫中已經建立了movie表而且其內已經插入了一條數據
mysql> use MOVIE_DB; Database changed mysql> select name from Movie; +------------------+ | name | +------------------+ | 速度與激情8 | +------------------+ 1 row in set (0.00 sec) mysql>
學習過程當中遇到的一些問題:
1.MYSQL使用的是5.7版本,而JDBC使用的最新的8.0.8版本,啓動的時候提示時區信息不可識別
Caused by: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support. at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:121) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:81) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:55) at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:65) at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:70) at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:853) at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:440) at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:241) at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:221) at org.hibernate.engine.jdbc.connections.internal.DriverConnectionCreator.makeConnection(DriverConnectionCreator.java:38) ... 28 more
該問題在hibrnate.cfg.xml中指定時區(GMT+8,其中+需用%2B轉義)信息便可:jdbc:mysql://localhost:3306/MOVIE_DB?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
2.Hibernae官方基礎示例中配置的方言爲org.hibernate.dialect.H2Dialect,需更改成正確的方言配置org.hibernate.dialect.MySQL5Dialect,不然會提示DDL語句執行失敗
WARN: GenerationTarget encountered exception accepting command : Error executing DDL via JDBC Statement org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL via JDBC Statement at org.hibernate.tool.schema.internal.exec.GenerationTargetToDatabase.accept(GenerationTargetToDatabase.java:67) at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlString(SchemaCreatorImpl.java:440) at org.hibernate.tool.schema.internal.SchemaCreatorImpl.applySqlStrings(SchemaCreatorImpl.java:424) at org.hibernate.tool.schema.internal.SchemaCreatorImpl.createFromMetadata(SchemaCreatorImpl.java:315) at org.hibernate.tool.schema.internal.SchemaCreatorImpl.performCreation(SchemaCreatorImpl.java:166) at org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:135) at org.hibernate.tool.schema.internal.SchemaCreatorImpl.doCreation(SchemaCreatorImpl.java:121) at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:155) at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:72) at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:313) at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:452) at org.hibernate.boot.internal.MetadataImpl.buildSessionFactory(MetadataImpl.java:170) at study.hibernate.Launcher.main(Launcher.java:19)
3.Hibernate.cfg.xml中的<property name="hbm2ddl.auto">create</property>配置只會自動創表,不會幫忙把schemal一塊兒建立出來,所以程序運行前必須手動建立:create database MOVIE_DB;