JPA基础及查询规则


JPA


  JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。

  JPA框架中支持大数据集、事务、并发等容器级事务,这使得 JPA 超越了简单持久化框架的局限,在企业应用发挥更大的作用。

Spring Boot使用JPA


首先在idea中创建项目的时候你就需要选择JPA这一项,就会自动的在pom.xml文件中引入JPA的jar包

创建一个BaseDAO来继承JpaRepository,这是根本也是基础的,这里的BaseDAO跟hibernate中的很相似,可以参照一下,DAO是一个项目的根本所在,写好了他其他也差不多了

基本查询


JPA基本查询也分为两种,一种是spring data默认已经实现,一种是根据查询的方法来自动解析成SQL。

默认的直接在你的Controller中直接调用:


以下是看到大牛写的,真是太好了,我只是搬运工

地址http://www.cnblogs.com/ityouknow/p/5891443.html

基本查询

基本查询也分为两种,一种是spring data默认已经实现,一种是根据查询的方法来自动解析成SQL。

预先生成方法

spring data jpa 默认预先生成了一些基本的CURD的方法,例如:增、删、改等等

1 继承JpaRepository

public interface UserRepository extends JpaRepository<User, Long> {
}

2 使用默认方法

@Test
public void testBaseQuery() throws Exception {
User user=new User();
userRepository.findAll();
userRepository.findOne(1l);
userRepository.save(user);
userRepository.delete(user);
userRepository.count();
userRepository.exists(1l);
// ...
}

就不解释了根据方法名就看出意思来

自定义简单查询

自定义的简单查询就是根据方法名来自动生成SQL,主要的语法是findXXBy,readAXXBy,queryXXBy,countXXBygetXXBy后面跟属性名称:

User findByUserName(String userName);

也使用一些加一些关键字And、 Or

User findByUserNameOrEmail(String username, String email);

修改、删除、统计也是类似语法

Long deleteById(Long id);

Long countByUserName(String userName)

基本上SQL体系中的关键词都可以使用,例如:LIKE、 IgnoreCase、 OrderBy

List<User> findByEmailLike(String email);

User findByUserNameIgnoreCase(String userName);

List<User> findByUserNameOrderByEmailDesc(String email);

具体的关键字,使用方法和生产成SQL如下表所示

Keyword Sample JPQL snippet
And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
Is,Equals 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 (parameter bound with appended %)
EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (parameter bound with prepended %)
Containing findByFirstnameContaining … where x.firstname like ?1 (parameter bound wrapped in %)
OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
Not findByLastnameNot … where x.lastname <> ?1
In findByAgeIn(Collection ages) … where x.age in ?1
NotIn findByAgeNotIn(Collectionage) … 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)

复杂查询

在实际的开发中我们需要用到分页、删选、连表等查询的时候就需要特殊的方法或者自定义SQL

分页查询

分页查询在实际使用中非常普遍了,spring data jpa已经帮我们实现了分页的功能,在查询的方法中,需要传入参数Pageable
,当查询中有多个参数的时候Pageable建议做为最后一个参数传入

Page<User> findALL(Pageable pageable);

Page<User> findByUserName(String userName,Pageable pageable);

Pageable 是spring封装的分页实现类,使用的时候需要传入页数、每页条数和排序规则

@Test
public void testPageQuery() throws Exception {
int page=1,size=10;
Sort sort = new Sort(Direction.DESC, "id");
Pageable pageable = new PageRequest(page, size, sort);
userRepository.findALL(pageable);
userRepository.findByUserName("testName", pageable);
}

限制查询

有时候我们只需要查询前N个元素,或者支取前一个实体。

ser findFirstByOrderByLastnameAsc();

User findTopByOrderByAgeDesc();

Page<User> queryFirst10ByLastname(String lastname, Pageable pageable);

List<User> findFirst10ByLastname(String lastname, Sort sort);

List<User> findTop10ByLastname(String lastname, Pageable pageable);

自定义SQL查询

其实Spring data 觉大部分的SQL都可以根据方法名定义的方式来实现,但是由于某些原因我们想使用自定义的SQL来查询,spring data也是完美支持的;在SQL的查询方法上面使用@Query注解,如涉及到删除和修改在需要加上@Modifying.也可以根据需要添加 @Transactional 对事物的支持,查询超时的设置等

