This article from the 《 Master JPA And Hibernate: Java Object Persistence technology details 》, Published by Tsinghua University Press , By sun Weiqin .

1. Set up Spring Configuration file for

stay Spring Configuration file for applicationContext.xml in , To configure C3P0 data source 、EntityManagerFactory、JpaTransactionManager etc. Bean Components .applicationContext.xml The file is located in the classpath Under the root path , Here is its source program .

/* applicationContext.xml */
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=……>
<!-- The file path of the configuration properties file -->
<context:property-placeholder
location="classpath:jdbc.properties"/>
<!-- To configure c3p0 Database connection pool -->
<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 Integrate JPA, To configure 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 Related properties -->
<!-- Configuration database type -->
<property name="database" value="MYSQL"/>
<!-- Show the SQL -->
<property name="showSql" value="true"/>
</bean>
</property>
<!-- To configure Spring The package where the scanned entity class is located -->
<property name="packagesToScan">
<list>
<value>mypack</value>
</list>
</property>
</bean>
<!-- Configure transaction manager -->
<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" />
<!-- Configure to enable annotation driven transactions -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- To configure Spring Packages that need to be scanned ,
Spring Will scan these packages and the classes in the subpackages Spring annotation -->
<context:component-scan base-package="mypack"/>
</beans>

above applicationContext.xml Profile's <context:property-placeholder> Element to set the property file to classpath Under the root path jdbc.properties file .C3P0 The data source will get the information of connecting to the database from the property file . Here are jdbc.properties The source code of the file .

/* 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 Of applicationContext.xml The configuration file is configuring EntityManagerFactory Bean When the component , Specify the use of HibernateJpaVendorAdapter Adapter , The adapter is able to connect Hibernate Integrated into the Spring in .<property name="packagesToScan"> Property to specify the package where the entity class is located ,Spring Will scan the objects in the entity classes in these packages - Relation mapping annotation .

above applicationContext.xml Profile's <tx:annotation-driven> The element indicates that in a program you can pass @Transactional Annotation to delegate Spring Declare a transaction boundary for a method .

2. Writing examples Java class

This example uses Spring frame , The business logic layer is subdivided into : Business logic service layer 、 Data access layer and model layer .

 Insert picture description here

In the diagram above , The model layer contains entity classes that represent business data , The data access layer is responsible for accessing the database , The business logic service layer is responsible for handling all kinds of business logic , And through the data access layer to provide methods to complete a variety of database operations .

In the picture above CustomerDaoImpl、CustomerServiceImpl and Tester Class will use Spring API Class or annotation in . The rest of the classes and interfaces do not depend on Spring API.

2.1 To write Customer Entity class

Customer Class is a common entity class , It doesn't depend on Sping API, But through JPA API and Hibernate API To set the object - Relation mapping . Here are Customer Source code of class .

/* 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;
// Omit here Customer Construction method of class 、set Methods and get Method
……
}

2.2 To write CustomerDao Data access interfaces and classes

CustomerDao by DAO(Data Access Object, Data access object ) Interface , Provided with Customer Object related access to the database . Here are CustomerDao The source code of the interface .

/* 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 Class implements the CustomerDao Interface , adopt Spring API and JPA API To access the database . Here are CustomerDaoImpl Source code of class .

/* 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();
}
}

stay CustomerDaoImpl Class is used from Spring API Two notes on :

  • @Repository annotation : indicate CustomerDaoImpl yes DAO class , stay Spring Of applicationContext.xml Through the file <bean> The element configures this Bean Components ,Spring Will be responsible for creating the Bean Components , And manage its life cycle :
    <bean id="CustomerDao" class="mypack.CustomerDaoImpl" />
  • @PersistenceContext annotation : indicate CustomerDaoImpl Class entityManager Attribute from Spring To provide ,Spring Will be responsible for creating and managing EntityManager Object lifecycle .Spring Will be based on @PersistenceContext(name="entityManagerFactory") Set in comments EntityManagerFactory Object to create EntityManager object , and EntityManagerFactory Object as Bean Components , stay applicationContext.xml The document also passed <bean> The element is configured ,EntityManagerFactory The life cycle of an object is also determined by Spring To manage .

from CustomerDaoImpl The source code of the class shows that , This class doesn't need to be managed EntityManagerFactory and EntityManager Object lifecycle , Just use Spring API Of @Repository and @PersistenceContext Annotate to identify ,Spring Will automatically manage the lifecycles of these two objects .

stay applicationContext.xml In profile ,<context:component-scan> Element designation Spring The packets scanned ,Spring Scans the specified package and all classes in the child package for Spring annotation , Provides functions corresponding to annotations .

2.3 To write CustomerService Business logic service interfaces and classes

CustomerService Interface as business logic service interface , There will be some operations to deal with business logic . This example is simplified ,CustomerService The interface is responsible for saving 、 to update 、 Delete and retrieve Customer object , Here's the source code .

/* 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 Class implements the CustomerService Interface , adopt CustomerDao Component to access the database , Here's the source code .

/* 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);
}
}

stay CustomerServiceImpl Class is used from Spring API Three notes of :
(1) @Service annotation : indicate CustomerServiceImpl Class is a service class . stay Spring Of applicationContext.xml Through the file <bean> The element configures this Bean Components ,Spring Will be responsible for creating the Bean Components , And manage its life cycle :

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

(2) @Autowired annotation : indicate customerDao Attribute from Spring To provide .
(3) @Transactional annotation : Indicates that the annotated method is transactional .Spring All operations in this method are added to the transaction .

from CustomerServiceImpl The source code of the class shows that ,CustomerServiceImpl Class depends on CustomerDao Components , But there's no need to create and manage its lifecycle , and CustomerServiceImpl Classes also do not need to explicitly declare transaction boundaries . These are made by Spring take the trouble for .

2.4 Writing test classes Tester

Tester Class is a test program , It initializes Spring frame , And access CustomerService Components , Here's the source code .

/* 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()+" year ");
List<Customer> customers=
customerService.findCustomerByName(c.getName());
for(Customer cc:customers)
System.out.println(cc.getName()+": "+cc.getAge()+" year ");
customerService.deleteCustomer(customer);
}
public static void main(String args[]) throws Exception {
new Tester().test();
}
}

stay Tester In the constructor of a class , according to applicationContext.xml Content of profile , To initialize the Spring frame , And created a ClassPathXmlApplicationContext object , Call this object again getBean(CustomerService.class) Method , Can get CustomerService Components .

 Insert picture description here