架构实战篇(七):Spring Boot Data JPA 快速入门

架构实战篇(七):Spring Boot Data JPA 快速入门_第1张图片
SpringBoot JPA.jpg

首先了解JPA是什么?

JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据。他的出现主要是为了简化现有的持久化开发工作和整合ORM技术,结束现在Hibernate,TopLink,JDO等ORM框架各自为营的局面。值得注意的是,JPA是在充分吸收了现有Hibernate,TopLink,JDO等ORM框架的基础上发展而来的,具有易于使用,伸缩性强等优点。从目前的开发社区的反应上看,JPA受到了极大的支持和赞扬,其中就包括了Spring与EJB3.0的开发团队。

注意:JPA是一套规范,不是一套产品,那么像Hibernate,TopLink,JDO他们是一套产品,如果说这些产品实现了这个JPA规范,那么我们就可以叫他们为JPA的实现产品。

Spring boot Data JPA 是什么?

Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!

Spring boot Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现

多种查询方式

一、规范命名方式

举个例子就知道什么是“规范命名方式”了

User findByUserName(String userName);

这个方法同查询语句

select * from User where userName = ?

就是通过一些关键字来实现一些简单的数据库操作

下面是JPA 列定义规范

架构实战篇(七):Spring Boot Data JPA 快速入门_第2张图片
JPA 列定义规范

二、HQL 查询语句

使用过Hibernate 的应该对这个HQL 不陌生

    // 使用HQL 查询语句
    @Query("select c.id, c.firstName, c.lastName from Customer c where c.firstName = ?1")
    List findByLastNameAsHQL(String name);

三、原生SQL支持

    // 使用原始 sql 语句查询
    @Query(value = "SELECT c.id, c.first_name, c.last_name FROM customer c WHERE c.last_name = ?1", nativeQuery = true)
    List findByLastNameAsSQL(String name);

    // 使用原始做复杂查询
    @Query(value = "SELECT c.id, concat(c.first_name, c.last_name) AS name FROM customer c", nativeQuery = true)
    List findCustomerVoAsSQL();

四、案例

老样子先看案例项目整体结构图

架构实战篇(七):Spring Boot Data JPA 快速入门_第3张图片
项目整体结构图
  1. 定义实体类
package com.itunion.entity;
import java.persistence.*;
@Entity
@Table(indexes = {
        @Index(name = "customer_last_name_idx", columnList = "lastName")
})
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String firstName;
    private String lastName;

    protected Customer() {
    }

    public Customer(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    // get set
}
package com.itunion.entity;
import java.persistence.*;
@Entity
@Table(indexes = {
        @Index(name = "customer_phone_customer_id_idx", columnList = "customerId")
})
public class CustomerPhone {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column
    private Long customerId;
    @Column
    private String type;
    @Column
    private String number;

    public CustomerPhone() {
    }

    public CustomerPhone(Long customerId, String type, String number) {
        this.customerId = customerId;
        this.type = type;
        this.number = number;
    }
// get set
}
  1. 持久化操作
package com.itunion.dao;
import com.itunion.entity.Customer;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;

public interface CustomerRepository extends JpaRepository {
    // 使用命名的方式查询数据
    List findByLastName(String lastName);

    // 使用HQL 查询语句
    @Query("select c.id, c.firstName, c.lastName from Customer c where c.firstName = ?1")
    List findByLastNameAsHQL(String name);

    // 使用原始 sql 语句查询
    @Query(value = "SELECT c.id, c.first_name, c.last_name FROM customer c WHERE c.last_name = ?1", nativeQuery = true)
    List findByLastNameAsSQL(String name);

    // 使用原始做复杂查询
    @Query(value = "SELECT c.id, concat(c.first_name, c.last_name) AS name FROM customer c", nativeQuery = true)
    List findCustomerVoAsSQL();
}
package com.itunion.dao;
import com.itunion.entity.CustomerPhone;
import org.springframework.data.repository.CrudRepository;
import java.util.List;

public interface CustomerPhoneRepository extends CrudRepository {
    List findAllByCustomerId(Long customerId);
}
  1. 配置JPA
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database=h2
spring.jpa.show-sql=true
spring.jpa.open-in-view=false