@Modifying
@Query("update User u set u.userName = ?1 where c.id = ?2")
int modifyByIdAndUserId(String userName, Long id); @Transactional
@Modifying
@Query("delete from User where id = ?1")
void deleteByUserId(Long id); @Transactional(timeout = 10)
@Query("select u from User u where u.emailAddress = ?1")
User findByEmailAddress(String emailAddress);

多表查询

多表查询在spring data jpa中有两种实现方式,第一种是利用hibernate的级联查询来实现,第二种是创建一个结果集的接口来接收连表查询后的结果,这里主要第二种方式。

首先需要定义一个结果集的接口类。

public interface HotelSummary {

    City getCity();

    String getName();

    Double getAverageRating();

    default Integer getAverageRatingRounded() {
return getAverageRating() == null ? null : (int) Math.round(getAverageRating());
} }

查询的方法返回类型设置为新创建的接口

@Query("select h.city as city, h.name as name, avg(r.rating) as averageRating "
- "from Hotel h left outer join h.reviews r where h.city = ?1 group by h")
Page<HotelSummary> findByCity(City city, Pageable pageable); @Query("select h.name as name, avg(r.rating) as averageRating "
- "from Hotel h left outer join h.reviews r group by h")
Page<HotelSummary> findByCity(Pageable pageable);

使用

Page<HotelSummary> hotels = this.hotelRepository.findByCity(new PageRequest(0, 10, Direction.ASC, "name"));
for(HotelSummary summay:hotels){
System.out.println("Name" +summay.getName());
}

在运行中Spring会给接口(HotelSummary)自动生产一个代理类来接收返回的结果,代码汇总使用getXX的形式来获取

多数据源的支持

同源数据库的多源支持

日常项目中因为使用的分布式开发模式,不同的服务有不同的数据源,常常需要在一个项目中使用多个数据源,因此需要配置sping data jpa对多数据源的使用,一般分一下为三步:

  • 1 配置多数据源
  • 2 不同源的实体类放入不同包路径
  • 3 声明不同的包路径下使用不同的数据源、事务支持

这里有一篇文章写的很清楚:Spring Boot多数据源配置与使用

异构数据库多源支持

比如我们的项目中,即需要对mysql的支持,也需要对mongodb的查询等。

实体类声明@Entity 关系型数据库支持类型、声明@Document 为mongodb支持类型,不同的数据源使用不同的实体就可以了

interface PersonRepository extends Repository<Person, Long> {

} @Entity
public class Person {

} interface UserRepository extends Repository<User, Long> {

} @Document
public class User {

}

但是,如果User用户既使用mysql也使用mongodb呢,也可以做混合使用

interface JpaPersonRepository extends Repository<Person, Long> {

} interface MongoDBPersonRepository extends Repository<Person, Long> {

} @Entity
@Document
public class Person {

}

也可以通过对不同的包路径进行声明,比如A包路径下使用mysql,B包路径下使用mongoDB

@EnableJpaRepositories(basePackages = "com.neo.repositories.jpa")
@EnableMongoRepositories(basePackages = "com.neo.repositories.mongo")
interface Configuration { }

其它

使用枚举

使用枚举的时候,我们希望数据库中存储的是枚举对应的String类型,而不是枚举的索引值,需要在属性上面添加@Enumerated(EnumType.STRING) 注解

@Enumerated(EnumType.STRING)
@Column(nullable = true)
private UserType type;

不需要和数据库映射的属性

正常情况下我们在实体类上加入注解@Entity,就会让实体类和表相关连如果其中某个属性我们不需要和数据库来关联只是在展示的时候做计算,只需要加上@Transient属性既可。

@Transient
private String userName;

