SpringBoot之JPA
撸了今年阿里、网易和美团的面试,我有一个重要发现.......>>>
前言:用Spring全家桶,大家常用的应该是jpa,上次我看过一次调查统计,歪果人使用持久化框架jpa比较多,目前国内已知互联网公司mybatis会比较多,可能大家都觉得mybatis的查询效率更高。 SpringData JPA只是SpringData中的一个子模块,JPA是一套标准接口,而Hibernate是JPA的实现,SpringData JPA 底层默认实现是使用Hibernate,SpringDataJPA 的首个接口就是Repository,它是一个标记接口。只要我们的接口实现这个接口,那么我们就相当于在使用SpringDataJPA了。
Spring Data存储库抽象中的中央接口是
Repository。它将域类以及域类的ID类型作为类型参数进行管理。此接口主要用作标记接口,用于捕获要使用的类型,并帮助您发现扩展此接口的接口。该
CrudRepository规定对于正在管理的实体类复杂的CRUD功能。
public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { //保存给定的实体 <S extends T> S save(S entity); //返回指定ID的实体 Optional<T> findById(ID primaryKey); //返回所有的实体 Iterable<T> findAll(); //返回实体数量 long count(); //删除 void delete(T entity); //查询是否存在某一个数据 boolean existsById(ID primaryKey); // … more functionality omitted. }
最重要的是
CrudRepository,有一个
PagingAndSortingRepository抽象添加了额外的方法来简化对实体的分页访问
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> { //排序 Iterable<T> findAll(Sort sort); //分页加查询 Page<T> findAll(Pageable pageable); }
一般我们自己的jpa接口会继承 jpa,因为jpa既继承了page分页和 query查询的接口。
public interface JpaRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> { List<T> findAll(); List<T> findAll(Sort var1); List<T> findAllById(Iterable<ID> var1); <S extends T> List<S> saveAll(Iterable<S> var1); void flush(); <S extends T> S saveAndFlush(S var1); void deleteInBatch(Iterable<T> var1); void deleteAllInBatch(); T getOne(ID var1); <S extends T> List<S> findAll(Example<S> var1); <S extends T> List<S> findAll(Example<S> var1, Sort var2); }
jpa常用的关键词
关键词 | 样品 | JPQL代码段 |
---|---|---|
And |
findByLastnameAndFirstname |
… where x.lastname = ?1 and x.firstname = ?2 |
Or |
findByLastnameOrFirstname |
… where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals |
findByFirstname, findByFirstnameIs, findByFirstnameEquals |
… where x.firstname = ?1 |
Between |
findByStartDateBetween |
… where x.startDate between ?1 and ?2 |
LessThan |
findByAgeLessThan |
… where x.age < ?1 |
LessThanEqual |
findByAgeLessThanEqual |
… where x.age <= ?1 |
GreaterThan |
findByAgeGreaterThan |
… where x.age > ?1 |
GreaterThanEqual |
findByAgeGreaterThanEqual |
… where x.age >= ?1 |
After |
findByStartDateAfter |
… where x.startDate > ?1 |
Before |
findByStartDateBefore |
… where x.startDate < ?1 |
IsNull |
findByAgeIsNull |
… where x.age is null |
IsNotNull,NotNull |
findByAge(Is)NotNull |
… where x.age not null |
Like |
findByFirstnameLike |
… where x.firstname like ?1 |
NotLike |
findByFirstnameNotLike |
… where x.firstname not like ?1 |
StartingWith |
findByFirstnameStartingWith |
… where x.firstname like ?1(附加参数绑定 %) |
EndingWith |
findByFirstnameEndingWith |
… where x.firstname like ?1(与前置绑定的参数 %) |
Containing |
findByFirstnameContaining |
… where x.firstname like ?1(包含参数绑定 %) |
OrderBy |
findByAgeOrderByLastnameDesc |
… where x.age = ?1 order by x.lastname desc |
Not |
findByLastnameNot |
… where x.lastname <> ?1 |
In |
findByAgeIn(Collection<Age> ages) |
… where x.age in ?1 |
NotIn |
findByAgeNotIn(Collection<Age> ages) |
… where x.age not in ?1 |
True |
findByActiveTrue() |
… where x.active = true |
False |
findByActiveFalse() |
… where x.active = false |
IgnoreCase |
findByFirstnameIgnoreCase |
… where UPPER(x.firstame) = UPPER(?1) |
我们自定义hql语句
public interface UserRepository extends JpaRepository<User, Long> { @Query("select u from User u where u.emailAddress = ?1") User findByEmailAddress(String emailAddress); }
我们自定义的原生sql语句
public interface UserRepository extends JpaRepository<User, Long> { @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true) User findByEmailAddress(String emailAddress); }
占位符 ?用下标来
占位符 :name 用参数名来占位 用@Param(“name”) 来替换
增删改语句 必须用@Modifying注解
@Modifying @Query("update User u set u.firstname = ?1 where u.lastname = ?2") int setFixedFirstnameFor(String firstname, String lastname);
CrudRepository里有个findById该方法的返回值是一个Optional<T>,在Optional类中有个get()方法,返回的是当前对象
/** * Retrieves an entity by its id. * * @param id must not be {@literal null}. * @return the entity with the given id or {@literal Optional#empty()} if none found * @throws IllegalArgumentException if {@code id} is {@literal null}. */ Optional<T> findById(ID id);
JpaRepository里有个getOne()方法返回的是实体对象的代理对象(a reference)
如果不开启事务 会抛出org.hibernate.LazyInitializationException: could not initialize proxy - no Session的异常
/** * Returns a reference to the entity with the given identifier. Depending on how the JPA persistence provider is * implemented this is very likely to always return an instance and throw an * {@link javax.persistence.EntityNotFoundException} on first access. Some of them will reject invalid identifiers * immediately. * * @param id must not be {@literal null}. * @return a reference to the entity with the given identifier. * @see EntityManager#getReference(Class, Object) for details on when an exception is thrown. */ T getOne(ID id);
QueryByExampleExecutor里有个findOne 查询不到数据会 throw new NoSuchElementException("No value present");
/** * Returns a single entity matching the given {@link Example} or {@literal null} if none was found. * * @param example must not be {@literal null}. * @return a single entity matching the given {@link Example} or {@link Optional#empty()} if none was found. * @throws org.springframework.dao.IncorrectResultSizeDataAccessException if the Example yields more than one result. */ <S extends T> Optional<S> findOne(Example<S> example);
持续更新中。。。。
博客地址 https://my.oschina.net/wangnian
- spring boot data-jpa 放回null
- Spring boot通过JPA和Mybatis同时连接2个关系数据库的例子
- [置顶] spring boot项目实战:JPA
- Spring Data JPA例子[基于Spring Boot、Mysql]
- 详解SpringBoot实现JPA的save方法不更新null属性
- Spring Boot 之jpa(二)数据库
- spring boot JPA 使用(二)常见注解说明
- 代码生成器CodeGenerator(目前只支持SpringBoot/SpringDataJpa)
- Spring boot 使用Jpa操作数据库
- spring boot 使用 spring data jpa
- Spring Boot JPA 连接数据库
- Spring Boot 系列(九)数据层-集成Spring-data-jpa
- springBoot jpa 多数据源的动态切换
- Springboot 之 JPA数据库操作进阶篇
- SpringBoot整合jpa
- spring boot 学习--05---mysql,jpa,jdbcTemplate-应用
- 在Spring Boot中使用Spring-data-jpa实现分页查询
- SpringBoot整合JPA
- Spring Boot JPA访问Mysql示例
- 深入学习spring-boot系列(二)--使用spring-data-jpa