Spring Data JPA简单实例

转自:http://itindex.net/detail/47162-spring-data-jpa

我们都知道Spring是一个非常优秀的JavaEE整合框架,它尽可能的减少我们开发的工作量和难度。 

  在持久层的业务逻辑方面,Spring开源组织又给我们带来了同样优秀的Spring Data JPA。 

  通常我们写持久层,都是先写一个接口,再写接口对应的实现类,在实现类中进行持久层的业务逻辑处理。 

  而现在,Spring Data JPA帮助我们自动完成了持久层的业务逻辑处理,我们要做的,仅仅是声明一个持久层接口。 



  1、下载开发所需要的发布包。 

    1)spring-framework-3.1.2.RELEASE-with-docs.zip   

      下载地址:http://www.springsource.org/spring-framework 

                                                   http://maven.springframework.org/release/org/springframework/spring/

    2)hibernate-release-4.1.6.Final.zip 

      下载地址:http://olex.openlogic.com/packages/hibernate 

    3)Spring Data JPA 

      Spring Data JPA 

        下载地址:http://www.springsource.org/spring-data/jpa 

      Spring Data Commons 

        下载地址:http://www.springsource.org/spring-data/commons 

    4)其他一些依赖包可以从 http://ebr.springsource.com/repository/app/library 上查找下载 



  2、新建一个Web项目 spring-data-jpa,把相应的jar包放到/WebRoot/WEB-INF/lib目录下。 

    我也没有挑选哪些是不需要的,最后用到的jar如下: 


复制代码 
antlr-2.7.7.jar 
com.springsource.net.sf.cglib-2.2.0.jar 
com.springsource.org.aopalliance-1.0.0.jar 
com.springsource.org.apache.commons.logging-1.1.1.jar 
com.springsource.org.aspectj.weaver-1.6.3.RELEASE.jar 
commons-lang3-3.1.jar 
dom4j-1.6.1.jar 
hibernate-commons-annotations-4.0.1.Final.jar 
hibernate-core-4.1.6.Final.jar 
hibernate-entitymanager-4.1.6.Final.jar 
hibernate-jpa-2.0-api-1.0.1.Final.jar 
javassist-3.15.0-GA.jar 
jboss-logging-3.1.0.GA.jar 
jboss-transaction-api_1.1_spec-1.0.0.Final.jar 
log4j-1.2.17.jar 
mysql-connector-java-5.0.4-bin.jar 
org.springframework.aop-3.1.2.RELEASE.jar 
org.springframework.asm-3.1.2.RELEASE.jar 
org.springframework.aspects-3.1.2.RELEASE.jar 
org.springframework.beans-3.1.2.RELEASE.jar 
org.springframework.context-3.1.2.RELEASE.jar 
org.springframework.context.support-3.1.2.RELEASE.jar 
org.springframework.core-3.1.2.RELEASE.jar 
org.springframework.expression-3.1.2.RELEASE.jar 
org.springframework.instrument-3.1.2.RELEASE.jar 
org.springframework.instrument.tomcat-3.1.2.RELEASE.jar 
org.springframework.jdbc-3.1.2.RELEASE.jar 
org.springframework.jms-3.1.2.RELEASE.jar 
org.springframework.js.resources-2.3.0.RELEASE.jar 
org.springframework.orm-3.1.2.RELEASE.jar 
org.springframework.oxm-3.1.2.RELEASE.jar 
org.springframework.test-3.1.2.RELEASE.jar 
org.springframework.transaction-3.1.2.RELEASE.jar 
org.springframework.web-3.1.2.RELEASE.jar 
org.springframework.web.portlet-3.1.2.RELEASE.jar 
org.springframework.web.servlet-3.1.2.RELEASE.jar 
slf4j-api-1.6.6.jar 
slf4j-log4j12-1.6.6.jar 
spring-data-commons-core-1.3.0.M1.jar 
spring-data-jpa-1.0.2.RELEASE.jar 

