Springdata-Jpa study notes

Respository Interface

Respository is Springdata JPA top-level interface that provides two query methods:

1) based on the method name naming rules

2) a query based on @Qeury comment

1. Method name naming query

Rules: findBy (keyword) + attribute name (first letter capitalized property name) + query (first letter capitalized)

Fuzzy query:

@Test
public void test(){
    
    List<StudentEntity> res = this.stu.findByXmLike("刘%");
    for(StudentEntity tmp : res){
        System.out.println(tmp);
    }
}

Methods naming rules:

  • And --- equivalent to the SQL and keywords, such as findByUsernameAndPassword (String user, Striang pwd);
  • Or --- equivalent to or keyword in SQL, such as findByUsernameOrAddress (String user, String addr);
  • BETWEEN --- equivalent to between keywords in SQL, such findBySalaryBetween (int max, int min);
  • LessThan --- SQL equivalent of "<", such findBySalaryLessThan (int max);
  • GreaterThan --- SQL equivalent of the ">", such findBySalaryGreaterThan (int min);
  • GreaterThanEqual
  • IsNull --- equivalent to the SQL "is null", such findByUsernameIsNull ();
  • IsNotNull --- SQL equivalent of "is not null", such findByUsernameIsNotNull ();
  • NotNull --- and IsNotNull equivalent;
  • Like --- SQL equivalent of "like", such findByUsernameLike (String user);
  • NotLike --- equivalent to the SQL in the "not like", such as findByUsernameNotLike (String user);
  • OrderBy --- equivalent to the SQL in "order by", such as findByUsernameOrderBySalaryAsc (String user);
  • Not --- equivalent to the SQL, such as findByUsernameNot (String user) "=!";
  • --- the In SQL equivalent to the "in", such findByUsernameIn (Collection UserList parameters), Collection type method may be, or may be an array variable length parameter;
  • NotIn --- equivalent to the SQL in the "not in", such as findByUsernameNotIn (Collection UserList parameters), Collection type method may be, or may be an array variable length parameter;

Cons: When the query is too complicated, method name will be very long

2. Based on the @Query notes queries

2.1 by JPQL statement queries

JPQL: through Hibernate's HQL of evolution. And HQL syntax is very similar.

Implementation is not required;

JPQL variables in statements using the class name and the class members.

//使用@Query注解查询, 抽象方法, 参数列表的顺序就是sql语句中的顺序
    @Query(value="from StudentEntity where xm like ?1")
    List<StudentEntity> queryByXm(String name);

//多值查询
    @Query(value="from StudentEntity where xm is ?1 and yxh is ?2")
    List<StduentEntity> queryByXmAndYxh(String name, Integer yxh);

//或是这样的Like查询写法
@Query(value="from StudentEntity where xm like %:name%")
    List<StudentEntity> queryByXm(@Param("name") String name);

@Param ( "name") to the parameter assignment statement in JPQL

2.2 through SQL statements to query

@Query statement using the table name and data tables in the database

nativeQuery = true use SQL statements

//可标可不标参数顺序, 多值查询时不标明顺序按次序填充
@Query(value = "select * from S where xm = ?1", nativeQuery = true)
    List<StudentEntity> queryBySQL(String name);

3. Paging

PagingAndSortingRepository

3.1. Paging treatment
@Test
    public void testPaging(){
        int page, size;
        //page 为当前页的索引,起始为0
        //size 为页面大小
        page = 1;
        size = 5;
        Pageable p = new PageRequest(page,size);
        Page<StudentEntity> res =  this.stu.findAll(p);
        for(StudentEntity s: res){
            System.out.println(s);
        }
    }
3.2 ordering process
/*
    对单列做排序
     */
    @Test
    public void testSort(){
        // Sort: 该对象封装了排序规则以及指定的排序字段(对象的属性来表示)
        // direction: 排序规则
        // properties: 指定做排序的属性, 给表对应类的属性
        Sort sort = new Sort(Sort.Direction.DESC, "xh");
        List<StudentEntity> res = this.stu.findAll(sort);
        for(StudentEntity s: res){
            System.out.println(s);
        }
    }