Spring Boot-------JPA基础及查询规则的更多相关文章

  1. Spring Boot Jpa 多条件查询+排序+分页

    事情有点多,于是快一个月没写东西了,今天补上上次说的. JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将 ...

  2. 【Spring Data 系列学习】Spring Data JPA 基础查询

    [Spring Data 系列学习]Spring Data JPA 基础查询 前面的章节简单讲解了 了解 Spring Data JPA . Jpa 和 Hibernate,本章节开始通过案例上手 S ...

  3. Spring Boot JPA的查询语句

    文章目录 准备工作 Containing, Contains, IsContaining 和 Like StartsWith EndsWith 大小写不敏感 Not @Query Spring Boo ...

  4. Spring Boot(五):Spring Boot Jpa 的使用

    在上篇文章Spring Boot(二):Web 综合开发中简单介绍了一下 Spring Boot Jpa 的基础性使用,这篇文章将更加全面的介绍 Spring Boot Jpa 常见用法以及注意事项. ...

  5. Spring Boot Jpa 的使用

    Spring Boot Jpa 介绍 首先了解 Jpa 是什么? Jpa (Java Persistence API) 是 Sun 官方提出的 Java 持久化规范.它为 Java 开发人员提供了一种 ...

  6. (转)Spring Boot(五):Spring Boot Jpa 的使用

    http://www.ityouknow.com/springboot/2016/08/20/spring-boot-jpa.html 在上篇文章Spring Boot(二):Web 综合开发中简单介 ...

  7. Spring boot JPA 用自定义主键策略 生成自定义主键ID

    最近学习Spring boot JPA 学习过程解决的一些问题写成随笔,大家一起成长.这次遇到自定义主键的问题 package javax.persistence; public enum Gener ...

  8. Spring Boot Jpa 表名小写转大写

    今天在使用SpringBoot整合Hibernate后创建表,表名为小写,而在linux下,mysql的表名是区分大小写的,因此在我的数据表中,就出现了两个一样的表 act_id_user 和  AC ...

  9. Spring Boot中利用递归算法查询到所有下级用户,并手动进行分页

    Spring Boot中利用递归算法查询到所有下级用户,并手动进行分页 前提:语言用的是kotlin(和Java一样,但更简洁),写下这篇文章用来记录编程过程中遇到的一些难点 1.功能需求 前端用户A ...

随机推荐

  1. MyEclipse下安装FatJar打包工具

    方法一:help > software updates > Find and install > add > add remote site name:FatJar url:h ...

  2. C#中抽象类和接口的区别2

    1.接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性        抽象类是从一系列相关对象中抽象出来的概念, 因此反映的是事物的内部共性:       2. 下面分别从声明, ...

  3. 《Linux命令行与shell脚本编程大全》第十章 使用编辑器

    主要介绍vim, nano, emacs,KWrite,Kate,GNOME 10.1 vim Unix系统最初的编辑器 10.1.1检查vim软件包 先搞明白你所用的Linux系统是哪种vim软件包 ...

  4. [转]oracle系统表v$session、v$sql字段说明

    在本视图中,每一个连接到数据库实例中的 session都拥有一条记录.包括用户 session及后台进程如 DBWR, LGWR, arcchiver等等. V$SESSION中的常用列 V$SESS ...

  5. jvm内存区域与内存溢出

    java内存 java动态运行时区域包括:方法区.虚拟机栈.本地方法栈.堆.程序计数器,如右图所示:   程序计数器 程序计数器用来标识要执行的代码的行号,为线程私有   虚拟机栈 为线程所私有 虚拟 ...

  6. 关于vue 框架与后台框架的混合使用的尝试

    这几天我在研究前台框架和后台框架融合的问题,进行了一些尝试; 我前台选择的是 vue,当然也可以选择 react 等其他 mvvm 框架,不过 vue 对于我来说是最熟悉的; 后台话,我选择的是 ph ...

  7. Python 学习之路3

    接下来把剩下的实验一起写上去 实验2 写一个学生类,属性有学号,姓名,成绩(三门),方法有输出,求平均成绩. 设计思路: 1.         先写一个学生类,并向里面写一个求平均值和输出信息的方法. ...

  8. javac 实现原理

    javac 概述 javac 是jdk bin目录下的一个脚本. 用于编译 java程序的源代码,但是 其实现的本质 是基于 jdk 标准类库中的 javac类库实现,所以java的编译器实质上是一个 ...

  9. PHP时间戳和日期互转换

    在php中我们要把时间戳转换日期可以直接使用date函数来实现,如果要把日期转换成时间戳可以使用strtotime()函数实现,下面我来给大家举例说明. 1.php中时间转换函数 strtotime ...

  10. dedecms注入漏洞

    版本:Powered by DedeCMSV57_GBK © 2004-2011 DesDev Inc. 漏洞利用EXP:plus/recommend.php?action=&aid=1&am ...