Java高手速成 | Spring、JPA与Hibernate的整合

简介: Spring、JPA与Hibernate的整合

image.png

01、设置Spring的配置文件

在Spring的配置文件applicationContext.xml中,配置C3P0数据源、EntityManagerFactory和JpaTransactionManager等Bean组件。以下是applicationContext.xml文件的源程序。

/* applicationContext.xml */
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=…>
 
  <!-- 配置属性文件的文件路径 -->
  <context:property-placeholder 
       location="classpath:jdbc.properties"/>
 
  <!-- 配置C3P0数据库连接池 -->
  <bean id="dataSource" 
     class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="driverClass" value="${jdbc.driver.class}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
  </bean>
 
  <!-- Spring 整合 JPA,配置 EntityManagerFactory-->
  <bean id="entityManagerFactory"
      class="org.springframework.orm.jpa
             .LocalContainerEntityManagerFactoryBean">
     <property name="dataSource" ref="dataSource"/>
 
     <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor
            .HibernateJpaVendorAdapter">
 
          <!-- Hibernate 相关的属性 -->
          <!-- 配置数据库类型 -->
         <property name="database" value="MYSQL"/>
         <!-- 显示执行的 SQL -->
         <property name="showSql" value="true"/>
      </bean>
    </property>
 
    <!-- 配置Spring所扫描的实体类所在的包 -->
    <property name="packagesToScan">
      <list>
        <value>mypack</value>
      </list>
    </property>
  </bean>
 
  <!-- 配置事务管理器 -->
  <bean id="transactionManager"
    class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory"
                      ref="entityManagerFactory"/>
   </bean>
 
   <bean id="CustomerService"  class="mypack.CustomerServiceImpl" />
   <bean id="CustomerDao"  class="mypack.CustomerDaoImpl" />
 
    <!-- 配置开启由注解驱动的事务处理 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
 
     <!-- 配置Spring需要扫描的包,
         Spring会扫描这些包以及子包中类的Spring注解 -->
     <context:component-scan base-package="mypack"/>
</beans>

applicationContext.xml配置文件的<context:property-placeholder>元素设定属性文件为classpath根路径下的jdbc.properties文件。C3P0数据源会从该属性文件获取连接数据库的信息。以下是jdbc.properties文件的源代码。

/* jdbc.properties */
jdbc.username=root
jdbc.password=1234
jdbc.driver.class=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sampledb?useSSL=false

Spring的applicationContext.xml配置文件在配置EntityManagerFactory Bean组件时,指定使用HibernateJpaVendorAdapter适配器,该适配器能够把Hibernate集成到Spring中。属性指定实体类所在的包,Spring会扫描这些包中实体类中的对象-关系映射注解。

applicationContext.xml配置文件的<tx:annotation-driven>元素表明在程序中可以通过@Transactional注解来为委托Spring为一个方法声明事务边界。

02、编写范例的Java类

本范例运用了Spring框架,把业务逻辑层又细分为业务逻辑服务层、数据访问层和模型层。

image.png


在上图中,模型层包含了表示业务数据的实体类,数据访问层负责访问数据库,业务逻辑服务层负责处理各种业务逻辑,并且通过数据访问层提供的方法来完成对数据库的各种操作。CustomerDaoImpl类、CustomerServiceImpl类和Tester类都会用到Spring API中的类或者注解。其余的类和接口则不依赖Spring API。

1●编写Customer实体类

Customer类是普通的实体类,它不依赖Sping API,但是会通过JPA API和Hibernate API中的注解来设置对象-关系映射。以下是Customer类的源代码。

/* Customer.java */
@Entity
@Table(name="CUSTOMERS")
public class Customer implements java.io.Serializable {
  @Id
  @GeneratedValue(generator="increment")
  @GenericGenerator(name="increment", strategy = "increment")
  @Column(name="ID")
  private Long id;
 
  @Column(name="NAME")
  private String name;
 
  @Column(name="AGE")
  private int age;
 
  //此处省略Customer类的构造方法、set方法和get方法
  …
}

2●编写CustomerDao数据访问接口和类

CustomerDao为DAO(Data Access Object,数据访问对象)接口,提供了与Customer对象有关的访问数据库的各种方法。以下是CustomerDao接口的源代码。

