Spring Data JPA

JPA(Java Persistence API)Java持久化API。Spring Data JPA是spring提供的一套简化JPA开发的框架,底层还是使用了hibernate的JPA技术实现。
持久化工具都有一个对象来操作数据库,原生的Hibernate中叫做Session,JPA中叫做EntityManager,MyBatis中叫做SqlSession。

<dependencies>
  <dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jpa</artifactId>
  </dependency>
<dependencies>

springboot集成jpa

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/zhu
    username: root
    password: root
  jpa:
    hibernate:
      # create 每次启动重新创建表
      # update 更新,原数据不会清空
      # validate 校验,字段不同会报错
      # none 禁用ddl
      ddl-auto: update
    show-sql: true

The central interface in the Spring Data repository abstraction is Repository.
CrudRepository接口提供复杂的CRUD功能

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
	// 保存
    <S extends T> S save(S entity);
	// 返回给定ID标识的实体
    Optional<T> findById(ID primaryKey);
	// 给定ID实体是否存在
    boolean existsById(ID primaryKey);
	// 返回所有实体
    Iterable<T> findAll();
	// 返回实体数量
    long count();
	// 删除指定ID实体
    void deleteById(ID primaryKey);
	// 删除指定实体
    void delete(T entity);
}

PagingAndSortingRepository简化对实体的分页访问

public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {

  Iterable<T> findAll(Sort sort);

  Page<T> findAll(Pageable pageable);
}

public interface PeopleRepository extends PagingAndSortingRepository<People, Integer> {
}

// 对User的分页查询
Page<User> users = peopleRepository.findAll(PageRequest.of(pageNum, pageSize, Sort.by("id").ascending()));

根据方法名称创建查询