/*
多列排序
*/
@Test
    public void testSort2(){
        //Sort sort = new Sort();
        Sort.Order o1 = new Sort.Order(Sort.Direction.DESC, "yxh");
        Sort.Order o2 = new Sort.Order(Sort.Direction.ASC, "csrq");
        Sort sort = new Sort(o1,o2);
        List<StudentEntity>  res = this.stu.findAll(sort);
        for(StudentEntity s: res){
            System.out.println(s);
        }
    }

4. JpaSpecificationExecutor Interface

Can not be used alone, must inherit and JpaRepository, otherwise you can not generate the proxy object.

Completion of complex multi-criteria query , and support for paging and sorting

//1.创建接口
public interface StudentRepository extends JpaRepository<StudentEntity,Integer>, JpaSpecificationExecutor<StudentEntity>
5.1 single condition query

The method of determining call criteriaBuilder query method, such as: determination are equal, fuzzy query

root.get () method returns the value may be used .as (String.class) turn into a string class (or other specified type)

/*
    JpaSpecificationExecutor
    单条件查询
     */
    @Test
    public void testSpecification(){
        Specification<StudentEntity> spec= new Specification<StudentEntity>() {
            /*
            @return Predicate:定义了查询条件
            @param Root<StduentEntity> root:根对象,封装了查询条件的对象
            @param criteriaQuery :定义了基本的查询,一般不常用
            @param criteriaBuilder : 创建一个查询条件
             */
            @Override
            public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                Predicate pre = criteriaBuilder.equal(root.get("xm"), "刘%");
                return pre;
            }
        };

        List<StudentEntity> res = this.stu.findAll(spec);
        for(StudentEntity s: res){
            System.out.println(s);
        }
    }
More than 5.2 criteria query

Multi-criteria query a variety of ways

/*
    JpaSpecificationExecutor
    需求:使用姓名和学院查询数据
    多条件查询方式一
     */
    @Test
    public void testSpecification2(){
        Specification<StudentEntity> spec= new Specification<StudentEntity>() {
            /*
            @return Predicate:定义了查询条件
            @param Root<StduentEntity> root:根对象,封装了查询条件的对象
            @param criteriaQuery :定义了基本的查询,一般不常用
            @param criteriaBuilder : 创建一个查询条件
             */
            @Override
            public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> plist = new ArrayList<>();
                plist.add(criteriaBuilder.like(root.get("xm"), "刘%"));
                plist.add(criteriaBuilder.equal(root.get("yxh"),2));
                //此时条件之间没有关联
                Predicate [] arr = new Predicate[plist.size()];
                return criteriaBuilder.or(plist.toArray(arr));     //规定关系之间的关系并返回查询规则
                //如果再想或关系,就将cb返回的Predicate对象再放入cb.or方法中
            }
        };

        List<StudentEntity> res = this.stu.findAll(spec);
        for(StudentEntity s: res){
            System.out.println(s);
        }
    }
/*
    JpaSpecificationExecutor
    需求:使用姓名和学院查询数据
    多条件查询方式二
     */
    @Test
    public void testSpecification2(){
        Specification<StudentEntity> spec= new Specification<StudentEntity>() {
            /*
            @return Predicate:定义了查询条件
            @param Root<StduentEntity> root:根对象,封装了查询条件的对象
            @param criteriaQuery :定义了基本的查询,一般不常用
            @param criteriaBuilder : 创建一个查询条件
             */
            @Override
            public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                return cb.or(cb.like(root.get("xm"),"刘%"), cb.equal(root.get("yxh"),2));
            }
        };

        List<StudentEntity> res = this.stu.findAll(spec);
        for(StudentEntity s: res){
            System.out.println(s);
        }
    }
More than 5.3 criteria query paging +
    /*
    查询院系号为1或性别为女的同学 结果分页
     */
    @Test
    public void test4(){
        Specification<StudentEntity> spec = new Specification<StudentEntity>() {
            @Override
            public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                return cb.and(cb.equal(root.get("yxh"),1),cb.equal(root.get("xb"),0));
            }
        };

        Pageable pg = new PageRequest(0,2);
        Page<StudentEntity> res = this.stu.findAll(spec, pg);
        System.out.println(res.getTotalElements());
        System.out.println(res.getTotalPages());
        for(StudentEntity s :res){
            System.out.println(s);
        }
    }
