原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9959865.html

SpringBoot整合JPA进行数据库开发

步骤

第一步:添加必要的jar包

<dependency>
<groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl.version}</version>
</dependency>

第二步:添加必要的配置

spring.datasource.url = jdbc\:h2\:file\:D\:\\testdb;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.username = sa
spring.datasource.password = sa
spring.datasource.driverClassName =org.h2.Driver

第三步:添加实体,并添加注解

@Entity
@Table(name = "USER")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int useId;
@Column
private String useName;
@Column
private UseSex useSex;
@Column
private int useAge;
@Column(unique = true)
private String useIdNo;
@Column(unique = true)
private String usePhoneNum;
@Column(unique = true)
private String useEmail;
@Column
private LocalDateTime createTime;
@Column
private LocalDateTime modifyTime;
@Column
private UseState useState;
}

第四步:添加持久层

@Repository
public interface UserRepository extends JpaRepository {
}

注意:

继承自JpaRepository的持久层可以直接使用其定义好的CRUD操作,其实只有增删查操作,关于修改的操作还是需要自定义的。

第五步:持久层的使用

@Service
public class UserService {
@Autowired
private UserRepository repository;
public ResponseEntity addUser(final User user) {
return new ResponseEntity<>(repository.save(user),HttpStatus.OK);
}
}

注意:其实在JpaRepository中已经定义了许多方法用于执行实体的增删查操作。

JPA高级功能

方法名匹配

在UserRepository中定义按照规则命名的方法,JPA可以将其自动转换为SQL,而免去手动编写的烦恼,比如定义如下方法:

User getUserByUseIdNo(String useIdNo);

JPA会自动将其转换为如下的SQL:

select * from USER where use_id_no = ?

下面简单罗列方法命名规则:

关键字 例子 sql
And findByNameAndAge ...where x.name=?1 and x.age=?2
Or findByNameOrAge ...where x.name=?1 or x.age=?2
Between findByCreateTimeBetween ...where x.create_time between ?1 and ?2
LessThan findByAgeLessThan ...where x.age < ?1
GreaterThan findByAgeGreaterThan ...where x.age > ?1
IsNull findByAgeIsNull ...where x.age is null
IsNotNull,NotNull findByAgeIsNotNull ...where x.age not null
Like findByNameLike ...where x.name like ?1
NotLike findByNameNotLike ...where x.name not like ?1
OrderBy findByAgeOrderByNameDesc ...where x.age =?1 order by x.name desc
Not findByNameNot ...where x.name <>?1
In findByAgeIn ...where x.age in ?1
NotIn findByAgeNotIn ...where x.age not in ?1

@Query注解

使用@Query注解在接口方法之上自定义执行SQL。

@Modifying
@Query(value = "update USER set USE_PHONE_NUM = :num WHERE USE_ID= :useId", nativeQuery = true)
void updateUsePhoneNum(@Param(value = "num") String num, @Param(value = "useId") int useId);

上面的更新语句必须加上@Modifying注解,其实在JpaRepository中并未定义更新的方法,所有的更新操作均需要我们自己来定义,一般采用上面的方式来完成。

/**
* 表示一个查询方法是修改查询,这会改变执行的方式。只在@Query注解标注的方法或者派生的方法上添加这个注解,而不能
* 用于默认实现的方法,因为这个注解会修改执行方式,而默认的方法已经绑定了底层的APi。
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Documented
public @interface Modifying {
boolean flushAutomatically() default false;
boolean clearAutomatically() default false;
}

JPQL(SQL拼接)

使用JPQL需要在持久层接口的实现列中完成,即UserRepositoryImpl,这个类是UserRepository的实现类,我们在其中定义JPQL来完成复杂的SQL查询,包括动态查询,连表查询等高级功能。

QBE(QueryByExampleExecutor)

使用QBE来进行持久层开发,需要用到两个接口类,Example和ExampleMatcher,开发方式如下:

List users = repository.findAll(Example.of(user));

或者配合ExampleMarcher使用:

ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreCase();
List users = repository.findAll(Example.of(user, matcher));

以上逻辑一般位于service之中。其中user模型中保存着查询的条件值,null的字段不是条件,只有设置了值的字段才是条件。ExampleMatcher是用来自定义字段匹配模式的。

处理枚举

​ 使用Spring-Data-Jpa时,针对枚举的处理有两种方式,对应于EnumType枚举的两个值:

public enum EnumType {
/** Persist enumerated type property or field as an integer. */
ORDINAL,
/** Persist enumerated type property or field as a string. */
STRING
}

​ 其中ORDINAL表示的是默认的情况,这种情况下将会将枚举值在当前枚举定义的序号保存到数据库,这个需要是从0开始计算的,正对应枚举值定义的顺序。STRING表示将枚举的名称保存到数据库中。

​ 前者用于保存序号,这对枚举的变更要求较多,我们不能随便删除枚举值,不能随意更改枚举值的位置,而且必须以0开头,而这一般又与我们定义的业务序号不一致,限制较多,一旦发生改变,极可能造成业务混乱;后者较为稳妥。

​ 正常情况下,如果不在枚举字段上添加@Enumerated注解的话,默认就以ORDINAL模式存储,若要以STRING模式存储,请在枚举字段上添加如下注解:

@Enumerated(EnumType.STRING)
@Column(nullable=false) // 一般要加上非null约束
private UseState useState;

分页功能

