Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!
Spring Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现
这边主要介绍Spring Data JPA的一些用法:
SpringBoot整合使用:
- 添加依赖
org.springframework.boot spring-boot-starter-data-jpa
- 创建实体类:实体类在JPA中可以根据脚本一键生成实体类;
在idea中找到数据库表右键scripted Extensions --> Generate POJOs.groovy,然后选择生成的文件需要在那个对应的文件夹下面就可以;
@Entity
@Table(name = "tableName", schema = "SQLName")
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "ID")
private Integer id;
@Basic
@Column(name = "NAME", length = 500)
private String name;
@Basic
@Column(name = "SEX", length = 20)
private String sex;
@Basic
@Column(name = "CREATED_BY", length = 100)
private String createdBy;
@Basic
@Column(name = "CREATED_DATE")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createdDate;
@Basic
@Column(name = "LAST_UPDATeD_BY" , length = 100)
private String lastUpdatedBy;
@Basic
@Column(name = "LAST_UPDATED_DATE" )
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date lastUpdatedDate;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public String getLastUpdatedBy() {
return lastUpdatedBy;
}
public void setLastUpdatedBy(String lastUpdatedBy) {
this.lastUpdatedBy = lastUpdatedBy;
}
public Date getLastUpdatedDate() {
return lastUpdatedDate;
}
public void setLastUpdatedDate(Date lastUpdatedDate) {
this.lastUpdatedDate = lastUpdatedDate;
}
}
- 创建DAO层:JPA可以继承5个接口:
1.Repository
2.CrudRepository
3.PagingAndSortingRepository
4.JpaSpecificationExecutor
5.JpaRepository<实体类、主键类型>:一般都使用这个接口,因为这个接口有所有接口的功能
@NoRepositoryBean public interface JpaRepositoryextends PagingAndSortingRepository , QueryByExampleExecutor { List findAll(); List findAll(Sort var1); List findAllById(Iterable var1); ListsaveAll(Iterablevar1); void flush();S saveAndFlush(S var1); void deleteInBatch(Iterablevar1); void deleteAllInBatch(); T getOne(ID var1); ListfindAll(Examplevar1);ListfindAll(Examplevar1, Sort var2); }
public interface StudentRepository extends JpaRepository{ @Query(value="select * from student where name = ?1", nativeQuery = true) Student findByName(String name); @Query(value = "update student set name = ?1 where sex = ?2", nativeQuery = true) @Modifying @Transactional void updateNameBySex(String name, String sex); Student findByName(String name); List findByName(String name); Integer countByName(String name); }
可以根据下面的图片
4. 使用
public class StudenTest {
@Autowired
private StudentRepository studentRepository;
@Transactional(rollbackFor = Exception.class)
public void Test() {
// 根据名字查询数据
Student student = studentRepository.findByName("张三");
// 根据性别更新
studentRepository.updateNameBySex("李四", "男");
// 保存
Student student1 = new Student();
student1.setName("哈哈");
student1.setSex("女");
studentRepository.save(student1);
// 更新,只需要指定对应的id就可以
Student student2 = new Student();
student2.setId(1);
student2.setSex("女");
studentRepository.save(student2);
// 根据id删除
studentRepository.deleteById(1);
// 根据类进行删除
studentRepository.delete(student);
// 查询所有
studentRepository.findAll();
// 根据姓名倒叙排序
Sort sort = Sort.by(new Sort.Order(Sort.Direction.DESC, student.getName()));
// 分页查询数据并且排序
Page page = studentRepository.findAll(PageRequest.of(0, 10, sort));
// 获取查询的内容
page.getContent();
// 总条数
page.getTotalElements();
}
}
总结
Spring Date JPA使我们不需要手动写SQL,很方便,也很简单,但是往往让我们忽略了SQL本身,有利有弊;
当我们需要使用复杂的SQL语句,并且需要多表联查的时候,就需要结合QueryDSL进行使用;
QueryDSL
- 添加依赖
com.querydsl querydsl-jpa 2.4.1 // 插件 com.querydsl querydsl-apt 2.4.1 com.mysema.maven apt-maven-plugin 1.1.3 process target/generated-sources/java com.querydsl.apt.jpa.JPAAnnotationProcessor
- Dao层:Dao层添加后要需要编译一下,—maven–package 重新扫描包
继承QuerydslPredicateExecutor<实体类>
public interface StudentRepository extends JpaRepository, QuerydslPredicateExecutor {} public interface OrderDetailRepository extends JpaRepository , QuerydslPredicateExecutor {}
- 使用
public class Test {
@Autowired
private EntityManager entityManager;
// 查询工厂实体
private JPAQueryFactory jpaQueryFactory;
// 实例化控制器完成后执行该方法实例化JPAQueryFactory
@PostConstruct
public void initFactory() {
jpaQueryFactory = new JPAQueryFactory(entityManager);
}
public void Test() {
QStudent qStudent = QStudent.student;
QOrderDetail qOrderDetail = QOrderDetail.orderDetail;
String name = "张三";
// 查询条件
BooleanBuilder builder = new BooleanBuilder();
if (!StringUtils.isEmpty(name)) {
builder.and(qStudent.name.eq(name));
}
QueryResults results = jpaQueryFactory.select(qStudent).from(qStudent).leftJoin(qOrderDetail).on(qStudent.id.eq(qOrderDetail.Id))
.where(builder).orderBy(qStudent.id.asc()).fetchResults();
QueryResults results = jpaQueryFactory.select(qStudent).from(qStudent).leftJoin(qOrderDetail).on(qStudent.id.eq(qOrderDetail.Id))
.where(qStudent.name.eq("张三")).orderBy(qStudent.id.asc()).fetchResults();
QueryResults results = jpaQueryFactory.select(qStudent).from(qStudent).leftJoin(qOrderDetail).on(qStudent.id.eq(qOrderDetail.Id))
.where(qStudent.name.eq("张三")).orderBy(qStudent.id.asc())
.offset(0).limit(10).fetchResults();
jpaQueryFactory.selectDistinct(qStudent.name).from(qStudent).fetchOne();
jpaQueryFactory.select(Projections.bean(
Policy.class,
qStudent.id,
qStudent.name,
qOrderDetail.Id.as("orderId")
)).from(qStudent).leftJoin(qOrderDetail).on(qStudent.id.eq(qOrderDetail.Id))
.where(qStudent.name.eq("张三")).orderBy(qStudent.id.asc());
}
}
总结:
QueryDSL可以解决复杂的SQL查询,不在需要手动书写SQL,调试起来也很简单,debug把鼠标放到代码上就可以映射出对应的SQL,也可以打印出对应的SQL进行调试;
第一次写文章,请大家多多包含,Spring Data JPA在公司经常使用,所以比较熟悉;本人菜鸟一枚,想通过写文章来提升自己并且记录知识;



