- springdataJpa的继承结构
其中JpaSpecificationExecutor接口是一个单独的用于高级查询(排序,分页,自定义条件分页)的接口,需要与JpaRepository组合使用。在开发中使用的最多的是JpaRepository。下面按照继承结构一一示例:
- 所需依赖
<?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>
<!-- springboot父类工程 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
</parent>
<groupId>com.bjsxt.spring.boot.data.jpa</groupId>
<artifactId>07SpringbootdataJpa</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.7</java.version>
<thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
<thymeleaf-layout-dialect.version>2.0.4</thymeleaf-layout-dialect.version>
</properties>
<dependencies> <!-- springBoot 的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- thymeleaf 的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- spring-data-jpa 的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.9</version>
</dependency>
<!-- 测试工具的启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
</dependencies>
</project>
- 实体化对象(举例中使用)
/**
* @Author:CarlosXu
* @Date:2019/8/10 0010
* @Description:com.bjsxt.spring.boot.data.jpa
*/
@Entity
@Table(name = "users")
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Integer id;
@Column(name = "name")
private String name;
@Column(name = "age")
private Integer age;
public Users() {
}
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
public Users(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Users{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
其中所有接口中需要传递的第一个参数为实体类,第二个为操作对象的主键
- Repository
接口:
public interface UsersRepository extends Repository<Users,Integer> {
List<Users> findByName(String name);
List<Users> findByNameAndAge(String name,Integer age);
List<Users> findByNameLike(String name);
}
测试:
/**
* @Author:CarlosXu
* @Date:2019/8/10 0010
* @Description:com.bjsxt.test
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {App.class})
public class RepositoryDemoTest {
@Autowired
private UsersRepository usersRepository;
@Test
public void test01() {
List<Users> name = this.usersRepository.findByName("伽罗");
for (Users u:
name) {
System.out.println(u);
}
}
@Test
public void test02() {
List<Users> name = this.usersRepository.findByNameAndAge("伽罗",18);
for (Users u:
name) {
System.out.println(u);
}
}
@Test
public void test03() {
List<Users> name = this.usersRepository.findByNameLike("伽%");
for (Users u:
name) {
System.out.println(u);
}
}
}
或者基于@QUERY方式实现jdbc操作:
public interface UsersRepositoryAnnotation extends Repository<Users,Integer> {
@Query("FROM Users WHERE name = ?")
List<Users> findByName(String name);
@Query(value = "select * from users where name=? and age=?",nativeQuery = true)
List<Users> findByNameAndAge(String name, Integer age);
@Query("FROM Users where name like ?")
List<Users> findByNameLike(String name);
@Query("update Users set name= ? where id=?")
@Modifying
void updateUsers(String name,Integer id);
}
注意:当需要对数据库更新操作时需要加上@Modifying注解
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {App.class})
public class RepositoryAnnotationDemoTest {
@Autowired
private UsersRepositoryAnnotation usersRepositoryAnnotation;
@Test
public void test01() {
List<Users> name = this.usersRepositoryAnnotation.findByName("伽罗");
for (Users u:
name) {
System.out.println(u);
}
}
@Test
public void test02() {
List<Users> name = this.usersRepositoryAnnotation.findByNameAndAge("伽罗",18);
for (Users u:
name) {
System.out.println(u);
}
}
@Test
public void test03() {
List<Users> name = this.usersRepositoryAnnotation.findByNameLike("伽%");
for (Users u:
name) {
System.out.println(u);
}
}
@Test
@Transactional
@Rollback(false)
public void test04() {
this.usersRepositoryAnnotation.updateUsers("黄忠",3);
}
}
- CrudRepository(基本增删改查操作)
接口:
public interface UsersCrudRepository extends CrudRepository<Users,Integer> {
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {App.class})
public class CrudRepositoryDemoTest {
@Autowired
private UsersCrudRepository crudRepository;
@Test
public void test01() {
List<Users> name = (List<Users>) this.crudRepository.findAll();
for (Users u:
name) {
System.out.println(u);
}
}
@Test
public void test02() {
Users users=new Users("伽罗",23);
this.crudRepository.save(users);
}
//更新使用的也是save方法,会根据主键查询,如果数据库存在则更新,如果不存在,则添加
//在底层已经添加了事务的注解,这里不需要再添加
@Test
public void test03() {
Users users=new Users("狄仁杰",23);
users.setId(5);
this.crudRepository.save(users);
}
}
- PagingAndSortingRepository(分页和查询操作)
接口:
public interface UsersPageAndSorting extends PagingAndSortingRepository<Users,Integer> {
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {App.class})
public class PageAndSortTest {
@Autowired
private UsersPageAndSorting usersPageAndSorting;
//分页查询
@Test
public void test001() {
Sort.Order order =new Sort.Order(Sort.Direction.DESC,"id");
Sort sort=new Sort(order);
List<Users> all = (List<Users>) this.usersPageAndSorting.findAll(sort);
for (Users u:
all) {
System.out.println(u);
}
}
//分页查询
@Test
public void test01() {
//注意:分页第一页从0开始
Pageable pageable=new PageRequest(0,2);
Page<Users> all = this.usersPageAndSorting.findAll(pageable);
System.out.println("总页数:"+all.getTotalPages());
System.out.println("总数:"+all.getTotalElements());
List<Users> content = all.getContent();
for (Users u:
content) {
System.out.println(u);
}
}
//排序-分页查询
@Test
public void test02() {
Sort.Order order =new Sort.Order(Sort.Direction.DESC,"id");
Sort sort=new Sort(order);
//注意:分页第一页从0开始
Pageable pageable=new PageRequest(0,2,sort);
Page<Users> all = this.usersPageAndSorting.findAll(pageable);
System.out.println("总页数:"+all.getTotalPages());
System.out.println("总数:"+all.getTotalElements());
List<Users> content = all.getContent();
for (Users u:
content) {
System.out.println(u);
}
}
}
- JpaRepository
接口:
public interface UsersJpaRepository01 extends JpaRepository<Users,Integer> {
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {App.class})
public class JpaDemoTest {
@Autowired
private UsersJpaRepository01 usersJpaRepository01;
@Test
public void test01(){
Users users=new Users("伽罗",18);
this.usersJpaRepository01.save(users);
}
@Test
public void test02(){
Sort sort=new Sort(Sort.Direction.DESC,"id");
Pageable pageable=new PageRequest(0,2,sort);
Page<Users> all = this.usersJpaRepository01.findAll(pageable);
List<Users> content = all.getContent();
for (Users u:
content) {
System.out.println(u);
}
}
}
- JpaSpecificationExecutor
接口(不可单独使用,因为时单独的,没有继承Repository结构):
public interface UsersJpaAndSpecification extends JpaRepository<Users,Integer>
, JpaSpecificationExecutor<Users> {
}
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {App.class})
public class JpaSpecificationTest {
@Autowired
private UsersJpaAndSpecification usersJpaAndSpecification;
//按照特定条件查询,并将结果进行分页和排序
@Test
public void test02(){
Sort sort=new Sort(Sort.Direction.DESC,"id");
Pageable pageable=new PageRequest(0,2,sort);
Specification<Users> spec=new Specification<Users>() {
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
List<Predicate> list=new ArrayList<>();
list.add(criteriaBuilder.equal(root.get("age"),18));
Predicate[] pred=new Predicate[list.size()];
return criteriaBuilder.and(list.toArray(pred));
}
};
Page<Users> all = this.usersJpaAndSpecification.findAll(spec,pageable);
List<Users> content = all.getContent();
for (Users u:
content) {
System.out.println(u);
}
}
}