复制代码 

   

  3、在MySql数据库中建立一个叫spring_data_jpa的数据库。 

create database spring_data_jpa default character set utf8; 



  4、JPA配置文件persistence.xml 

    1)在src目录下建立一个叫META-INF的文件夹 

    2)在META-INF文件夹下建立persistence.xml文件 

      persistence.xml内容如下: 


复制代码 
<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" 
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
            xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
            http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> 
            
    <persistence-unit name="myJPA" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider>  
        <properties> 
            <!--配置Hibernate方言 --> 
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> 
            <!--配置数据库驱动 --> 
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> 
            <!--配置数据库用户名 --> 
            <property name="hibernate.connection.username" value="root" /> 
            <!--配置数据库密码 --> 
            <property name="hibernate.connection.password" value="root" /> 
            <!--配置数据库url --> 
            <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/spring_data_jpa?useUnicode=true&amp;characterEncoding=UTF-8" /> 
            <!--设置外连接抓取树的最大深度 --> 
            <property name="hibernate.max_fetch_depth" value="3" /> 
            <!--自动输出schema创建DDL语句 --> 
            <property name="hibernate.hbm2ddl.auto" value="update" />    
            <property name="hibernate.show_sql" value="true" /> 
            <property name="hibernate.format_sql" value="true" /> 
            <property name="javax.persistence.validation.mode" value="none"/> 
        </properties> 
    </persistence-unit> 
            
</persistence> 

复制代码 

   

  5、Spring配置文件applicationContext.xml 

   在src目录下建立applicationContext.xml 

   applicationContext.xml内容如下: 


复制代码 
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xmlns:p="http://www.springframework.org/schema/p"  
    xmlns:cache="http://www.springframework.org/schema/cache"  
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
    
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
          http://www.springframework.org/schema/beans/spring-beans-3.1.xsd   
          http://www.springframework.org/schema/context   
          http://www.springframework.org/schema/context/spring-context-3.1.xsd   
          http://www.springframework.org/schema/aop   
          http://www.springframework.org/schema/aop/spring-aop-3.1.xsd   
          http://www.springframework.org/schema/tx    
          http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 
          http://www.springframework.org/schema/cache 
          http://www.springframework.org/schema/cache/spring-cache-3.1.xsd 
          http://www.springframework.org/schema/data/jpa 
          http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">  
        
        <context:annotation-config />  
        
        <context:component-scan base-package="cn.luxh.app"/> 
       
        <!-- 定义实体管理器工厂 --> 
        <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">  
             <property name="persistenceUnitName" value="myJPA"/> 
        </bean> 
         
         <!-- 配置事务管理器 -->  
           <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">  
            <property name="entityManagerFactory" ref="entityManagerFactory" />  
           </bean> 
       
          <!-- 启用 annotation事务--> 
           <tx:annotation-driven transaction-manager="transactionManager"/> 
           
           <!-- 配置Spring Data JPA扫描目录--> 
           <jpa:repositories base-package="cn.luxh.app.repository"/> 

        
       
</beans> 

复制代码 

   

  6、web.xml 

  web.xml内容如下: 