pom.xml 配置


        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
        
            com.h2database
            h2
        
        
            org.springframework.boot
            spring-boot-starter-web
        
        
            org.springframework.boot
            spring-boot-devtools
            runtime
        
    
  1. 运行测试
package com.itunion;
import com.itunion.dao.CustomerPhoneRepository;
import com.itunion.dao.CustomerRepository;
import com.itunion.entity.Customer;
import com.itunion.entity.CustomerPhone;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.util.List;

@SpringBootApplication
public class SpringBootJpaApplication {
    private static final Logger log = LoggerFactory.getLogger(SpringBootJpaApplication.class);

    public static void main(String[] args) {
        SpringApplication.run(SpringBootJpaApplication.class, args);
    }

    @Bean
    public CommandLineRunner demo(CustomerRepository repository, CustomerPhoneRepository customerPhoneRepository) {
        return (args) -> {
            // save a couple of customers
            repository.save(new Customer("Jack", "Bauer"));
            repository.save(new Customer("Chloe", "O'Brian"));
            repository.save(new Customer("Kim", "Bauer"));
            repository.save(new Customer("David", "Palmer"));
            repository.save(new Customer("Michelle", "Dessler"));

            customerPhoneRepository.save(new CustomerPhone(1L, "LAND", "0218888888"));
            customerPhoneRepository.save(new CustomerPhone(1L, "MOBILE", "18522222222"));
            customerPhoneRepository.save(new CustomerPhone(2L, "MOBILE", "18533333333"));
            customerPhoneRepository.save(new CustomerPhone(3L, "MOBILE", "18544444444"));
            customerPhoneRepository.save(new CustomerPhone(4L, "MOBILE", "18555555555"));
            customerPhoneRepository.save(new CustomerPhone(5L, "MOBILE", "18566666666"));

            // fetch all customers
            log.info("Customers found with findAll():");
            log.info("-------------------------------");
            for (Customer customer : repository.findAll()) {
                log.info(customer.toString());
            }
            log.info("");

            // fetch an individual customer by ID
            Customer customer = repository.findOne(1L);
            log.info("Customer found with findById(1L):");
            log.info("--------------------------------");
            log.info(customer.toString());
            log.info("");

            // fetch customers by last name
            log.info("Customer found with findByLastName('Bauer'):");
            log.info("--------------------------------------------");
            repository.findByLastName("Bauer").forEach(bauer -> {
                log.info(bauer.toString());
            });
            // for (Customer bauer : repository.findByLastName("Bauer")) {
            //  log.info(bauer.toString());
            // }
            log.info("");

            log.info("Customer found with findCustomerVoById(1L):");
            for (CustomerPhone customerPhone : customerPhoneRepository.findAllByCustomerId(1L)) {
                log.info(customerPhone.toString());
            }
            log.info("");

            print("findByLastNameUseHQL", repository.findByLastNameAsHQL("Bauer"));
            print("findByLastNameUseSQL", repository.findByLastNameAsSQL("Bauer"));
            print("findCustomerVoUseSQL", repository.findCustomerVoAsSQL());
        };
    }

    private void print(String title, List list) {
        log.info(" ");
        log.info(title);
        log.info("--------------------------------------------");
        for (Object bean : list) {
            if (bean instanceof Object[]) {
                for (Object b : (Object[]) bean) {
                    log.info(b.toString());
                }
            } else {
                log.info(bean.toString());
            }
        }
    }
}

好了JPA上手就是这么简单,使用T-SQL 语句返回类型还有待研究,敬请期待后续文章

更多精彩内容

架构实战篇(一):Spring Boot 整合MyBatis
架构实战篇(二):Spring Boot 整合Swagger2
架构实战篇(三):Spring Boot 整合MyBatis(二)
架构实战篇(四):Spring Boot 整合 Thymeleaf
架构实战篇(五):Spring Boot 表单验证和异常处理
架构实战篇(六):Spring Boot RestTemplate的使用

关注我们

如果需要源码可以关注“IT实战联盟”公众号并留言(源码名称+邮箱),小萌看到后会联系作者发送到邮箱,也可以加入交流群和作者互撩哦~~~!

架构实战篇(七):Spring Boot Data JPA 快速入门_第4张图片

你可能感兴趣的:(架构实战篇(七):Spring Boot Data JPA 快速入门)