​ Spring-Data-Jpa中实现分页使用到了Pageable接口,这个接口将作为一个参数参与查询。

​ Pageable有一个抽象实现类AbstractPageRequest,是Pageable的抽象实现,而这个抽象类有两个实现子类:PageRequest和QPageRequest,前者现已弃用,现在我们使用QPageRequest来定义分页参数,其有三个构造器:

public QPageRequest(int page, int size) {
this(page, size, QSort.unsorted());
}
public QPageRequest(int page, int size, OrderSpecifier<?>... orderSpecifiers) {
this(page, size, new QSort(orderSpecifiers));
}
public QPageRequest(int page, int size, QSort sort) {
super(page, size);
this.sort = sort;
}

​ 在这里面我们可以看到一个QSort,这个QSort是专门用于与QPageRequest相配合使用的类,用于定义排序规则。默认情况下采用的是无排序的模式,即上面第一个构造器中的描述。

​ 要构造一个QSort需要借助querydsl来完成,其中需要OrderSpecifier来完成。

​ 这里有个简单的用老版本实现的分页查询:

    public ResponseEntity<Page<User>> getUserPage(final int pageId) {
Sort sort = new Sort(new Sort.Order(Sort.Direction.DESC, "useId"));
Page<User> users = repository.findAll(new PageRequest(pageId,2, sort));
return new ResponseEntity<>(users, HttpStatus.OK);
}

​ 至于新版本的分页查询和排序涉及内容较多较复杂,稍后再看。

注意:分页首页页码为0

SpringBoot整合系列-整合JPA的更多相关文章

  1. SpringBoot整合系列--整合MyBatis-plus

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/10125279.html SpringBoot整合MyBatis-plus 步骤 第一步: ...

  2. SpringBoot整合系列-整合H2

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9959855.html SpringBoot整合H2内存数据库 一般我们在测试的时候习惯于 ...

  3. SpringBoot整合系列-整合SpringMVC

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9984607.html SpringBoot整合Spring MVC 步骤 第一步:添加必 ...

  4. SpringBoot整合系列-整合MyBatis

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9971036.html SpringBoot整合Mybatis 步骤 第一步:添加必要的j ...

  5. SpringBoot整合系列-整合Swagger2

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9959844.html SpringBoot整合Swagger2 步骤 第一步:添加必要的 ...

  6. SpringBoot整合系列-PageHelper分页插件

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9971043.html SpringBoot整合MyBatis分页插件PageHelper ...

  7. SpringBoot系列-整合Mybatis(注解方式)

    目录 一.常用注解说明 二.实战 三.测试 四.注意事项 上一篇文章<SpringBoot系列-整合Mybatis(XML配置方式)>介绍了XML配置方式整合的过程,本文介绍下Spring ...

  8. springboot整合spring Data JPA

    今天敲代码,一连串的错误,我也是服气~果然,我们不是在出bug,就是在找bug的路上…… 今天完成的是springboot整合spring data JPA ,出了一连串的错,真是头大 java.sq ...

  9. SpringBoot第四集:整合JdbcTemplate和JPA(2020最新最易懂)

    SpringBoot第四集:整合JdbcTemplate和JPA(2020最新最易懂) 当前环境说明: Windows10_64 Maven3.x JDK1.8 MySQL5.6 SpringTool ...

随机推荐

  1. npm几个常用命令

    npm install xxx 安装模块(例如npm install express 就会默认安装express的最新版本,也可以通过在后面加版本号的方式安装指定版本,如npm install exp ...

  2. 用JS来判断版本号比如v21.2.2.2和v21.2.2.2.15

    当判断两个版本号的时候,不能单纯的去点然后相互比较,版本比较可能比较特殊,但是分析起来又挺简单的,既然不能直接去点比较,那就拆分成数组,一组一组对应的去比,为了能正常的进行比较 如果上一个版本长度小于 ...

  3. CROS+node-basis+ajax

    $.ajax({ url: this.baseUrl + this.restful.showDesigerViewList, type: "post", dataType: &qu ...

  4. 堆排序应用之topK问题

    题目:求海量数据(正整数)按逆序排列的前k个数(topK),因为数据量太大,不能全部存储在内存中,只能一个一个地从磁盘或者网络上读取数据,请设计一个高效的算法来解决这个问题. 第一行用户输入K,代表要 ...

  5. CS20SI-tensorflow for research笔记: Lecture3

    本文整理自知乎专栏深度炼丹,转载请征求原作者同意. 本文的全部代码都在原作者GitHub仓库github CS20SI是Stanford大学开设的基于Tensorflow的深度学习研究课程. Tens ...

  6. [Swift]LeetCode279. 完全平方数 | Perfect Squares

    Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 1 ...

  7. [Swift]LeetCode434. 字符串中的单词数 | Number of Segments in a String

    Count the number of segments in a string, where a segment is defined to be a contiguous sequence of ...

  8. [Swift]LeetCode749. 隔离病毒 | Contain Virus

    A virus is spreading rapidly, and your task is to quarantine the infected area by installing walls. ...

  9. Android device debug (adb) by Charge Only mode

    Android device debug by Charge Only mode Method 1 Connect devices to computer and execute lsusb Find ...

  10. Python常见面试题

    Q 1:Python 有哪些特点和优点? 作为一门编程入门语言,Python 主要有以下特点和优点: ● 可解释● 具有动态特性● 面向对象● 简明简单● 开源● 具有强大的社区支持当然,实际上 Py ...