复制代码 
<?xml version="1.0" encoding="UTF-8"?> 
<web-app version="2.5" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
  <display-name></display-name>    
  
   <!-- log4j配置 --> 
  <context-param> 
    <param-name>webAppRootKey</param-name> 
    <param-value>springdatajpa.root</param-value> 
  </context-param> 
  <context-param> 
    <param-name>log4jConfigLocation</param-name> 
    <param-value>classpath:log4j.properties</param-value> 
  </context-param> 
  <listener> 
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
  </listener> 
  
  <!-- 编码过滤器 --> 
  <filter> 
    <filter-name>characterEncodingFilter</filter-name> 
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> 
    <init-param> 
          <param-name>encoding</param-name> 
          <param-value>UTF-8</param-value> 
    </init-param> 
    
    
  </filter> 
  <filter-mapping> 
    <filter-name>characterEncodingFilter</filter-name> 
    <url-pattern>/*</url-pattern> 
  </filter-mapping> 
  
  <!-- 配置spring监听器 --> 
  <context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>classpath:applicationContext.xml</param-value> 
  </context-param> 
  <listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
  </listener> 
  
  <!-- 配置缓存清除监听器,负责处理由 JavaBean Introspector 功能而引起的缓存泄露 --> 
  <listener>  
      <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
  </listener> 
  
  <welcome-file-list> 
    <welcome-file>index.jsp</welcome-file> 
  </welcome-file-list> 
</web-app> 

复制代码 



  7、日志配置 

    在src目录下建立log4j.properties文件 

    log4j.properties内容如下: 


复制代码 
log4j.rootLogger=INFO,CONSOLE,FILE 
log4j.addivity.org.apache=true 
# 应用于控制台 
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender 
log4j.appender.Threshold=INFO 
log4j.appender.CONSOLE.Target=System.out 
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout 
log4j.appender.CONSOLE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 
#log4j.appender.CONSOLE.layout.ConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n 
#应用于文件 
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender 
log4j.appender.FILE.File=${springdatajpa.root}/springdatajpa.log 
log4j.appender.FILE.Append=true 
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout 
log4j.appender.FILE.layout.ConversionPattern=[framework] %d - %c -%-4r [%t] %-5p %c %x - %m%n 

复制代码 

   

  8、所有环境配完毕,开始写一个Spring Data JPA 的增删改查 

    1)建立相应的包 

                                               



    2)领域模型实体类User 


复制代码 
package cn.luxh.app.domain; 

import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.Table; 

/** 
* 用户信息 
* @author Luxh 
* 2012-8-30 
*/ 
@Entity 
@Table(name="t_user") 
public class User { 
    
    @Id 
    @GeneratedValue 
    private Integer id; 
    
    //账号 
    private String account; 
    
    //姓名 
    private String name; 
    
    //密码 
    private String password; 
    
    
    //省略 getter和setter方法 



复制代码 

    3)声明持久层接口UserRepository 

    让UserRepository接口继承CrudRepository<T,ID>,T是领域实体,ID是领域实体的主键类型。CrudRepository实现了相应的增删改查方法。 


复制代码 
package cn.luxh.app.repository; 


import org.springframework.data.repository.CrudRepository; 

import cn.luxh.app.domain.User; 

/** 
* 用户持久层接口 
* @author Luxh 
* 2012-8-31 
*/ 
public interface UserRepository extends CrudRepository<User,Integer>{ 
    
    


复制代码 

    不再需要持久层接口实现类。 



    4)业务层 

      一般多层架构是控制层调用业务层,业务层再调用持久层。所以这里写个业务层。 

      a、业务层接口: 


复制代码 
package cn.luxh.app.service; 

import cn.luxh.app.domain.User; 

/** 
* 用户业务接口 
* @author Luxh 
* 2012-8-31 
*/ 
public interface UserService { 
    
    /** 
     * 保存用户 
     * @param user 
     */ 
    void saveUser(User user); 
    
    /** 
     * 根据id查找用户 
     * @param id 
     * @return 
     */ 
    User findUserById(Integer id); 
    
    /** 
     * 更新用户 
     * @param user 
     */ 
    void updateUser(User user); 
    
    /** 
     * 根据ID删除用户 
     * @param id 
     */ 
    void deleteUserById(Integer id); 
    
    


复制代码 

    b、业务层接口实现类 


复制代码 
package cn.luxh.app.service; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Service; 
import org.springframework.transaction.annotation.Transactional; 

import cn.luxh.app.domain.User; 
import cn.luxh.app.repository.UserRepository; 

/** 
* 用户业务服务实现类 
* @author Luxh 
* 2012-8-31 
*/ 
@Service("userService") 
public class UserServiceImpl implements UserService{ 
    
    
    @Autowired 
    private UserRepository userRepository;//注入UserRepository 