public interface PeopleRepository extends PagingAndSortingRepository<People, Integer> {
	// 根据名称和国家查
	People findByNameAndCountry(String name, String country);
	// 根据名称或国家查
	People findByNameOrCountry(String name, String country);
	// between
	List<People> findByAgeBetween(Integer age1, Integer age2);
	// lessThan小于/lessThanEqual小于等于/greaterThan大于/greaterThanEqual大于等于
	List<People> findByAgeIsLessThan(Integer age);
	// isNull/isNotNull/isLike/isNotLike/isStartingWith/isEndingWith/Containing/not/in......
	List<People> findByNameIsNull(..);
	// first5/top5 前5条数据
	List<People> findFirst5ByName(String name);
	// 根据名字查询结果按年龄升序,并提供排序和分页功能
	List<Person> findByNameOrderByAgeAsc(String name, int age, Sort sort, PageRequest pageRequest);
	//Spring Data JPA 支持@Query来定义查询方法,使用方法是将@Query写在接口的方法上面
	@Query(select p from Person p where p.name = ?1 and p.country = ?2")
	Person selectByNameAndCountry(String name, String country);
	@Query(select p from Person p where p.name = :name and p.country = :country")
	Person selectByNameAndCountry(@Param("name")String name, @Param("country")String country);
	
	// 更新
	@Modify
	@Transcational
	@Query("update Person p set p.name = ?1 where p.id = ?2 ")
	int setName(String name, Integer id);
	// hql模糊查询
	@Query("select u from user u where u.name like concat('%', ?1, '%')")
	User findByName(String name);

	// 查询指定字段, 得在User中存在id和name得构造函数,否则启动报错:Unable to locate appropriate constructor on class
	@Query("select new User(a.id, a.name) from User as a where a.name = ?1 ")
	Page<User> queryPartColumns(String name, Pageable pageable);
	
	// Spring Data Jpa目前不支持对原生查询进行动态排序,但可以通过自己指定计数查询countQuery来使用原生查询进行分页、排序
	@Query(value = "select * from User u where u.namelike %?1%",
            countQuery = "select count(1) from User u where u.name= %?1%",
            nativeQuery = true)
	Page<User> queryByUsernameLike(String username, Pageable pageable);
}

// 调用
peopleRepository.findByNameOrderByAge("Tom",20, Sort.by("id").ascending(),

                PageRequest.of(0,5));
                

动态条件分页查询

// 分页条件查询 Page<S> findAll(Example<S> example, Pageable pageable);
User user = new User();
user.setName("tom");
ExampleMatcher matcher = ExampleMatcher.matching()
	.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINTING) // 改变默认字符串匹配方式:模糊查询
	.withIgnoreCase(true)
	.withMatcher("country", ExampleMatcher.GenericPropertyMatchers.startsWith()) //地区采用“开始匹配”的方式查询 
	.withIgnorePaths("age") // 忽略属性age;
Example<User> example = Example.of(user);
Page<User> page = userRepository.findAll(example, PageRequest.of(0, 3));    


// 分页条件查询 Page<T> findAll(Specification<T> spe, Pageable pageable);
Page<User> page = userRepository.findAll((Specification<User>) (root, criteriaQuery, criteriaBuilder) -> {
	List<Predicate> list = new ArrayList<>();
	if (StringUtils.isNotBlank(name)) {
		list.add(criteriaBuilder.like(root.get("name").as(String.class), '%' + name + '%'));
	}
	if (null != age) {
		list.add(criteriaBuilder.equal(root.get("age").as(Integer.class), age));
	}
	return criteriaQuery.where(list.toArray(new Predicate[list.size()])).getRestriction();
}, PageRequest.of(pageNo, pageSize));


// 还可使用EntityManager
StringBuilder sqlStr = new StringBuilder("select new User(a.name,a.age) from User a where 1=1 ");
StringBuilder countStr = new StringBuilder("select count(1) from tbl_user a where 1=1 ");
if (StringUtils.isNotBlank(name)) {
	sqlStr.append(" and a.name = :name);
	countStr.append(" and a.user_name = :name);

}
// createQuery使用HQL语句实现查询,以hibernate生成的Bean为对象装入list返回
/** 
 * createNativeQuery使用SQL语句实现查询      
 * List<User> = query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(User.class)).getResultList();
 */

Query query = entityManager.createQuery(sqlStr.toString(), User.class);
Query countQuery = entityManager.createNativeQuery(sqlStr.toString());

if (StringUtils.isNotBlank(name)) {
	query.setParameter("name", name);
	countQuery.setParameter("name", name);
}
long total = (long)countQuery.getSingleResult();
query.setFirstResult(pageNo * pageSize).setMaxResults(pageSize);
Page<user> page = new PageImpl<>(query.getResultList(), PageRequest.of(pageNo, pageSize), total);

多表查询

	// 实体类 多对多
    @ManyToMany(targetEntity = Role.class, cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch = FetchType.LAZY)
    @JoinTable(name = "tb_user_role", joinColumns = {@JoinColumn(name = "user_id", referencedColumnName = "id")},
            inverseJoinColumns = {@JoinColumn(name = "role_id", referencedColumnName = "id")})
    private Set<Role> roles;

	// 调用
    Optional<User> optional = userRepository.findById("1");
    Set<Role> roles = optional.get().getRoles();
    System.out.println(optional.get());
    
    // spring Boot整合JPA后Hibernate的Session就交付给Spring去管理。每次数据库操作后,会关闭Session,当我们想要用懒加载方式去获得数据的时候,原来的Session已经关闭,不能获取数据
	spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

	// 一对多/多对一 一个部门包含多个员工
	// Department 部门表
    @OneToMany(mappedBy = "department", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private Set<Employee> employees;
    
    // Emplouee 员工表
    @ManyToOne(targetEntity = Department.class, cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinColumn(name = "dept_id")
    private Department department;

Spring Data Jpa支持审计功能: @CreatedBy,@LastModifiedBy,@CreatedDate,@LastModifiedDate 4个注解

启动类上添加@EnableJpaAuditing注解启用Jpa的审计功能
实体类加注解@EntityListeners(AuditingEntityListener.class)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xiha_zhu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值