• 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

        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查询

      

    我喜欢程序员,他们单纯、固执、容易体会到成就感;面对压力,能够挑灯夜战不眠不休;面对困难,能够迎难而上挑战自我。他 们也会感到困惑与傍徨,但每个程序员的心中都有一个比尔盖茨或是乔布斯的梦想“用智慧开创属于自己的事业”。我想说的是,其 实我是一个程序员
  • 相关阅读:
    C++重载运算符
    std::vector
    new、delete、动态数组初始化、野指针、解引用、内存池、重载new和delete、内存泄漏等,释放崩溃
    C++匿名函数lambda
    缺少wntdll.pdb
    map、multimap和unordered_map(hash_map)以及unorderd_multimap
    分享一个双击后编辑并AJAX提交保存的脚本
    jquery.cookie.js操作cookie
    MVC获得某个View 或者 PartialView 生成的字符串
    c#中using 和new
  • 原文地址:https://www.cnblogs.com/kms1989/p/5578399.html
Copyright © 2020-2023  润新知