Spring Data JPA初使用

咱們都知道Spring是一個很是優秀的JavaEE整合框架,它儘量的減小咱們開發的工做量和難度。java

  在持久層的業務邏輯方面,Spring開源組織又給咱們帶來了一樣優秀的Spring Data JPAmysql

  一般咱們寫持久層,都是先寫一個接口,再寫接口對應的實現類,在實現類中進行持久層的業務邏輯處理。web

  而如今,Spring Data JPA幫助咱們自動完成了持久層的業務邏輯處理,咱們要作的,僅僅是聲明一個持久層接口。spring

 

  一、下載開發所須要的發佈包。sql

    1)spring-framework-3.1.2.RELEASE-with-docs.zip  數據庫

      下載地址:http://www.springsource.org/spring-frameworkexpress

    2)hibernate-release-4.1.6.Final.zipapache

      下載地址:http://olex.openlogic.com/packages/hibernateapi

    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 上查找下載

 

  二、新建一個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.jarspring-data-commons-core-1.3.0.M1.jarspring-data-jpa-1.0.2.RELEASE.jar

  

  三、在MySql數據庫中創建一個叫spring_data_jpa數據庫

create database spring_data_jpa default character set utf8;

 

  四、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>

  

  五、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>

  

  六、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>

 

  七、日誌配置

    在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

  

  八、全部環境配完畢,開始寫一個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查詢

相關文章
相關標籤/搜索