首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

SSH 框架整合實戰:用 JPA (Hibernate 實現) 替代傳統 Hibernate XML 配置

     編輯:Java 綜合教學

為什麼選擇 JPA?

  • 標準化:JPA 是 Java EE 標準規範,代碼可移植,不綁定具體 ORM 實現。
  • 注解驅動:實體映射從繁瑣的 .hbm.xml 遷移到 Java 類注解,開發體驗大幅提升。
  • 靈活切換:底層可無縫切換 Hibernate、EclipseLink、OpenJPA 等實現。

整合步驟詳解

1. 添加 Maven 依賴

<dependencies>
    <!-- JPA API -->
    <dependency>
        <groupId>javax.persistence</groupId>
        <artifactId>javax.persistence-api</artifactId>
        <version>2.2</version>
    </dependency>
    <!-- Hibernate 作為 JPA Provider -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.4.32.Final</version>
    </dependency>
    <!-- 數據庫驅動 & C3P0 連接池 -->
    <dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
        <version>9.4.0.jre11</version>
    </dependency>
    <dependency>
        <groupId>com.mchange</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.5.5</version>
    </dependency>
</dependencies>

2. 配置 persistence.xml(核心配置文件)

位置:src/main/resources/META-INF/persistence.xml(目錄名必須為 META-INF,大小寫敏感)。

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="https://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="https://xmlns.jcp.org/xml/ns/persistence
                                 https://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">

    <persistence-unit name="myJpa" transaction-type="RESOURCE_LOCAL">
        <!-- 指定 JPA Provider -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <!-- 實體類掃描(或用  逐個列出) -->
        <class>entity.BookCard</class>

        <properties>
            <!-- 數據庫方言 -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.SQLServer2008Dialect"/>
            <!-- 連接信息(或引用 JNDI DataSource) -->
            <property name="hibernate.connection.driver_class" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
            <property name="hibernate.connection.url" value="jdbc:sqlserver://localhost:1433;DatabaseName=webLastExam_20160727"/>
            <property name="hibernate.connection.username" value="sa"/>
            <property name="hibernate.connection.password" value="123456"/>

            <!-- 連接池 (C3P0) -->
            <property name="hibernate.c3p0.min_size" value="5"/>
            <property name="hibernate.c3p0.max_size" value="20"/>
            <property name="hibernate.c3p0.timeout" value="300"/>
            <property name="hibernate.c3p0.max_statements" value="50"/>

            <!-- SQL 輸出與 DDL 自動更新 -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

3. 實體類注解映射

package entity;

import javax.persistence.*;

@Entity
@Table(name = "BookCard")
public class BookCard implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY) // 或使用 Hibernate 擴展策略
    @GenericGenerator(name = "uuid", strategy = "uuid2") // Hibernate 擴展
    private Long id;

    @Column(name = "card_name", nullable = false, length = 50)
    private String name;

    // Getter/Setter/toString 省略
}

關鍵注解對照:

JPA 注解Hibernate XML 對應說明
@Entity<class name=...>聲明實體
@Table(name="...")<class table=...>指定表名
@Id<id>主鍵
@GeneratedValue<generator class=...>主鍵生成策略
@Column<property column=...>列屬性
@OneToMany / @ManyToOne<set> / <many-to-one>關聯映射

4. DAO 層使用 EntityManager

package dao.impl;

import dao.BookCardDao;
import entity.BookCard;
import javax.persistence.*;
import java.util.List;

public class BookCardDaoImpl implements BookCardDao {
    // 線程安全,可作為單例注入
    private EntityManagerFactory emf = Persistence.createEntityManagerFactory("myJpa");

    @Override
    public List findAll() {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            // JPQL 查詢,面向對象而非表
            List list = em.createQuery("SELECT b FROM BookCard b", BookCard.class).getResultList();
            tx.commit();
            return list;
        } catch (Exception e) {
            if (tx.isActive()) tx.rollback();
            throw new RuntimeException("查詢失敗", e);
        } finally {
            em.close(); // 必須關閉,歸還連接
        }
    }

    @Override
    public void save(BookCard bookCard) {
        EntityManager em = emf.createEntityManager();
        EntityTransaction tx = em.getTransaction();
        try {
            tx.begin();
            em.persist(bookCard);
            tx.commit();
        } catch (Exception e) {
            if (tx.isActive()) tx.rollback();
            throw new RuntimeException("保存失敗", e);
        } finally {
            em.close();
        }
    }
}

5. Spring 整合(可選,推薦)

在 Spring 中配置 LocalContainerEntityManagerFactoryBean 與 JpaTransactionManager,實現 @PersistenceContext 注入 EntityManager、@Transactional 聲明式事務,進一步簡化 DAO 代碼。

核心概念對照表

Hibernate 原生JPA (Hibernate 實現)說明
SessionFactoryEntityManagerFactory重量級、線程安全、對應持久化單元
SessionEntityManager輕量級、非線程安全、請求級別
TransactionEntityTransaction資源本地事務
HQLJPQL面向對象查詢語言,語法幾乎一致
Criteria APICriteriaBuilder類型安全查詢構建

避坑指南

  • persistence.xml 必須放在 META-INF/ 目錄下,否則無法被識別。
  • 實體類必須有**無參構造函數**(public/protected),否則 Provider 無法實例化。
  • EntityManager **非線程安全**,切勿作為類字段共享,請求級創建、用完即關閉。
  • 使用 hibernate.hbm2ddl.auto=update 僅限開發環境,生產環境請用 Flyway/Liquibase 管理遷移腳本。
  • 若需使用 Hibernate 特有功能(如 @GenericGenerator、@Formula),可直接引入 org.hibernate.annotations 包,不影響 JPA 標準性。

完成上述整合後,你將擁有一套標準化、可測試、易維護的持久化層。JPA 不僅是 Hibernate 的「標準外衣」,更是通往領域驅動設計(DDD)與微服務架構的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved