spring data jpa 入门

初衷

项目中有用到spring data jpa,简单看了一下,在基础的数据库操作上,要比mybatis好用,简化了持久层的操作,使coder可以专注于业务逻辑的实现。网上参考了一些文章,实际coding的时候还是出好多错误。这里通过CRUD,记录摸索填坑的过程。详细的概念可以参考文末的文章。


创建工程

创建一个maven工程。
spring data jpa 入门_第1张图片


配置

web.xml


<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>spring-jpa-webdisplay-name>
  
  <servlet>
    <servlet-name>appServletservlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
    <init-param>
      <param-name>contextConfigLocationparam-name>
      <param-value>classpath:spring.xmlparam-value>
    init-param>
    <load-on-startup>1load-on-startup>
  servlet>

  <servlet-mapping>
    <servlet-name>appServletservlet-name>
    <url-pattern>/url-pattern>
  servlet-mapping>

web-app>

pom.xml

特别说明,spring-data-jpa要用版本1.9.0.RELEASE。


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0modelVersion>

    <groupId>org.wxs.springgroupId>
    <artifactId>spring-jpa-webartifactId>
    <packaging>warpackaging>
    <version>0.1.0version>

    <properties>
        <spring_version>4.3.0.RELEASEspring_version>
        <spring_jpa_version>1.9.0.RELEASEspring_jpa_version>
        <spring_data_commons_version>1.12.6.RELEASEspring_data_commons_version>
        <hibernate.version>4.2.5.Finalhibernate.version>
    properties>

    <dependencies>

        
        
        <dependency>
            <groupId>org.springframework.datagroupId>
            <artifactId>spring-data-jpaartifactId>
            <version>${spring_jpa_version}version>
        dependency>

        
        <dependency>
            <groupId>org.hibernategroupId>
            <artifactId>hibernate-coreartifactId>
            <version>${hibernate.version}version>
        dependency>
        <dependency>
            <groupId>org.hibernategroupId>
            <artifactId>hibernate-entitymanagerartifactId>
            <version>${hibernate.version}version>
        dependency>
        <dependency>
            <groupId>org.hibernategroupId>
            <artifactId>hibernate-ehcacheartifactId>
            <version>${hibernate.version}version>
        dependency>

        
        <dependency>
            <groupId>org.apache.tomcatgroupId>
            <artifactId>tomcat-jdbcartifactId>
            <version>7.0.54version>
        dependency>

        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.35version>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-coreartifactId>
            <version>${spring_version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-beansartifactId>
            <version>${spring_version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webartifactId>
            <version>${spring_version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>${spring_version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>${spring_version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-ormartifactId>
            <version>${spring_version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-txartifactId>
            <version>${spring_version}version>
        dependency>
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>${spring_version}version>
        dependency>

        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-context-supportartifactId>
            <version>${spring_version}version>
        dependency>

        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-testartifactId>
            <version>${spring_version}version>
        dependency>
        
        
        <dependency>
            
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            
            
            
            
            <version>4.12version>
            <scope>testscope>
        dependency>

        
        <dependency>
            <groupId>org.apache.tomcatgroupId>
            <artifactId>tomcat-servlet-apiartifactId>
            <version>8.0.3version>
            <scope>providedscope>
        dependency>

        <dependency>
            <groupId>org.apache.tomcatgroupId>
            <artifactId>jsp-apiartifactId>
            <version>6.0.39version>
            <scope>providedscope>
        dependency>

        <dependency>
            <groupId>jstlgroupId>
            <artifactId>jstlartifactId>
            <version>1.2version>
        dependency>

        <dependency>
            <groupId>javax.servlet.jspgroupId>
            <artifactId>jsp-apiartifactId>
            <version>2.1version>
            <scope>providedscope>
        dependency>
        
    dependencies>


project>

spring.xml


<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:tx="http://www.springframework.org/schema/tx"
       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-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd"
       default-lazy-init="true">

    <description>Spring公共配置description>

    
    <context:component-scan base-package="com.wx.jpa"/>

    
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/>
        <property name="packagesToScan" value="com.wx.jpa.entities"/>
        <property name="jpaProperties">
            <props>
                
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategyprop>
            props>
        property>

        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
        property>
    bean>

    <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
        <property name="generateDdl" value="true"/>
        <property name="database" value="MYSQL"/>
        <property name="databasePlatform" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
    bean>

    
    <jpa:repositories base-package="com.wx.jpa.repository" transaction-manager-ref="transactionManager"
                      entity-manager-factory-ref="entityManagerFactory"/>

    
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    bean>

    
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"/>
    bean>

    
    <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close">
        
        <property name="driverClassName" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

        
        <property name="maxActive" value="${jdbc.pool.maxActive}"/>
        <property name="maxIdle" value="${jdbc.pool.maxIdle}"/>
        <property name="minIdle" value="0"/>
        <property name="defaultAutoCommit" value="true"/>
    bean>

    
    <context:property-placeholder location="classpath:jdbc.properties"/>
beans>

属性文件

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/seckill?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=admin
jdbc.pool.maxIdle=5
jdbc.pool.maxActive=10

Entity

新建表

新建表 user

spring data jpa 入门_第2张图片

实体类

新建实体类User

@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer  id;
    @Column(name = "name")
    private String name;
    @Column(name = "password")
    private String password;
    @Column(name = "birthday")
    private Date birthday;

    /**
     * The default constructor only exists for the sake of JPA. You won’t use it directly, so it is designated as protected.
     */
    protected User() {
    }

    public User(String name, String password, Date birthday) {
        this.name = name;
        this.password = password;
        this.birthday = birthday;
    }
getter、setter省略

DAO层

创建接口UserRepository

public interface UserRepository extends JpaRepository<User,Integer> {

}

测试

新增

    @Test
    public void test1(){
        User user=new User("SL1","123",new Date());
        userRepository.save(user);
        System.out.println("save success");
    }

spring data jpa 入门_第3张图片

查询

查询全部

    @Test
    public void test2(){
        for (User user:userRepository.findAll()) {
            System.out.println(user);
        }
        System.out.println("search all success");
    }

查询结果

User{id=9, name='SL1', password='123', birthday=2017-01-12 00:00:00.0}
User{id=10, name='SL1', password='123', birthday=2017-01-12 00:00:00.0}
User{id=11, name='SL1', password='123', birthday=2017-01-13 00:00:00.0}
search all success

根据ID查询

    @Test
    public void test3(){
        System.out.println(userRepository.findOne(9));
        System.out.println("search one success");
    }

查询结果

User{id=9, name='SL1', password='123', birthday=2017-01-12 00:00:00.0}
search one success

更新

如果有Id,jpa会认为是更新,没有则是新增。

    @Test
    public void test4(){
        User user=new User("SL99","123",new Date());
        user.setId(9);
        userRepository.save(user);
        test3();
        System.out.println("update success");
    }

更新成功

User{id=9, name='SL99', password='123', birthday=2017-01-13 00:00:00.0}
search one success
update success

删除

    @Test
    public void test5(){
        userRepository.delete(9);
        test3();
        System.out.println("delete success");
    }

删除成功

null
search one success
delete success

踩过的坑

坑1

java.lang.AbstractMethodError: org.springframework.data.repository.core.support.RepositoryFactorySupport.getTargetRepository(Lorg/springframework/data/repository/core/RepositoryInformation;)Ljava/lang/Object;

解决方案

Deleting the spring-data-commons and changing the spring-data-jpa version to 1.9.0.RELEASE like @peeskillet said now works fine!
这也是为什么pom文件中spring-data-jpa要配置1.9.0.RELEASE的版本。

坑2

java.lang.IllegalArgumentException: Not an managed type: class java.lang.Object

解决方案

Dao层的接口继承JpaRepository的时候加上泛型。添加域对象类型和主键类型。

public interface UserRepository extends JpaRepository

坑3

org.hibernate.InstantiationException: No default constructor for entity: com.wx.jpa.entities.User

新增、根据ID查询这2个方法不会报这个异常。

解决方案

Hibernate在创建Bean的时候需要User的默认构造方法。Accessing Data with JPA中也有讲到。
You also have two constructors. The default constructor only exists
for the sake of JPA. You won’t use it directly, so it is designated
as protected. The other constructor is the one you’ll use to create
instances of Customer to be saved to the database.


欢迎感兴趣的同学指正。。。


参考:
【原创】纯干货,Spring-data-jpa详解,全方位介绍。
了解 Spring Data JPA

你可能感兴趣的:(spring)