SpringData --SpringData JPA small demo

Based on the previous article  JPA introductory small demo  , we continue to understand SpringData JPA in depth.

 

Spring Data JPA Overview

Spring Data JPA is a set of JPA application framework encapsulated by Spring based on ORM framework and JPA specification, which enables developers to use minimal code to achieve database access and operation. It provides common functions including additions, deletions, corrections, etc., and is easy to expand! Learning and using Spring Data JPA can greatly improve development efficiency!

 

Spring Data JPA frees us from the operation of the DAO layer. Basically all CRUD can be realized by relying on it. In actual work projects, it is recommended to use Spring Data JPA + ORM (such as: Hibernate) to complete the operation, so that the switching is different The ORM framework provides great convenience, while also making database layer operations easier and convenient for decoupling.

 

SpringData Jpa greatly simplifies the database access layer code. How to simplify it? Using  SpringDataJpa , we only need to write the interface in our dao  layer, and it will automatically have methods such as addition, deletion, modification and paging query.

The relationship between Spring Data JPA and JPA and Hibernate

JPA is a set of specifications, which is composed of interfaces and abstract classes. Hibernate is a mature ORM framework, and Hibernate implements the JPA specification, so Hibernate can also be called an implementation of JPA. We use JPA API programming, which means looking at the problem from a higher perspective (interface-oriented Programming).

 

Spring Data JPA is a more advanced encapsulation of JPA operations provided by Spring, and is a solution specially used for data persistence under the JPA specification.

 

1. Build a Spring Data JPA development environment

1. Create a project and import dependent coordinates

<properties>
    <spring.version>5.0.2.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.12</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>

    <!-- spring对orm框架的支持包 -->
    <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>

    <!-- 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>

    <!-- c3p0 beg -->
    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>${c3p0.version}</version>
    </dependency>

    <!-- log beg -->
    <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>

    <!-- mysql beg -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>${mysql.version}</version>
    </dependency>

    <!-- spring data jpa 的坐标-->
    <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>${spring.version}</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>

</dependencies>

2. Integrate Spring Data JPA and Spring configuration files

Create applicationContext.xml under the resources folder:

<?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.创建entityManagerFactory对象交给spring容器管理 -->
    <bean id="entityManagerFactoty" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!--配置的扫描的包(实体类所在的包) -->
        <property name="packagesToScan" value="com.cast.domain" />
        <!-- jpa的实现厂家 -->
        <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="false" />
                <!-- 指定数据库类型 -->
                <property name="database" value="MYSQL" />
                <!-- 数据库方言:支持的特有语法 -->
                <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />
                <!-- 是否显示sql -->
                <property name="showSql" value="true" />
            </bean>
        </property>

        <!-- jpa的方言 :高级的特性 -->
        <property name="jpaDialect" >
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
        </property>
    </bean>

    <!-- 2.创建数据库连接池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="root"></property>
        <property name="password" value="root"></property>
        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_data" ></property>
        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    </bean>

    <!-- 3.整合spring dataJpa-->
    <jpa:repositories base-package="com.cast.dao" transaction-manager-ref="transactionManager"
                      entity-manager-factory-ref="entityManagerFactoty" ></jpa:repositories>

    <!-- 4.配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactoty"></property>
    </bean>

    <!-- 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. 配置包扫描 -->
    <context:component-scan base-package="com.cast" ></context:component-scan>

</beans>

3. Create an entity class for the customer table in the database

package com.cast.domain;

import java.io.Serializable;
import javax.persistence.*;

/**
 * 封装数据库中表的实体类
 */
@Entity    //该类是一个数据库表实体封装类
@Table(name = "cst_customer")    //指定数据库中对应表名
public class Customer implements Serializable {

    @Id    //主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)    //主键自增
    @Column(name = "cust_id")    //数据库表中的列名
    private Long custId;    //客户的主键

    @Column(name = "cust_name")
    private String custName;     //客户名称

    @Column(name="cust_source")
    private String custSource;     //客户来源
 
    @Column(name="cust_level")
    private String custLevel;     //客户级别

    @Column(name="cust_industry")
    private String custIndustry;     //客户所属行业

    @Column(name="cust_phone")
    private String custPhone;     //客户的联系方式

    @Column(name="cust_address")
    private String custAddress;     //客户地址

    // getter setter 方法....

    // toString() 方法....

}

2. Use Spring Data JPA to complete the requirements

1. Write a Dao layer interface that conforms to the Spring Data JPA specification

* 符合 Spring Data JPA 规范的 Dao 层接口
*      JpaRepository<操作的实体类类型,实体类中主键属性的类型>
*          * 封装了基本 CRUD 操作
*      JpaSpecificationExecutor<操作的实体类类型>
*          * 封装了复杂查询(分页)
public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {

}

2. Establish a test framework

@RunWith(SpringJUnit4ClassRunner.class)   //声明spring提供的单元测试环境
@ContextConfiguration(locations = "classpath:applicationContext.xml")   //指定spring容器的配置信息
public class CustomerDaoTest {

