在Spring的配置文件applicationContext.xml中,配置C3P0数据源、EntityManagerFactory和JpaTransactionManager等Bean组件。以下是applicationContext.xml文件的源程序。
/* applicationContext.xml */
mypack
applicationContext.xml配置文件的
/* 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中。
applicationContext.xml配置文件的
本范例运用了Spring框架,把业务逻辑层又细分为业务逻辑服务层、数据访问层和模型层。
在上图中,模型层包含了表示业务数据的实体类,数据访问层负责访问数据库,业务逻辑服务层负责处理各种业务逻辑,并且通过数据访问层提供的方法来完成对数据库的各种操作。CustomerDaoImpl类、CustomerServiceImpl类和Tester类都会用到Spring API中的类或者注解。其余的类和接口则不依赖Spring API。
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方法
…
}
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 ListfindCustomerByName(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 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组件,并管理它的生命周期,如:
(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配置文件中 ,
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 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 findCustomerByName(String name){
return customerDao.findCustomerByName(name);
}
}
在CustomerServiceImpl类中使用了以下来自Spring API的三个注解。
(1)@Service注解:表明CustomerServiceImpl类是服务类。在Spring的applicationContext.xml文件中通过
元素配置了这个Bean组件,Spring会负责创建该Bean组件,并管理它的生命周期,如:
(2)@Autowired注解:表明customerDao属性由Spring来提供。
(3)@Transactional注解:表明被注解的方法是事务型的方法。Spring将该方法中的所有操作加入到事务中。
从CustomerServiceImpl类的源代码可以看出,CustomerServiceImpl类虽然依赖CustomerDao组件,但是无须创建和管理它的生命周期,而且CustomerServiceImpl类也无须显式声明事务边界。这些都由Spring代劳了。
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 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组件。