首先了解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 列定义规范
JPA 列定义规范
二、HQL 查询语句
使用过Hibernate 的应该对这个HQL 不陌生
// 使用HQL 查询语句
@Query("select c.id, c.firstName, c.lastName from Customer c where c.firstName = ?1")
List<Customer> 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<Customer> findByLastNameAsSQL(String name);
// 使用原始做复杂查询
@Query(value = "SELECT c.id, concat(c.first_name, c.last_name) AS name FROM customer c", nativeQuery = true)
List<Object[]> findCustomerVoAsSQL();
四、案例
老样子先看案例项目整体结构图
项目整体结构图
定义实体类
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;
@Columnprivate Long customerId;
@Columnprivate String type;
@Columnprivate String number;
public CustomerPhone() {
}
public CustomerPhone(Long customerId, String type, String number) { this.customerId = customerId;
this.type = type;
this.number = number;
}// get set
}
持久化操作
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<Customer, Long> {
// 使用命名的方式查询数据
List<Customer> findByLastName(String lastName);
// 使用HQL 查询语句
@Query("select c.id, c.firstName, c.lastName from Customer c where c.firstName = ?1")
List<Customer> 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<Customer> findByLastNameAsSQL(String name);
// 使用原始做复杂查询
@Query(value = "SELECT c.id, concat(c.first_name, c.last_name) AS name FROM customer c", nativeQuery = true)
List<Object[]> 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<CustomerPhone, Long> {
List<CustomerPhone> findAllByCustomerId(Long customerId);
}
配置JPA
spring.jpa.generate-ddl=truespring.jpa.hibernate.ddl-auto=create-drop
spring.jpa.database=h2
spring.jpa.show-sql=truespring.jpa.open-in-view=false
pom.xml 配置
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
运行测试
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实战联盟”公众号并留言(源码名称+邮箱),小萌看到后会联系作者发送到邮箱,也可以加入交流群和作者互撩哦~~~!
注意:本文归作者所有,未经作者允许,不得转载