/* CustomerDao.java */
public interface CustomerDao {
  public void insertCustomer(Customer customer);
  public void updateCustomer(Customer customer);
  public void deleteCustomer(Customer customer);
  public Customer findCustomerById(Long customerId);
  public List<Customer>findCustomerByName(String name);
}

CustomerDaoImpl类实现了CustomerDao接口,通过Spring API和JPA API来访问数据库。以下是CustomerDaoImpl类的源代码。

/* CustomerDaoImpl.java */
package mypack;
import org.springframework.stereotype.Repository;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
 
@Repository("CustomerDao")
public class CustomerDaoImpl implements CustomerDao {
 
    @PersistenceContext(name="entityManagerFactory")
    private EntityManager entityManager;
 
    public void insertCustomer(Customer customer) {
        entityManager.persist(customer);
    }
 
    public void updateCustomer(Customer customer) {
        entityManager.merge(customer);
    }
 
    public void deleteCustomer(Customer customer) {
        Customer c = findCustomerById(customer.getId());
        entityManager.remove(c);
    }
 
    public Customer findCustomerById(Long customerId) {
        return entityManager.find(Customer.class, customerId);
    }
 
    public List<Customer> findCustomerByName(String name) {
        return entityManager
                .createQuery("from Customer c where c.name = :name",
                                 Customer.class)
                .setParameter("name", name)
                .getResultList();
    }
}

在CustomerDaoImpl类中使用了以下来自Spring API的两个注解。

(1) @Repository注解:表明CustomerDaoImpl是DAO类,在Spring的applicationContext.xml文件中通过元素配置了这个Bean组件,Spring会负责创建该Bean组件,并管理它的生命周期,如:

 <bean id="CustomerDao"  class="mypack.CustomerDaoImpl" />

(2)@PersistenceContext注解:表明CustomerDaoImpl类的entityManager属性由Spring来提供,Spring会负责创建并管理EntityManager对象的生命周期。Spring会根据@PersistenceContext(name="entityManagerFactory")注解中设置的EntityManagerFactory对象来创建EntityManager对象,而EntityManagerFactory对象作为Bean组件,在applicationContext.xml文件中也通过元素做了配置,EntityManagerFactory对象的生命周期也由Spring来管理。

从CustomerDaoImpl类的源代码可以看出,这个类无须管理EntityManagerFactory和EntityManager对象的生命周期,只需用Spring API的@Repository和@PersistenceContext注解来标识,Spring 就会自动管理这两个对象的生命周期。

在applicationContext.xml配置文件中 ,<context:component-scan>元素指定Spring所扫描的包,Spring会扫描指定的包以及子包中的所有类中的Spring注解,提供和注解对应的功能。

3●编写CustomerService业务逻辑服务接口和类

CustomerService接口作为业务逻辑服务接口,会包含一些处理业务逻辑的操作。本范例做了简化,CustomerService接口负责保存、更新、删除和检索Customer对象,以下是它的源代码。

/* CustomerService.java */
public interface CustomerService {
  public void insertCustomer(Customer customer);
  public void updateCustomer(Customer customer);
  public Customer findCustomerById(Long customerId);
  public void deleteCustomer(Customer customer);
  public List<Customer> findCustomerByName(String name);
}

CustomerServiceImpl类实现了CustomerService接口,通过CustomerDao组件来访问数据库,以下是它的源代码。

/* CustomerServiceImpl.java */
package mypack;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
 
@Service("CustomerService")
public class CustomerServiceImpl implements CustomerService{
  @Autowired
  private CustomerDao customerDao;
 
  @Transactional
  public void insertCustomer(Customer customer){
    customerDao.insertCustomer(customer);
  }
 
  @Transactional
  public void updateCustomer(Customer customer){
    customerDao.updateCustomer(customer);
  }
 
  @Transactional
  public Customer findCustomerById(Long customerId){
    return customerDao.findCustomerById(customerId);
  }
 
  @Transactional
  public void deleteCustomer(Customer customer){
    customerDao.deleteCustomer(customer);
  }
 
  @Transactional
  public List<Customer> findCustomerByName(String name){
    return customerDao.findCustomerByName(name);
  }
}

在CustomerServiceImpl类中使用了以下来自Spring API的三个注解。

(1)@Service注解:表明CustomerServiceImpl类是服务类。在Spring的applicationContext.xml文件中通过元素配置了这个Bean组件,Spring会负责创建该Bean组件,并管理它的生命周期,如:

