先说简单一下JPAspring
概念:JPA(Java Persistence API)是Sun官方提出的Java持久化规范。它为Java开发人员提供了一种对象/关联映射工具来管理Java应用中的关系数据。数据库
影响:他的出现主要是为了简化现有的持久化开发工做和整合ORM技术,结束如今Hibernate,TopLink,JDO等ORM框架各自为营的局面数组
好处:spring data jpa让咱们解脱了DAO层的操做,基本上全部CRUD均可以依赖于它来实现缓存
进入正题框架
Spring DATA JPAmaven
一、引入:spring-boot
maven引入:工具
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
gradle引入:gradle
compile('org.springframework.boot:spring-boot-starter-data-jpa')
实现:建立一个接口继承下面的任何一个接口均可以ui
3.1:Repository
概述:仅仅是一个标识,代表任何继承它的均为仓库接口类,方便Spring自动扫描识别 。这个接口是最基础的接口,只是一个标志性的接口,没有定义任何的方法。
它是最顶层的接口,是一个空接口,目的是为了统一全部的Repository的类型,且能让组件扫描的时候自动识别。
好处:例如,咱们有一部分方法是不想对外提供的,好比咱们只想提供增长和修改方法,不提供删除方法,那么下面介绍的几个接口都是作不到的,这个时候,咱们就能够继承这个接口,而后将CrudRepository接口里面相应的方法拷贝到Repository接口就能够了。
3.2:CrudRepository
概述:Repository的子接口,提供CRUD相关的方法
主要方法:
保存 <S extends T> S save(S entity); 批量保存 <S extends T> Iterable<S> save(Iterable<S> entities); 根据id查询一个对象 T findOne(ID id) 判断对象是否存在 boolean exists(ID id) 查询全部的对象 Iterable<T> findAll() 根据id列表查询全部的对象 Iterable<T> findAll(Iterable<ID> ids) 计算对象的总个数 long count() 根据id删除 void delete(ID id) 删除对象 void delete(T entity); 批量删除 void delete(Iterable<? extends T> entities); 删除全部 void deleteAll()
3.3:PagingAndSortingRepository
概述:CrudRepository的子接口,添加一组分页排序相关的方法
主要方法:
不带分页的排序 Iterable<T> findAll(Sort sort) 带分页的排序 Page<T> findAll(Pageable pageable)
3.4:JpaRepository
概述:PagingAndSortingRepository的子接口,增长一组JPA规范相关的方法
主要方法:
查询全部对象,不排序 List<T> findAll() 查询全部对象,并排序 List<T> findAll(Sort sort) 批量保存 <S extends T> List<S> save(Iterable<S> entities); 强制缓存与数据库同步 void flush() 保存并强制同步 T saveAndFlush(T entity) 批量删除 void deleteInBatch(Iterable<T> entities) 删除全部 void deleteAllInBatch();
3.5:JpaSpecificationExecutor
概述:这个比较特殊,不属于Repository体系,它实现一组JPA Criteria查询相关的方法,主要是用来作复杂的查询的接口(辅助接口)。
注意事项:这个接口很特殊,不属于Repository体系,而Spring data JPA不会自动扫描识别,因此会报找不到对应的Bean,咱们只须要继承任意一个继承了Repository的子接口或直接继承Repository接口,Spring data JPA就会自动扫描识别,进行统一的管理
四、自定义方法:
前提:实现上面的任何一个接口
4.1:使用 @Query 建立查询
4.1.1:用法
@Query 注解的使用很是简单,只需在声明的方法上面标注该注解,同时提供一个 JP QL 查询语句便可
例如:
@Query("select u from User u where u.name = :name")
User findUserByName(@Param("name") String name);
4.1.2:参数
4.1.2.1:命名参数
描述:推荐使用这种方法,能够不用管参数的位置
@Query("select u from User u where u.name = :name")
User findUserByName(@Param("name") String name);
4.1.2.2:索引参数
描述:使用?占位符
@Query("select u from User u where u.email = ?1")// 1表示第一个参数 User findUserByEmail(String email);
4.1.2.3: SPEL表达式(这里只是简单的写了一下,有兴趣能够去文档看一下)
描述:从Spring Data JPA版本1.4开始,咱们支持经过手动定义的查询来使用受限制的SpEL模板表达式@Query
@Query("select u from User u where u.name = :name")
User findUserByName(@Param("name") String name);
基于SpEL的查询模板中支持的变量
变量
entityName
用法
select x from #{#entityName} x
描述
插入entityName与给定存储库关联的域类型。该entityName解决以下:若是域类型已设置的name属性@Entity注解那么它将被使用。不然,将使用域类型的简单类名称。
注意
该entityName能够经过自定义@Entity的注释。orm.xmlSpEL表达式不支持自定义。
引用#entityName将会把用户类的潜在的将来重映射转换成一个不一样的实体名称(例如经过使用@Entity(name = "MyUser")
4.1.3:分类
4.1.3.1:QUERY
例如:
@Query("select u from User u where u.name = :name")
User findUserByName(@Param("name") String name);
注意:
一、使用@Query来指定本地查询,只要设置nativeQuery为true,好比:
好比: @Query(value="select * from tbl_user where name like %?1" ,nativeQuery=true) public List<UserModel> findByUuidOrAge(String name);
二、当前版本的本地查询不支持翻页和动态的排序
分类(在Query中也分不少中查询)
一、使用@Query在查询方法中声明查询
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);
二、使用高级LIKE表达式
@Query("select u from User u where u.firstname like %?1")
List<User> findByFirstnameEndsWith(String firstname);
三、使用@Query在查询方法中声明本地计数查询以进行分页
@Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1", countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1", nativeQuery = true) Page<User> findByLastname(String lastname, Pageable pageable);
4.1.3.1:修改查询
好比:
@Modifying @Query(value="update UserModel o set o.name=:newName where o.name like %:nn") public int findByUuidOrAge(@Param("nn") String name,@Param("newName") String newName);
注意:能够经过使用 @Query 来执行一个更新操做,为此,咱们须要在使用 @Query 的同时,* 用 @Modifying 来将该操做标识为修改查询,这样框架最终会生成一个更新的操做,而非查询操做。
4.2:@NamedQueries建立查询
概念:命名查询是 JPA 提供的一种将查询语句从方法体中独立出来,以供多个方法共用的功能
用法:用户只须要按照 JPA 规范在 orm.xml 文件或者在代码中使用 @NamedQuery(或 @NamedNativeQuery)定义好查询语句,惟一要作的就是为该语句命名时,须要知足”DomainClass.methodName()”的 命名规则
好比:
编写接口: public interface FindUserByNamedQueryRepository extends JpaRepository<User, Integer> { User findUserWithName(@Param("name") String name); } 编写类: @Entity @NamedQueries(value={ @NamedQuery(name="User.findUserWithName",query="select u from User u where u.name = :name") })
如下是实体类
......
注意:
一、@NamedQuery中的name属性的值要和接口中的方法名称同样。
二、此处若是是多个方法,那么须要使用@NamedQueries,若是只有一个方法,则可使用@NamedQuery,写法以下:
@NamedQuery(name="User.findUserWithName",query="select u from User u where u.name = :name")
4.3:经过解析方法名建立查询
概念:顾名思义,就是根据方法的名字,就能建立查询
定义规则:
说明:按照Spring data 定义的规则,查询方法以find|read|get开头涉及条件查询时,条件的属性用条件关键字链接,要注意的是:条件属性首字母需大写(参数名大写,条件名首字母大写,而且接口名中参数出现的顺序必须和参数列表中的参数顺序一致)
例如:
//参数名大写,条件名首字母大写,而且接口名中参数出现的顺序必须和参数列表中的参数顺序一致
User findByNameAndEmail(String name, String email); //至关于发送了一条SQL:select u from User u where u.name = :name and u.email = :email List<User> findByNameOrPassword(String name, String password); //至关于发送了一条SQL:select u from User u where u.name = ?1 or u.password = ?2
List<User> findByNameOrPassword(String name, String password); //至关于发送了一条SQL:select u from User u where u.name = ?1 or u.password = ?2
List<User> findByIdBetween(Integer start, Integer end); //至关于发送了一条SQL:select u from User u where u.id between ?1 and ?2
List<User> findByIdLessThan(Integer end); //至关于发送了一条SQL:select u from User u where u.id < ?1 ...
解析:框架在进行方法名解析时,会先把方法名多余的前缀截取掉,好比 find、findBy、read、readBy、get、getBy,而后对剩下部分进行解析。而且若是方法的最后一个参数是 Sort 或者 Pageable 类型,也会提取相关的信息,以便按规则进行排序或者分页查询。在建立查询时,咱们经过在方法名中使用属性名称来表达,好比 findByIdIn()。框架在解析该方法时,首先剔除 findBy,而后对剩下的属性进行解析
一些条件查询的关键字:
框架在进行方法名解析时,会先把方法名多余的前缀截取掉,好比 find、findBy、read、readBy、get、getBy,而后对剩下部分进行解析。
而且若是方法的最后一个参数是 Sort 或者 Pageable 类型,也会提取相关的信息,以便按规则进行排序或者分页查询。在建立查询时,咱们经过在方法名中使用属性名称来表达
,好比 findByIdIn()。框架在解析该方法时,首先剔除 findBy,而后对剩下的属性进行解析
And --- 等价于 SQL 中的 and 关键字,好比 findByUsernameAndPassword(String user, Striang pwd)
Or --- 等价于 SQL 中的 or 关键字,好比 findByUsernameOrAddress(String user, String addr)
Between --- 等价于 SQL 中的 between 关键字,好比 findBySalaryBetween(int max, int min)
LessThan --- 等价于 SQL 中的 "<",好比 findBySalaryLessThan(int max)
GreaterThan --- 等价于 SQL 中的">",好比 findBySalaryGreaterThan(int min)
IsNull --- 等价于 SQL 中的 "is null",好比 findByUsernameIsNull()
IsNotNull --- 等价于 SQL 中的 "is not null",好比 findByUsernameIsNotNull()
NotNull --- 与 IsNotNull 等价
Like --- 等价于 SQL 中的 "like",好比 findByUsernameLike(String user)
NotLike --- 等价于 SQL 中的 "not like",好比 findByUsernameNotLike(String user)
OrderBy ---等价于 SQL 中的 "order by",好比 findByUsernameOrderBySalaryAsc(String user)
Not --- 等价于 SQL 中的 "! =",好比 findByUsernameNot(String user)
In --- 等价于 SQL 中的 "in",好比 findByUsernameIn(Collection<String> userList) ,方法的参数能够是 Collection 类型,也能够是数组或者不定长参数
NotIn --- 等价于 SQL 中的 "not in",好比 findByUsernameNotIn(Collection<String> userList) ,方法的参数能够是 Collection 类型,也能够是数组或者不定长参数