在这里我们创建实体类与继承了JpaRepository
的接口,下面的增删改查都以实体类与接口做示例。
import java.io.Serializable;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Id;
import javax.persistence.Column;
@Data
@Entity
@Table(name="user_info")
public class UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
/**
* id
*/
@Id
private String id;
/**
* 登录名
*/
@Column(name = "login_name")
private String loginName;
/**
* 密码
*/
private String password;
/**
* 年龄
*/
private int age;
}
定义一个接口,继承JpaRepository
。
public interface UserInfoRepository extends JpaRepository<UserInfo, String> {
}
在JpaRepository
中,当保存的实体类主键ID在数据库中存在时进行修改操作,不存在则进行保存。
@Autowired
private UserInfoRepository userInfoRepository;
public void addUserInfo() {
UserInfo userInfo = new UserInfo();
userInfo.setId("jHfnKlsCvN");
userInfo.setLoginName("登录名");
userInfo.setPassword("123456");
userInfo.setAge(18);
// 保存或修改用户信息, 并返回用户实体类
UserInfo save = userInfoRepository.save(userInfo);
}
@Autowired
private UserInfoRepository userInfoRepository;
public void deleteUserInfo() {
UserInfo userInfo = new UserInfo();
userInfo.setId("jHfnKlsCvN");
userInfo.setLoginName("登录名");
userInfo.setPassword("123456");
userInfo.setAge(18);
// 根据实体类删除
userInfoRepository.delete(userInfo);
}
@Autowired
private UserInfoRepository userInfoRepository;
public void deleteUserInfo() {
// 根据实体类主键删除
userInfoRepository.deleteById("111");
}
在JpaRepository
中根据某一个字段或者某几个字段查询时,就使用findBy
方法。
这里给个例子,假设,我想根据loginName
查询用户信息,就可以用findByLoginName
查询用户信息,如果有多个条件后面就继续拼接AndXXX
。
假设,我想查询loginName
等于某值,并且password
等于某值的,就可以使用findByLoginNameAndPassword
。
public interface UserInfoRepository extends JpaRepository<UserInfo, String> {
// 根据登录名查询用户信息
UserInfo findByLoginName(String loginName);
// 根据登录名和密码查询用户信息
UserInfo findByLoginNameAndPassword(String loginName, String password);
}
在JpaRepository
中根据某一个字段或者某几个字段查询时,就使用findAllBy
方法,而接口根据某个条件查询写法跟查询单个信息时一样。
这里给个例子,假设,我想查询loginName
等于某值的所有用户信息时,就写做findAllByLoginName
。
public interface UserInfoRepository extends JpaRepository<UserInfo, String> {
// 查询所有登录名叫做XXX的用户
List<UserInfo> findAllByLoginName(String loginName);
}
在UserInfoRepository
中创建一个方法,使用Specification
和Pageable
去做复杂查询以及分页。
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserInfoRepository extends JpaRepository<UserInfo, String> {
// 用于复杂查询
Page<UserInfo> findAll(Specification<UserInfo> specification, Pageable pageable);
}
@Autowired
private UserInfoRepository userInfoRepository;
public void queryUserInfo {
Pageable pageable = org.springframework.data.domain.PageRequest.of(Math.toIntExact(num - 1), pageSize);
Specification<UserInfo> specifications = new Specification<UserInfo>() {
@Override
public Predicate toPredicate(Root<UserInfo> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
// 条件【查询所有登录名等于张三的用户】
predicates.add(criteriaBuilder.equal(root.get("loginName"), "张三"));
return query.where(criteriaBuilder.and(predicates.toArray(new Predicate[0]))).getGroupRestriction();
}
};
// JAVA8 lambda写法
// Specification specifications = (root, query, criteriaBuilder) -> {
// List predicates = new ArrayList<>();
// 条件【查询所有登录名等于张三的用户】
// predicates.add(criteriaBuilder.equal(root.get("loginName"), "张三"));
// return query.where(criteriaBuilder.and(predicates.toArray(new Predicate[0]))).getGroupRestriction();
// };
final Page<UserInfo> planPage = userInfoReportRepository.findAll(specification, pageable);
long totalElements = planPage.getTotalElements();// 总共多少条数据
int totalPages = planPage.getTotalPages();// 总共多少页
}
Specification<UserInfo> specification = (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
// 条件【查询所有登录名等于张三的用户】
predicates.add(criteriaBuilder.like(root.get("loginName"), "%张%"));
return query.where(criteriaBuilder.and(predicates.toArray(new Predicate[0]))).getGroupRestriction();
};
Specification<UserInfo> specification = (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
// 条件【查询大于等于10岁的用户】
predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("age"), 10));
return query.where(criteriaBuilder.and(predicates.toArray(new Predicate[0]))).getGroupRestriction();
};
Specification<UserInfo> specification = (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
// 条件【查询小雨等于20岁的用户】
predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("age"), 20));
return query.where(criteriaBuilder.and(predicates.toArray(new Predicate[0]))).getGroupRestriction();
};
List<String> ids = new ArrayList();
ids.add("1");
ids.add("2");
Specification<UserInfo> specification = (root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
// 条件【查询多个Id】
CriteriaBuilder.In<String> in = criteriaBuilder.in(root.get("id"));
for (String id : ids) {
in.value(id);
}
return query.where(criteriaBuilder.and(in)).getGroupRestriction();
};
toPredicate
方法参数说明:
Root
:主要用于处理实体和字段、实体与实体之间的关系,还可以做join操作;CriteriaQuery
:主要用于对查询结果的处理,有groupBy、orderBy、having、distinct等操作;CriteriaBuilder
:主要是各种条件查询,就像刚刚的equal(等于)操作等;