1. 程式人生 > >Hibernate學習筆記(一) --- 使用Hibernate連接數據庫

Hibernate學習筆記(一) --- 使用Hibernate連接數據庫

比較 得到 對象 urn stack close logs mysql .org

Hibernate用來操作數據庫,它對開發人員隱藏了底層JDBC的操作及不同數據庫的差異,通過它,開發人員基本上只用關心自己的對象就可以了

構建一個最基本的Hibernate應用需要四個部分:

  1.數據類。數據類同數據庫的表存在對應關系,使用Hibernate操作數據類時,Hibernate會將之轉換為對數據庫中對應表的操作;

  2.ORM配置文件,用於配置數據類及數據庫中表的對應關系;

3.Hibernate配置文件,用於配置JDBC數據源、ORM配置文件路徑等信息;

  4.程序啟動類,用於加載Hibernate並啟動整個應用;

 以一個基於maven的項目為例,其項目結構示例如下,該項目將創建一個電影表用來管理電影數據

          技術分享

首先,在pom.xml中配置Hibernate相關的依賴

 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、電影名稱及描述信息

 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&amp;useUnicode=true&amp;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 ?D1ú±ê×?ê±?? 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&amp;useUnicode=true&amp;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;

Hibernate學習筆記(一) --- 使用Hibernate連接數據庫