1.ORM框架
建立Pojo与数据库的关系,将数据持久化,就是将从前台获取的数据保存到数据库中,避免了数据在内存中被GC收集。
2.核心接口
- Repository
- CrudRepository
- PagingAndSortingRepository
- JpaRepository
- JPASpecificationExectuor
3.方法名称查询
接口:
public interface UserRepositoryByName extends Repository<Users,Integer> {
//方法的名称必须遵循驼峰命名法则,findBy(关键字)+属性名称(首字母大写)+查询条件(首字母大写)
List<Users> findByNameEquals(String name);
List<Users> findByNameAndAge(String name, Integer age);
List<Users>findByNameLike(String name);//模糊查询
}
测试:
@Test
void contextLoads() {
System.out.println("hello");
Users users = new Users();
users.setAddress("江苏市张家港市");
users.setAge(20);
users.setName("qxd");
Users save = userRepository.save(users);
System.out.println(save.toString());
}
@Test
public void testFindByName(){
List<Users> list = userRepositoryByName.findByNameEquals("qxd");
for (Users users : list) {
System.out.println(users.toString());
}
}
@Test
public void testFindByName(){
List<Users> list = userRepositoryByName.findByNameAndAge("liut1ao",22);
for (Users users : list) {
System.out.println(users.toString());
}
List<Users> list = userRepositoryByName.findByNameLike
("%liu%");
}
结果可以为null
4.Query查询
接口:
p
ublic interface UsersRepositoryQueryAnnotation extends Repository<Users,Integer> {
@Query("select users from Users users where name =?1")
List<Users> querybyNameUserHQL(String name);
@Query(value = "select * from t_users where name = ?1",nativeQuery = true )
List<Users> queryByNameUserSQL(String name);
//update
@Query(value = "update Users set name = ?1 where id = ?2")
//@Query(value = "update Users users set users.name = ?1 where users.id = ?2")
@Modifying//需要执行一个更新的操作
//@Transactional //事务
//三个注解
void updateUsersNameById(String name ,Long id);
}
测试:
@Test
public void testQueryHQL(){
List<Users> list = usersRepositoryQueryAnnotation.querybyNameUserHQL("qin");
for (Users users : list) {
System.out.println(users.toString());
}
}
@Test
@Transactional //事务
@Rollback(value = false)
public void testUpdateUsersNameById(){
usersRepositoryQueryAnnotation.updateUsersNameById("qqq",10);
}
5.CrudRepository接口
主要完成一些增删改查的工作
如果save的数据原表中已经存在,则使用update将原表中的数据进行覆盖 如果不存在,则进行添加。
源码为:
Transactional
public <S extends T> S save(S entity) {
if (this.entityInformation.isNew(entity)) {
this.em.persist(entity);
return entity;
} else {
return this.em.merge(entity);
}
}
测试:
@Test
public void testCrudRepository(){
Users users = new Users();
users.setName("psy");
users.setAge(22);
users.setAddress("天津");
users.setId(1);
userRepositoryCrudRepository.save(users);
}
@Test
public void testFind(){
Users users = userRepositoryCrudRepository.findById(1).get();
System.out.println(users.toString());
}
@Test
public void testFindAll(){
Iterable<Users> all =userRepositoryCrudRepository.findAll();
for (Users user: all) {
System.out.println(user.toString());
}
@Test
public void deleteById(){
userRepositoryCrudRepository.deleteById(1);
}
6.PagingAndSortingRepository接口
该接口提供了分页与排序的操作
测试:
// PagingAndSortingRepository接口测试
@Test
public void testPagingAndSortingRepository(){
Sort.Order order = new Sort.Order(Sort.Direction.DESC, "id");
Sort sort = Sort.by(order);
//Sort对象封装了排序的功能
Iterable<Users> all = userRepositoryPagingAndSorting.findAll(sort);
for (Users users : all) {
System.out.println(users.toString());
}
}
// PagingAndSortingRepository接口测试
@Test
public void testPagingAndSortingRepository2(){
//page:当前页
//size:每页的条数
Sort sort = Sort.by(new Sort.Order(Sort.Direction.ASC, "id"));
Pageable pageable = PageRequest.of(1,4,sort);
Page<Users> page = userRepositoryPagingAndSorting.findAll(pageable);
System.out.println("总条数" + page.getTotalElements());
System.out.println("总页数" + page.getTotalPages());
List<Users> content = page.getContent();
for (Users users : content) {
System.out.println(users.toString());
}
}
7.JpaRepository接口
继承图:
image.png
对父接口的返回值进行适配
public interface UserRepository extends JpaRepository<Users,Integer> {
}
测试:
// jpaRepository接口测试
@Test
public void jpaRepository(){
//page:当前页
//size:每页的条数
int page = 0;
int size = 3;
Sort sort = Sort.by(new Sort.Order(Sort.Direction.ASC, "id"));
Pageable pageable = PageRequest.of(page, size, sort);
Page<Users> all = userRepository.findAll(pageable);
for (Users users : all) {
System.out.println(users.toString());
}
}
8.JPASpecificationExectuor接口
该接口主要提供了多条件查询的支持,并且可以在查询中添加分页与排序。注意:JPASpecificationExectuor是单独存在的,完全独立。
image.png
image.png
接口:
//多条件查询
public interface UsersRepositorySpecification extends JpaRepository<Users,Integer>,
JpaSpecificationExecutor<Users>{
}
测试:
1.多条件查询的第一种写法
@Autowired
private UsersRepositorySpecification usersRepositorySpecification;
@Test
//jpaSpecificationExecutor接口测试
public void testJpaSpecificationExecutor1(){
/*
*
*Specification<Users>:用于封装查询条件
*
* */
Specification<Users> spec= new Specification<Users>() {
//Predicate 封装单个查询条件
/*
* Root<Users> root:查询对象的属性封装
*CriteriaQuery<?> criteriaQuery:封装了我们要执行的查询中的各个部分的信息:select from order by
*CriteriaBuilder criteriaBuilder:查询条件构造器,定义不同的查询条件
* */
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//where name = "qin"
/*
* 参数1:查询的属性
* 参数2:条件的值
*
* */
Predicate pre = criteriaBuilder.equal(root.get("name"),"qin");
return pre;
}
};
List<Users> list = usersRepositorySpecification.findAll(spec);
for (Users users : list) {
System.out.println(users.toString());
}
}
@Autowired
private UsersRepositorySpecification usersRepositorySpecification;
@Test
//jpaSpecificationExecutor接口测试
public void testJpaSpecificationExecutor5(){
/*
*
*Specification<Users>:用于封装查询条件
*
* */
Specification<Users> spec= new Specification<Users>() {
//Predicate 封装单个查询条件
/*
* Root<Users> root:查询对象的属性封装
*CriteriaQuery<?> criteriaQuery:封装了我们要执行的查询中的各个部分的信息:select from order by
*CriteriaBuilder criteriaBuilder:查询条件构造器,定义不同的查询条件
* */
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//where name = "qin" and age=20
/*
*/
//先写前面两个,在写后面一个
// Predicate predicate = criteriaBuilder.and(criteriaBuilder.equal(root.get("name"), "qin"),
// criteriaBuilder.equal(root.get("age"), 22));
// Predicate predicate1 = criteriaBuilder.or(predicate, criteriaBuilder.equal(root.get("id"), 2));
// return predicate1;
List<Predicate>predicateList = new ArrayList<>();
predicateList.add(criteriaBuilder.equal(root.get("name"), "qin")) ;
predicateList.add(criteriaBuilder.equal(root.get("age"), 20));
Predicate[] arr = new Predicate[predicateList.size()];
//列表变换成数组
Predicate[] predicates = predicateList.toArray(arr);
// return criteriaBuilder.and(predicates);
Predicate restriction = criteriaQuery.where(predicates).getRestriction();
return restriction;
}
};
Sort sort = Sort.by(new Sort.Order(Sort.Direction.DESC, "id"));
List<Users> list = usersRepositorySpecification.findAll(spec,sort);
for (Users users : list) {
System.out.println(users.toString());
}
}
上面和下面这两种写法最后得到效果是相同的。
@Test
//jpaSpecificationExecutor接口测试
public void testJpaSpecificationExecutor2(){
/*
*Specification<Users>:用于封装查询条件
*
* */
Specification<Users> spec= new Specification<Users>() {
//Predicate 封装单个查询条件
/*
* Root<Users> root:查询对象的属性封装
*CriteriaQuery<?> criteriaQuery:封装了我们要执行的查询中的各个部分的信息:select from order by
*CriteriaBuilder criteriaBuilder:查询条件构造器,定义不同的查询条件
* */
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//where name = "qin" and age=20
/*
*/
List<Predicate>preList = new ArrayList<>();
preList.add(criteriaBuilder.equal(root.get("name"),"qin"));
preList.add(criteriaBuilder.equal(root.get("age"),20));
//造一个等长度的空数组
Predicate[] arr = new Predicate[preList.size()];
//将preList 复制到arr里面去
Predicate[] predicates = preList.toArray(arr);
//两个条件用and连接
return criteriaBuilder.and(predicates);
}
};
List<Users> list = usersRepositorySpecification.findAll(spec);
for (Users users : list) {
System.out.println(users.toString());
}
}
2.多条件查询的第二种写法
@Test
//jpaSpecificationExecutor接口测试
public void testJpaSpecificationExecutor3(){
/*
*
*Specification<Users>:用于封装查询条件
*
* */
Specification<Users> spec= new Specification<Users>() {
//Predicate 封装单个查询条件
/*
* Root<Users> root:查询对象的属性封装
*CriteriaQuery<?> criteriaQuery:封装了我们要执行的查询中的各个部分的信息:select from order by
*CriteriaBuilder criteriaBuilder:查询条件构造器,定义不同的查询条件
* */
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//where name = "qin" and age=20
/*
*/
return criteriaBuilder.and(criteriaBuilder.equal(root.get("name"),"qin"),
criteriaBuilder.equal(root.get("age"),22));
}
};
List<Users> list = usersRepositorySpecification.findAll(spec);
for (Users users : list) {
System.out.println(users.toString());
}
}
@Test
//jpaSpecificationExecutor接口测试
public void testJpaSpecificationExecutor4(){
/*
*
*Specification<Users>:用于封装查询条件
*
* */
Specification<Users> spec= new Specification<Users>() {
//Predicate 封装单个查询条件
/*
* Root<Users> root:查询对象的属性封装
*CriteriaQuery<?> criteriaQuery:封装了我们要执行的查询中的各个部分的信息:select from order by
*CriteriaBuilder criteriaBuilder:查询条件构造器,定义不同的查询条件
* */
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//where name = "qin" and age=20 or id =1
/*
*/
//先写前面两个,在写后面一个
Predicate predicate = criteriaBuilder.and(criteriaBuilder.equal(root.get("name"), "qin"),
criteriaBuilder.equal(root.get("age"), 22));
Predicate predicate1 = criteriaBuilder.or(predicate, criteriaBuilder.equal(root.get("id"), 1));
return predicate1;
}
};
List<Users> list = usersRepositorySpecification.findAll(spec);
for (Users users : list) {
System.out.println(users.toString());
}
}
@Test
//jpaSpecificationExecutor接口测试
public void testJpaSpecificationExecutor5(){
/*
*Specification<Users>:用于封装查询条件
*
* */
Specification<Users> spec= new Specification<Users>() {
//Predicate 封装单个查询条件
/*
* Root<Users> root:查询对象的属性封装
*CriteriaQuery<?> criteriaQuery:封装了我们要执行的查询中的各个部分的信息:select from order by
*CriteriaBuilder criteriaBuilder:查询条件构造器,定义不同的查询条件
* */
@Override
public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//where name = "qin" and age=20 or id =1
/*
*/
//先写前面两个,在写后面一个
Predicate predicate = criteriaBuilder.and(criteriaBuilder.equal(root.get("name"), "qin"),
criteriaBuilder.equal(root.get("age"), 22));
Predicate predicate1 = criteriaBuilder.or(predicate, criteriaBuilder.equal(root.get("id"), 2));
return predicate1;
}
};
Sort sort = Sort.by(new Sort.Order(Sort.Direction.DESC, "id"));
List<Users> list = usersRepositorySpecification.findAll(spec,sort);
for (Users users : list) {
System.out.println(users.toString());
}
}
9.关联映射操作
一对多的关联关系
- 需求:角色与用户的关系就是一对多的关联
- 角色:一方
- 用户:多方
1.1 Users
@Entity
@Table(name = "t_users")
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
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;
@Column(name = "address")
private String address;
@ManyToOne(cascade = CascadeType.PERSIST)
//@JoinColumn():维护外键
@JoinColumn(name = "roles_id")
private Roles roles;
@Override
public String toString() {
return "Users{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
1.2 Roles
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "t_roles")
public class Roles {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "roleid")
private Integer roleid;
@Column(name = "rolename")
private String rolename;
@OneToMany(mappedBy = "roles")
private Set<Users> users= new HashSet<>();
}
1.3 测试一对多的关系
@Autowired
private UserRepository userRepository;
//一对多关联关系的添加
@Test
public void testSave(){
//创建一个用户
Users users = new Users();
users.setAddress("天津");
users.setAge(30);
users.setName("xiaogang");
//创建一个角色
Roles roles = new Roles();
roles.setRolename("管理员");
//关联
roles.getUsers().add(users);
System.out.println(roles.toString());
users.setRoles(roles);
//保存
Users save = userRepository.save(users);
System.out.println(save.toString());
}
}
//一对多关联关系的查询
@Test
public void testFind(){
Optional<Users> optional = userRepository.findById(2);
Users users;
if(optional != null && optional.isPresent()) {
users = optional.get();
Roles roles = users.getRoles();
System.out.println(roles.getRolename());
}else{
System.out.println("查询结果为空");
}
}
多对多的关联关系
- 需求:角色与菜单的多对多关联关系
2.1 Roles
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(name = "t_roles")
public class Roles {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "roleid")
private Integer roleid;
@Column(name = "rolename")
private String rolename;
@OneToMany(mappedBy = "roles")
private Set<Users> users= new HashSet<>();
@ManyToMany
//JoinTable : 映射中间表
//joinColumns:当前主键关联的中间表中的外键字段
@JoinTable(name = "t_role_menus",
joinColumns =@JoinColumn(name = "role_id"),
inverseJoinColumns = @JoinColumn(name = "menu_id") )
private Set<Menus> menus= new HashSet<>();
}
2.2 Menus
@Entity
@Table(name = "t_menus")
@Getter
@Setter
public class Menus {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "menusid")
private Integer menusid;
@Column(name = "menusname")
private String menusname;
@Column(name = "menusurl")
private String menusurl;
@Column(name = "fatherid")
private Integer fatherid;
@ManyToMany(mappedBy = "menus")
private Set<Roles> roles = new HashSet<>();
}
2.3测试多对多的关系
@Autowired
private RolesRepository rolesRepository;
@Test
public void testSave(){
//创建角色对象
Roles role = new Roles();
role.setRolename("经理");
//创建菜单对象
Menus menus = new Menus();
menus.setMenusname("××××管理系统");
menus.setFatherid(0);
Menus menus2 = new Menus();
menus2.setFatherid(1);
menus2.setMenusname("项目管理");
//关联
role.getMenus().add(menus);
role.getMenus().add(menus2);
menus.getRoles().add(role);
menus2.getRoles().add(role);
//保存
rolesRepository.save(role);
}
//查询操作
@Test
public void testFind(){
Optional<Roles> optional = rolesRepository.findById(2);
if(optional !=null && optional.isPresent()){
Roles roles = optional.get();
System.out.println(roles.getRolename());
Set<Menus> menus = roles.getMenus();
for (Menus menu : menus) {
System.out.println(menu.getMenusname());
}
}
}
网友评论