    @Override 
    @Transactional 
    public void saveUser(User user) { 
        userRepository.save(user); 
        
    } 

    @Override 
    @Transactional(readOnly=true) 
    public User findUserById(Integer id) { 
        return userRepository.findOne(id); 
    } 

    
    @Override 
    @Transactional 
    public void updateUser(User user) { 
        userRepository.save(user); 
    } 

    @Override 
    @Transactional 
    public void deleteUserById(Integer id) { 
        userRepository.delete(id); 
    } 



复制代码 



  9)编写测试用例 

    在执行测试的时候,发现如下错误: 


复制代码 
Caused by: java.lang.NoSuchMethodError: javax.persistence.spi.PersistenceUnitInfo.getValidationMode()Ljavax/persistence/ValidationMode; 
    at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:633) 
    at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:73) 
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:268) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:310) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452) 
    ... 51 more 

复制代码 

  网上说是新版本的Hibernate跟javaee.jar里面的JPA接口冲突了。 

  解决方法:移除MyEclipse自带的Java EE 5 Libraries,自己新建一个user libraries,加入Java EE中的jsf-api.jar、jsf-impl.jar和jstl-1.2.jar,再加入Tomcat中自带的     servlet-api.jar 


  用servlet-api.jar替换掉javaee.jar就没问题了。 

  测试代码: 


复制代码 
package cn.luxh.app.test; 

import org.junit.Assert; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

import cn.luxh.app.domain.User; 
import cn.luxh.app.service.UserService; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration({"/applicationContext.xml"}) 
public class UserTest { 
    
    @Autowired 
    private UserService userService; 
    
    //保存用户 
    @Test 
    public void testSaveUser() { 
        User user = new User(); 
        user.setAccount("LiHuai"); 
        user.setName("李坏"); 
        user.setPassword("123456"); 
        
        userService.saveUser(user); 
    } 
    
    
    //根据id查找用户 
    @Test 
    public void testFindUserById() { 
        Integer id = 1; 
        User user = userService.findUserById(id); 
        Assert.assertEquals("李坏",user.getName()); 
    } 
    
    //更新用户 
    @Test 
    public void testUpdateUser() { 
        Integer id = 1; 
        User user = userService.findUserById(id); 
        user.setName("李寻欢"); 
        
        userService.updateUser(user); 
        
    } 
    
    //根据id删除用户 
    @Test 
    public void testDeleteUserById() { 
        Integer id = 1; 
        
        userService.deleteUserById(id); 
    } 



复制代码 



-------------------------------------------------------------------------------- 

   

  使用Spring Data JPA相当的简单,我们只需要定义持久层的接口,不需要编写实现代码。 

  步骤和注意点: 

  1)在spring配置文件中添加仓库接口的扫描路径 <jpa:repositories base-package="cn.luxh.app.repository"/> 

  2)编写领域实体,需要按照JPA规范 

  3)编写仓库Repository<T,ID>接口,依靠Spring Data规范定义接口方法。 

     比如按照规范定义一个数据访问接口方法  List<User> findByName(String name); 

     Spring Data JPA 就会自动转化为 select u from User u where u.name = ?1 

   

-------------------------------------------------------------------------------- 



  可以使用的仓库接口有: 
    Repository:           是 Spring Data的一个核心接口,它不提供任何方法,开发者需要在自己定义的接口中声明需要的方法。 

    CrudRepository:          继承Repository,提供增删改查方法,可以直接调用。 

    PagingAndSortingRepository:    继承CrudRepository,具有分页查询和排序功能

    JpaRepository:                         继承PagingAndSortingRepository,针对JPA技术提供的接口 

    JpaSpecificationExecutor:          可以执行原生SQL查询 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值