SpringDataJPA最佳实践(一)简介
在团队中使用SpringDataJPA有一段时间了,也踩过一些坑,这里记录一下学习历程。
1.简介
Spring Data是什么
Spring Data是一个用于简化数据库访问,并支持云服务的开源框架。其主要目标是使得对数据的访问变得方便快捷。 Spring Data 包含多个子项目Spring Data JPA,Spring Data MongoDB 等,官网为 http://projects.spring.io/spring-data/ 。
Spring Data JPA是什么
Spring Data JPA是Spring Data的一个子项目,可以极大的简化JPA的写法,可以在几乎不用写实现的情况下,实现对数据的访问和操作。除了CRUD外,还包括如分页、排序等一些常用的功能。
2.建立项目
使用IDEA建立spring boot项目,pom中如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jazz.test</groupId>
<artifactId>jpa-test</artifactId>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- 热重载使用devtools -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- 使用H2嵌入式数据库 -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
目录结构
配置文件很简单,指定了一个基于文件的单机数据库
server.port=8888
spring.datasource.url=jdbc:h2:file:~/test
spring.datasource.username=sa
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
主类如下,继承CommandLineRunner,run方法会在项目启动后马上运行,方便测试
@SpringBootApplication
public class MainApp implements CommandLineRunner{
public static void main(String[] args) {
SpringApplication.run(MainApp.class, args);
}
@Override
public void run(String... strings) throws Exception {
//测试代码
}
}
3.数据库模型
运行项目,访问 http://localhost:8888/h2-console 进入到h2数据库,现在没有用户定义的表
在domain包下新建实体类
import javax.persistence.Entity;
import javax.persistence.Id;
@Entity
public class Student {
@Id
private String id;
private String name;
private Integer age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
重启项目
再进入h2-console,会发现已经建立好了一个表
接下来就可以愉快地对这个表进行操作了
4.Repository相关接口提供的方法
想要使用spring data jpa提供的各种方法,必须继承相关接口
1:Repository:最顶层的接口,是一个空的接口,目的是为了统一所有Repository的类型,且能让组件扫描的时候自动识别。
2:CrudRepository :是Repository的子接口,提供CRUD的功能
3:PagingAndSortingRepository:是CrudRepository的子接口,添加分页和排序的功能
4:QueryByExampleExecutor:提供了QBE查询
5:JpaRepository:是PagingAndSortingRepository和QueryByExampleExecutor的子接口,增加了一些实用的功能,比如:批量操作等。
在domain包下新建数据访问接口
public interface StudentRepository extends JpaRepository<Student,String> {
}
保存save
在主类中测试保存
@SpringBootApplication
public class MainApp implements CommandLineRunner {
@Autowired
private StudentRepository studentRepository;
public static void main(String[] args) {
SpringApplication.run(MainApp.class, args);
}
@Override
public void run(String... strings) throws Exception {
Student student = new Student();
student.setId(UUID.randomUUID().toString());
student.setName("小明");
student.setAge(18);
studentRepository.save(student);
}
}
热重载项目,此时数据库控制台增加了一条记录
保存方法总结
<S extends T> S save(S entity);//保存实体
<S extends T> Iterable<S> save(Iterable<S> entities); //保存多个实体
<S extends T> S saveAndFlush(S entity);//保存并立刻刷新到数据库
更新update
jpa没有提供更新的方法,保存时先进行查询,如果在表中存在此ID就会进行更新 :( 。
删除delete
提供了如下方法
查询
List<T> findAll(); //查询所有
List<T> findAll(Iterable<ID> ids); //根据id列表查询多个
T findOne(ID id);//根据id查询1个
排序
List<T> findAll(Sort sort);//查找列表并排序
jpa提供了org.springframework.data.domain.Sort类来封装排序条件,它提供了多个构造方法。
studentRepository.findAll(new Sort(Sort.Direction.DESC, "name"));
studentRepository.findAll(new Sort(Sort.Direction.DESC, "name", "age"));
studentRepository.findAll(new Sort(
new Sort.Order(Sort.Direction.DESC,"name"),
new Sort.Order(Sort.Direction.ASC,"age")
));
分页
Page<T> findAll(Pageable pageable);
5 在Repository中使用命名方法
直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的条件关键字写法如下:
| 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 | 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 (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< Age> ages) | … where x.age in ?1 |
| NotIn | findByAgeNotIn(Collection< Age> age) | … 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) |
目前支持的动作关键字写法如下:
| 关键字 | 示例 | 含义 | 备注 |
|---|---|---|---|
| delete | void deleteByName(String name); | 根据name进行删除 | |
| remove | void removeByName(String name); | 根据name进行删除 | |
| count | int countByNameAndAge(String name,Integer age); | 根据name和age统计 | |
| find/read/query… | List< E> findByName(String name) | 推荐使用find | |
| findOne/… | E findOneByName(String name) | 查找一个对象时推荐使用,而不是使用find | |
| findTopN | List< Student> findTop3ByName(String name); | 查找3条记录 | |
| findTop/findFirst | Student findTopByName(String name); | 查找第一条 | |
| findDistinctBy | List< Student> findTopByName(String name); | 查找去重 |
排序
分页
SpringDataJPA最佳实践(一)简介的更多相关文章
- klg-jpa:spring-data-jpa 最佳实践
klg-jpa:spring-data-jpa 最佳实践 项目介绍 码云地址:https://gitee.com/klguang/klg-jpa JPA是sun为POJO持久化制定的标准规范,用来操作 ...
- 《AngularJS深度剖析与最佳实践》简介
由于年末将至,前阵子一直忙于工作的事务,不得已暂停了微信订阅号的更新,我将会在后续的时间里尽快的继续为大家推送更多的博文.毕竟一个人的力量微薄,精力有限,希望大家能理解,仍然能一如既往的关注和支持sh ...
- XPages访问关系型数据库技术与最佳实践
XPage 对于 Domino 开发人员的一大好处就是能够很方便和高效的访问关系型数据库.本文通过实例代码展现了在 XPage 中访问关系型数据库的具体步骤 , 同时讲解了一些在 XPage 中高效访 ...
- JavaScript best practices JS最佳实践
JavaScript best practices JS最佳实践 0 简介 最佳实践起初比较棘手,但最终会让你发现这是非常明智之举. 1.合理命名方法及变量名,简洁且可读 var someItem = ...
- Mysql数据库调优和性能优化的21条最佳实践
Mysql数据库调优和性能优化的21条最佳实践 1. 简介 在Web应用程序体系架构中,数据持久层(通常是一个关系数据库)是关键的核心部分,它对系统的性能有非常重要的影响.MySQL是目前使用最多的开 ...
- 探索云数据库最佳实践 阿里云开发者大会数据库专场邀你一起Code up!
盛夏.魔都.科技 三者在一起有什么惊喜? 7月24日,阿里云峰会·上海——开发者大会将在上海世博中心盛大启程,与未来世界的开发者们分享数据库.云原生.开源大数据等领域的技术干货,共同探讨前沿科技趋势, ...
- 《开源安全运维平台:OSSIM最佳实践》内容简介
<开源安全运维平台:OSSIM最佳实践 > 李晨光 著 清华大学出版社出版 内 容 简 介在传统的异构网络环境中,运维人员往往利用各种复杂的监管工具来管理网络,由于缺乏一种集成安全运维平台 ...
- memcache的最佳实践方案
1.memcached的基本设置 1)启动Memcache的服务器端 # /usr/local/bin/memcached -d -m 10 -u root -l 192.168.0.200 -p 1 ...
- ODCA最佳实践翻译:Architecting Cloud-Aware Applications (一)
Architecting Cloud-Aware Applications ** ODCA(Open Data Center Alliance)最佳实践 ** MagicBowen(e.bowen.w ...
随机推荐
- mysql索引详解(转)
什么是索引 索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存.如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录.表里面的 ...
- ThreadLocal类,实例测试,FutureTask类,实例测试。
1:测试ThreadLocal类, 为每个线程域保存局部变量.例如下面的例子. ThreadLocal为每个线程保存了一个Test对象, 那么当执行线程时,每个线程中的test具有唯一性.某一个线 ...
- PHP接收json格式的POST数据
/** * 获取 post 参数; 在 content_type 为 application/json 时,自动解析 json * @return array */ private function ...
- 安装memcached扩展 验证过了可行
. 安装libmemached 复制代码 代码如下: wget https://launchpad.net/libmemcached/1.0/1.0.16/+download/libmemcached ...
- [LeetCode]83. Remove Duplicates from Sorted List(排序链表去重)
Given a sorted linked list, delete all duplicates such that each element appear only once. For examp ...
- SQL学习笔记五之MySQL索引原理与慢查询优化
阅读目录 一 介绍 二 索引的原理 三 索引的数据结构 四 聚集索引与辅助索引 五 MySQL索引管理 六 测试索引 七 正确使用索引 八 联合索引与覆盖索引 九 查询优化神器-explain 十 慢 ...
- 20145104张家明 《Java程序设计》第一周学习总结
20145104张家明 <Java程序设计>第1周学习总结 教材学习内容总结 在开学的第一周,通过了看书进行了系统的学习java,首先简单的了解java的发展历程,然后了解了JVM.JRE ...
- HDU 1556 Color the ball(线段树:区间更新)
http://acm.hdu.edu.cn/showproblem.php?pid=1556 题意: N个气球,每次[a,b]之间的气球涂一次色,统计每个气球涂色的次数. 思路: 这道题目用树状数组和 ...
- zeptojs库解读1之整体框架
首先看的是整体框架, // zepto骨骼,这个函数的作用使得Zepto(slector, context)使用很多$.fn里面的方法 var Zepto = (function(){ // zept ...
- linux中find与rm实现查找并删除目录或文件
linux 下用find命令查找文件,rm命令删除文件. 删除指定目录下指定文件find 要查找的目录名 -name .svn |xargs rm -rf 删除指定名称的文件或文件夹: find -t ...