    @Autowired
    private CustomerDao customerDao;


}

Three. Complete basic operations in the test class

1. 增 - save(Customer customer);

@Test
public void testSave() {
    Customer customer = new Customer();
    customer.setCustName("张三");
    customer.setCustLevel("三级");
    customer.setCustIndustry("it行业");
    customer.setCustSource("广告");
    customer.setCustPhone("1303030303");
    customer.setCustAddress("武汉市汉阳区");
    customerDao.save(customer);
}

2. Delete- delete(Long id);

@Test
public void testDelete() {
    customerDao.delete(1L);
}

3.改 - save(Customer newCustomer);

@Test
public void testUpdate() {
    Customer customer = customerDao.findOne(1L);
    customer.setCustAddress("湖北省武汉市");
    customerDao.save(customer);
}

4. Check by id- findOne(Long id);

@Test
public void testFindOne() {
    Customer customer = customerDao.findOne(1L);
    System.out.println(customer);
}

5. Query all lists- findAll();

@Test
public void testFindAll() {
    List<Customer> list = customerDao.findAll();
    for (Customer customer : list) {
        System.out.println(customer);
    }
}

6. Query the total number of items - count();

@Test
public void testCount() {
    long count = customerDao.count();
    System.out.println("表中数据条数: " + count);
}

7. Query whether the data of the id exists- exists(Long id);

@Test
public void testExists() {
    boolean exists = customerDao.exists(1L);
    System.out.println("此 id 的客户是否存在:" + exists);
}

8. Lazy loading- getOne(Long id);

@Test
@Transactional
public void testGetOne() {
    Customer customer = customerDao.getOne(1L);
    System.out.println(customer);
}

3. Use Spring Data JPA's interface definition method (JPQL) for query

1. Define related methods in the Dao layer interface of the Spring Data JPA specification

/**
  * 根据客户名称查询客户
  */
@Query(value="from Customer where custName = ?")
public Customer findJpql(String custName);

/**
  * 根据客户名称和客户 id 查询客户
  */
@Query(value = "from Customer where custName = ?2 and custId = ?1")
public Customer findCustNameAndId(Long id, String name);

/**
  * 使用jpql完成更新操作
  */
@Query(value = "update Customer set custName = ?2 where custId = ?1")
@Modifying
public void updateCustomer(long custId, String custName);


/**
  * 使用sql的形式查询:
  *     根据姓名模糊查询客户
  */
//@Query(value = "select * from cst_customer", nativeQuery = true)
@Query(value="select * from cst_customer where cust_name like ?1", nativeQuery = true)
public List<Object []> findSql(String name);

/**
  * 方法名的约定:
  *      findBy : 查询
  *      findByCustName   --   根据客户名称查询
  */
public Customer findByCustName(String custName);

/**
  * 使用客户名称模糊查询
  */
public List<Customer> findByCustNameLike(String custName);

/**
  * 使用客户名称模糊匹配和客户所属行业精准匹配的查询
  */
public Customer findByCustNameLikeAndCustIndustry(String custName, String custIndustry);

2. Implement the above method in the test class

/**
  * 根据客户名称查询客户
  */
@Test
public void testFindJPQL() {
    Customer customer = customerDao.findJpql("张三");
    System.out.println(customer);
}

/**
  * 根据客户名称和客户 id 查询客户
  */
@Test
public void testFindCustNameAndId() {
    // Customer customer =  customerDao.findCustNameAndId("张三", 1L);
    Customer customer = customerDao.findCustNameAndId(1L, "张三");
    System.out.println(customer);
}

/**
  * 使用jpql完成更新操作
  */
@Test
@Transactional  //添加事务的支持
@Rollback(value = false)
public void testUpdateCustomer() {
    customerDao.updateCustomer(1L, "李四");
}

/**
  * 使用sql的形式查询:
  *     根据姓名模糊查询客户
  */
@Test
public void testFindSql() {
    List<Object[]> list = customerDao.findSql("李%");
    for (Object[] obj : list) {
        System.out.println(Arrays.toString(obj));
    }
}

/**
  * 方法名的约定:
  *      findBy : 查询
  *      findByCustName   --   根据客户名称查询
  */
@Test
public void testNaming() {
    Customer customer = customerDao.findByCustName("李四");
    System.out.println(customer);
}

/**
  * 使用客户名称模糊查询
  */
@Test
public void testFindByCustNameLike() {
    List<Customer> list = customerDao.findByCustNameLike("李%");
    for (Customer customer : list) {
        System.out.println(customer);
    }
}

/**
  * 使用客户名称模糊匹配和客户所属行业精准匹配的查询
  */
@Test
public void testFindByCustNameLikeAndCustIndustry() {
    Customer customer = customerDao.findByCustNameLikeAndCustIndustry("李%", "it行业");
    System.out.println(customer);
}

 

Source download:  https://pan.baidu.com/s/17y15LMqs5ohVuJQ509_kjw

Guess you like

Origin blog.csdn.net/weixin_42629433/article/details/84723266