5.4 + sorting criteria query
/*
    查询院系号为1或性别为女的同学,结果按学号做倒序排序
     */
    @Test
    public void test5(){
        Specification<StudentEntity> spec = new Specification<StudentEntity>() {
            @Override
            public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                return cb.and(cb.equal(root.get("yxh"),1),cb.equal(root.get("xb"),0));
            }
        };

        Sort sort = new Sort(Sort.Direction.DESC,"xh");
        List<StudentEntity> res = this.stu.findAll(sort);
        for(StudentEntity s :res){
            System.out.println(s);
        }
    }
Paging + 5.5 + sorting criteria query

Sort integrated into the page object

new PageRequest(0,3,sort);
/*
    查询院系号为1或性别为女的同学,做分页处理,结果按学号做倒序排序
     */
    @Test
    public void test6(){
        //排序定义
        Sort sort = new Sort(Sort.Direction.DESC,"xh");
        //分页定义,Pageable对象中存在
        Pageable pg = new PageRequest(0,3,sort);

        Specification<StudentEntity> spec = new Specification<StudentEntity>() {
            @Override
            public Predicate toPredicate(Root<StudentEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) {
                return cb.and(cb.equal(root.get("yxh"),1),cb.equal(root.get("xb"),0));
            }
        };
        Page<StudentEntity> res = this.stu.findAll(pg);
        System.out.println("总条目数: "+res.getTotalElements());
        System.out.println("页数: "+res.getTotalPages());
        for(StudentEntity s : res){
            System.out.println(s);
        }
    }

The entity class

5.1 primary key defined
//自增方式创建主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    @Column(name="xh")
    private int xh;

@Temporal method

//JPA将时间映射到日期
    @Temporal(TemporalType.DATE)
    @Column(name = "csrq")
    private Date csrq;

6. relationship

6.1 one relationship

Example: Roles and User-one

//测试一对一关系 学生类
    @OneToOne(cascade = CascadeType.PERSIST)        //表示级联关系,增加学生时,对应用户也会加入数据库
    @JoinColumn(name="id")              //表示外键,使用对应表的主键(数据库内的名称)
    private Account account;
    //用户类
    @OneToOne(mappedBy = "account")         //看谁引用了这个account
    private StudentEntity student;

Operating one relationship

//增添数据
@Test
    public void test7(){
        //创建用户对象
        Account acc = new Account();
        acc.setUsername("玩家");

        //创建学生对象
        StudentEntity student = new StudentEntity();
        student.setXm("李修文");
        student.setYxh(3);
        student.setSjhm("13120716616");
        student.setPassword("0");
        //student.setCsrq(new Date("1998-7-24"));
        student.setJg("上海");
        student.setXb(1);

        //关联
        student.setAccount(acc);
        acc.setStudent(student);

        //保存学生,相应地acc中也会出现“玩家”条目
        this.stu.save(student);
    }
    /*
    根据学号查询学生,并查询其账户
     */
    @Test
    public void test8(){
        StudentEntity student = this.stu.findByXh(1112);
        System.out.println("学生信息:"+student);
        Account acc = student.getAccount();
        System.out.println(acc);
    }
6.2-to-many relationship
//用户类
@Id
    @Column(name="user_id")
    private int userId;

    @Column(name="user_name")
    private String name;

    @OneToMany
    @JoinColumn(name="role_id")
    private Role role;
//角色类
    @Id
    @Column(name="role_id")
    private Integer roleId;

    @Column(name="role_name")
    private String roleName;

    @OneToMany(mappedBy = "role")
    private Set<User> users = new HashSet<User>();
6.3-many relationship

It will generate an intermediate table

//学生类

/*
@JoinTable: 配置中间表信息
joinColumns: 建立当前表在中间表的外键字段
*/
@ManyToMany(cascade = CasadeType.PERSIST, fetch = FetchType.EAGER)      //级联操作,添加不存在的数据时同时导入课程类,  放弃延迟加载改为立即加载
@JoinTable(name="t_stu_class",joinColumns=@JoinColumn(name="stu_xh"), inverseJoinColumns = @JoinColumn(name="class_id"))
private Set<Class> classes = new HashSet<Class>();
//课程类
@ManyToMany(mappedBy = "classes")       //映射引用课程类的对象
private Set<Student> students = new HashSet<Student>();

* Whether or many-to-many, cascading notes that operate in the open class of the specific use

At query time, if not immediately, then loaded with all courses students corresponding output will complain (because of delayed loading, session closed after retrieving a student)

Guess you like

Origin www.cnblogs.com/xiuwenli/p/11027776.html