JPA

作者: BowonQin5 | 来源:发表于2020-11-13 23:43 被阅读0次

    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());
            }
        }
    
    
    
    }
    

    相关文章

      网友评论

          本文标题:JPA

          本文链接:https://www.haomeiwen.com/subject/iwqibktx.html