Spring JPA integration

spring integrate basic CRUD jpa customers

rely

<properties>
    <spring.version>4.2.4.RELEASE</spring.version>
    <hibernate.version>5.0.7.Final</hibernate.version>
    <slf4j.version>1.6.6</slf4j.version>
    <log4j.version>1.2.12</log4j.version>
    <c3p0.version>0.9.1.2</c3p0.version>
    <mysql.version>5.1.6</mysql.version>
</properties>
<dependencies>
    <!-- junit单元测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
        <scope>test</scope>
    </dependency>
    <!-- spring beg -->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.6.8</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-orm</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <!-- spring end -->
    <!-- hibernate beg -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>5.2.1.Final</version>
    </dependency>
    <!-- hibernate end -->
    <!-- c3p0 beg -->
    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>${c3p0.version}</version>
    </dependency>
    <!-- c3p0 end -->
    <!-- log end -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>${log4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <!-- log end -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
        <version>1.9.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.2.4.RELEASE</version>
    </dependency>
    <!-- el beg 使用spring data jpa 必须引入 -->
    <dependency>
        <groupId>javax.el</groupId>
        <artifactId>javax.el-api</artifactId>
        <version>2.2.4</version>
    </dependency>
    <dependency>
        <groupId>org.glassfish.web</groupId>
        <artifactId>javax.el</artifactId>
        <version>2.2.4</version>
    </dependency>
    <!-- el end -->
</dependencies>

spring-jpa profile

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jdbc
http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <!-- 1.dataSource 配置数据库连接池-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///jpa"/>
        <property name="user" value="root"/>
        <property name="password" value="root"/>
    </bean>
    <!-- 2.配置entityManagerFactory -->
    <bean id="entityManagerFactory"
          class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan" value="cn.itcast.entity"/>
        <property name="persistenceProvider">
            <bean class="org.hibernate.jpa.HibernatePersistenceProvider"/>
        </property>
        <!--JPA的供应商适配器-->
        <property name="jpaVendorAdapter">
            <bean
                    class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                <property name="generateDdl" value="true"/>
                <property name="database" value="MYSQL"/>
                <property name="databasePlatform"
                          value="org.hibernate.dialect.MySQLDialect"/>
                <property name="showSql" value="true"/>
            </bean>
        </property>
        <property name="jpaDialect">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
        </property>
    </bean>
    <!-- 3.事务管理器-->
    <!-- JPA事务管理器 -->
    <bean id="transactionManager"
          class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>
    <!-- 整合spring data jpa-->
    <jpa:repositories base-package="cn.itcast.dao"
                      transaction-manager-ref="transactionManager"
                      entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
    <!-- 4.txAdvice-->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="insert*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="delete*" propagation="REQUIRED"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
    <!-- 5.aop-->
    <aop:config>
        <aop:pointcut id="pointcut" expression="execution(* cn.itcast.service.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>
    <context:component-scan base-package="cn.itcast"></context:component-scan>
    <!--组装其它 配置文件-->
</beans>

Entity class

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
 * 所有的注解都是使用JPA的规范提供的注解,
 * 所以在导入注解包的时候,一定要导入javax.persistence下的
 */
@Entity //声明实体类
@Table(name="cst_customer") //建立实体类和表的映射关系
public class Customer {
    @Id//声明当前私有属性为主键
    @GeneratedValue(strategy=GenerationType.IDENTITY) //配置主键的生成策略
    @Column(name="cust_id") //指定和表中cust_id字段的映射关系
    private Long custId;
    @Column(name="cust_name") //指定和表中cust_name字段的映射关系
    private String custName;
    @Column(name="cust_source")//指定和表中cust_source字段的映射关系
    private String custSource;
    @Column(name="cust_industry")//指定和表中cust_industry字段的映射关系
    private String custIndustry;
    @Column(name="cust_level")//指定和表中cust_level字段的映射关系
    private String custLevel;
    @Column(name="cust_address")//指定和表中cust_address字段的映射关系
    private String custAddress;
    @Column(name="cust_phone")//指定和表中cust_phone字段的映射关系
    private String custPhone;
}

Prepared in accordance with Spring Data JPA specification Dao layer interface

In the Spring Data JPA, the definition of Dao compliant layer interface, we only need to follow the following on it:

  1. Dao create a layer interface, the interface inherits JpaRepository and JpaSpecificationExecutor
  2. Provide generic
public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {
    // jpql 查全部
    @Query("from Customer")
    List<Customer> findAll();
    // jpql 条件查询
    @Query("from Customer where cust_name = ?1")
    List<Customer> findByCustName(String custName);
    // jpql 更新 @Modifying 执行更新操作
    @Query("update Customer set cust_address = ?2 where cust_id = ?1")
    @Modifying
    void updateCustAddress(Long custId, String custAddress);
    // 原生 sql
    @Query(value = "select * from cst_customer", nativeQuery = true)
    List<Customer> findSql();
    //方法命名规则查询
    List<Customer> findByCustAddress(String custAddress);
    List<Customer> findByCustAddressLikeAndCustNameLike(String custAddress, String custName);
}

The method of naming queries

That is the definition of our query methods when needed named after the spring data jpa specified naming convention

The method of attribute names findBy + + + query [logical connectors + name + method attribute query] ...

Advantages and disadvantages: simple, but if conditions are particularly will lead to lengthy method name. The actual method used jpql naming and binding.

jpql inquiry

It is using the class name and attribute names.@Query @Modifying

sql query

Using the table and column names.@Query nativeQuery = true

Test category

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/spring-jpa.xml")
public class CustomerDaoTest {
    @Autowired
    private CustomerDao customerDao;
    /**
     * 保存客户:调用save(obj)方法
     */
    @Test
    public void testSave() {
        Customer c = new Customer();
        c.setCustName("传智播客");
        customerDao.save(c);
    }
    /**
     * 修改客户:调用save(obj)方法
     * 根据是否存在 id ,进行保存或更新。
     */
    @Test
    public void testUpdate() {
        //根据id查询id为1的客户
        Customer customer = customerDao.findOne(1L);
        //修改客户名称
        customer.setCustName("传智播客顺义校区");
        //更新
        customerDao.save(customer);
    }
    /**
     * 根据id删除:调用delete(id)方法
     */
    @Test
    public void testDelete() {
        customerDao.delete(1L);
    }
    /**
     * 根据id查询:调用findOne(id)方法
     */
    @Test
    public void testFindById() {
        Customer customer = customerDao.findOne(1L);
        System.out.println(customer);
    }
    // jpql 查询
    @Test
    public void testFindAll(){
        List<Customer> customerList = customerDao.findAll();
        System.out.println(customerList);
    }
    @Test
    public void testFindByCustName(){
        List<Customer> customerList = customerDao.findByCustName("传智播客1");
        System.out.println(customerList);
    }

    /**
     * SpringDataJpa 更新/删除操作
     *      * 需要手动开启事务
     *      * 执行完毕后会回滚事务
     *      @Rollback : 设置是否回滚 false|true
     */
    @Test
    @Transactional
    @Rollback(false)
    public void testUpdateCustAddress(){
        customerDao.updateCustAddress(1L, "西安校区");
    }
    // 方法命名查询
    @Test
    public void testFindByCustAddress(){
        List<Customer> customerList = customerDao.findByCustAddress("西安校区");
        System.out.println(customerList);
    }

    @Test
    public void testFindByCustAddressLikeAndCustNameLike(){
        List<Customer> customerList = customerDao.findByCustAddressLikeAndCustNameLike("西安%", "传智%");
        System.out.println(customerList);
    }
    // sql 查询
    @Test
    public void testFindSql(){
        List<Customer> customerList = customerDao.findSql();
        System.out.println(customerList);
    }
}

bugs

org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
原因:SpringDataJpa 更新/删除操作,必须手动加事务
org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet
原因:sql 查询使用的是表名,不是实体名
@Query(value = "select * from Customer", nativeQuery = true)//错误
List<Customer> findSql();

Guess you like

Origin www.cnblogs.com/mozq/p/11288659.html