<bean id="CustomerService"  class="mypack.CustomerServiceImpl" />

(2)@Autowired注解:表明customerDao属性由Spring来提供。

(3)@Transactional注解:表明被注解的方法是事务型的方法。Spring将该方法中的所有操作加入到事务中。

从CustomerServiceImpl类的源代码可以看出,CustomerServiceImpl类虽然依赖CustomerDao组件,但是无须创建和管理它的生命周期,而且CustomerServiceImpl类也无须显式声明事务边界。这些都由Spring代劳了。

4●编写测试类Tester

Tester类是测试程序,它会初始化Spring框架,并访问CustomerService组件,以下是它的源代码。

/* Tester.java */
package mypack;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support
                      .ClassPathXmlApplicationContext;
import java.util.List;
 
public class Tester{
  private ApplicationContext ctx = null;
  private CustomerService customerService = null;
 
  public Tester(){
    ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    customerService = ctx.getBean(CustomerService.class);
  }
 
  public void test(){
     Customer customer=new Customer("Tom",25);
     customerService.insertCustomer(customer);
     customer.setAge(36);
     customerService.updateCustomer(customer);
 
     Customer c=customerService.findCustomerById(customer.getId());
     System.out.println(c.getName()+": "+c.getAge()+"岁");
 
     List<Customer> customers=
               customerService.findCustomerByName(c.getName());
     for(Customer cc:customers)
         System.out.println(cc.getName()+": "+cc.getAge()+"岁");
 
     customerService.deleteCustomer(customer);
  } 
 
  public static void main(String args[]) throws Exception {
    new Tester().test();
  }
}

在Tester类的构造方法中,首先根据applicationContext.xml配置文件的内容,来初始化Spring框架,并且创建了一个ClassPathXmlApplicationContext对象,再调用这个对象的getBean(CustomerService.class)方法,就能获得CustomerService组件。
————————————————
版权声明:本文为CSDN博主「TiAmo zhang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41640218/article/details/128572931

目录
相关文章
|
24天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
64 2
|
11天前
|
Java 开发者 微服务
Spring Boot 入门:简化 Java Web 开发的强大工具
Spring Boot 是一个开源的 Java 基础框架,用于创建独立、生产级别的基于Spring框架的应用程序。它旨在简化Spring应用的初始搭建以及开发过程。
27 6
Spring Boot 入门:简化 Java Web 开发的强大工具
|
1月前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
29天前
|
SQL Java 数据库连接
从理论到实践:Hibernate与JPA在Java项目中的实际应用
本文介绍了Java持久层框架Hibernate和JPA的基本概念及其在具体项目中的应用。通过一个在线书店系统的实例,展示了如何使用@Entity注解定义实体类、通过Spring Data JPA定义仓库接口、在服务层调用方法进行数据库操作,以及使用JPQL编写自定义查询和管理事务。这些技术不仅简化了数据库操作,还显著提升了开发效率。
39 3
|
2月前
|
Java 数据库连接 开发者
Spring 框架:Java 开发者的春天
【10月更文挑战第27天】Spring 框架由 Rod Johnson 在 2002 年创建,旨在解决 Java 企业级开发中的复杂性问题。它通过控制反转(IOC)和面向切面的编程(AOP)等核心机制,提供了轻量级的容器和丰富的功能,支持 Web 开发、数据访问等领域,显著提高了开发效率和应用的可维护性。Spring 拥有强大的社区支持和丰富的生态系统,是 Java 开发不可或缺的工具。
|
2月前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
94 2
|
22天前
|
Java 数据库连接 API
Spring 框架的介绍(Java EE 学习笔记02)
Spring是一个由Rod Johnson开发的轻量级Java SE/EE一站式开源框架,旨在解决Java EE应用中的多种问题。它采用非侵入式设计,通过IoC和AOP技术简化了Java应用的开发流程,降低了组件间的耦合度,支持事务管理和多种框架的无缝集成,极大提升了开发效率和代码质量。Spring 5引入了响应式编程等新特性,进一步增强了框架的功能性和灵活性。
40 0
|
1月前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
35 0
|
JavaScript Java 数据库连接
spring对hibernate的集成中的回调(CallBack)机制
spring对hibernate的集成中的回调(CallBack)机制
221 0
spring对hibernate的集成中的回调(CallBack)机制