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 ...
随机推荐
- RDD, DataFrame or Dataset
总结: 1.RDD是一个Java对象的集合.RDD的优点是更面向对象,代码更容易理解.但在需要在集群中传输数据时需要为每个对象保留数据及结构信息,这会导致数据的冗余,同时这会导致大量的GC. 2.Da ...
- gitlab卸载
1.停止gitlab gitlab-ctl stop 2.卸载gitlab(注意这里写的是gitlab-ce) rpm -e gitlab-ce 3.查看gitlab进程 ps aux | grep ...
- 史上最全的MonkeyRunner自动化测试从入门到精通(1)
原文地址https://zhuanlan.zhihu.com/p/26043620 MonkeyRunner使用 #-*- coding:utf-8 –*- from com.android.monk ...
- C语言中exit函数的使用
exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束 return() 是当前函数返回,当然如果是在主函数main, 自然也就结束当前进程了,如果不是,那就是退回上一 ...
- 使用RequireJS并实现一个自己的模块加载器 (二)
2017 新年好 ! 新年第一天对我来说真是悲伤 ,早上兴冲冲地爬起来背着书包跑去实验室,结果今天大家都休息 .回宿舍的时候发现书包湿了,原来盒子装的牛奶盖子松了,泼了一书包,电脑风扇口和USB口都进 ...
- MySQL connector c++使用笔记
MySQL的connector官方地址: http://dev.mysql.com/downloads/connector/ 针对c++来说, 可以选择c或者c++的库. c++的实现是参考了java ...
- ubuntu14.04 安装apache+mysql+php
1.安装apache sudo apt-get update sudo apt-get install apache2 这时http://你机器的ip,就可以访问了. 2.安装mysql sudo a ...
- Python3:sqlalchemy对sybase数据库操作,非sql语句
Python3:sqlalchemy对sybase数据库操作,非sql语句 # python3 # author lizm # datetime 2018-02-01 10:00:00 # -*- c ...
- 【转】为什么我的DIV块前总有空隙?
在做网站项目时,博主爱吾所爱(爱生活=爱技术)很偶然地碰到一个奇怪的事情.我的DIV嵌套在另一个DIV里,总是出现这样一行空隙: Firebug查看内外两层DIV的margin, padding, l ...
- 【eclipse】运行maven项目clean tomcat7:run报错
问题: Failed to execute goal org.apache.maven.plugins:maven-clean-plugin:2.5:clean 解决: 关闭进程javaw.exe,然 ...