ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Specification的基本使用

2022-07-09 01:34:28  阅读:141  来源: 互联网

标签:基本 status name age teacher _. teacher0 使用 Specification


Specification的基本使用

Specification是啥,相信你都需要使用了,我就不过多介绍了,直接上代码

1.基础表结构

create database jpa;
use jpa;

CREATE TABLE `teacher` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(16) NOT NULL,
  `age` int(4) NOT NULL,
  `teacher_no` int(8) NOT NULL,
  `status` char(1) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO jpa.teacher (name,age,teacher_no,status) VALUES
	 ('joshuay',20,1001,'Y'),
	 ('felixf',30,1002,'Y'),
	 ('stanh',25,1003,'Y');
	 
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `teacher_no` int(8) NOT NULL,
  `name` varchar(16) NOT NULL,
  `status` char(1) NOT NULL,
  `age` int(4) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO jpa.student (teacher_no,name,status,age) VALUES
	 (1001,'张三','Y',15),
	 (1001,'李四','Y',20),
	 (1002,'王五','Y',25),
	 (1002,'赵六','Y',30),
	 (1003,'金七','Y',35);

2.建立实体类

Teacher类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(catalog = "jpa", name = "teacher")
public class Teacher implements Serializable {

    @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 = "teacher_no")
    private Integer teacherNo;

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

    // @JsonIgnore
    @OneToMany(cascade = {CascadeType.ALL}, fetch = FetchType.EAGER)
    @JoinColumn(name = "teacher_no", referencedColumnName = "teacher_no", insertable = false, updatable = false)
    private List<Student> studentList;

}

Student类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
@Table(catalog = "jpa", name = "student")
public class Student {

    @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 = "teacher_no")
    private Integer teacherNo;

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

}

3.建立对应的Repository接口并继承相应的接口

public interface TeacherRepository extends JpaRepository<Teacher, Integer>, JpaSpecificationExecutor<Teacher> {
}

4.编写相应的Specification代码并进行单元测试

编写Specification实现逻辑

public class TeacherRepositorySpec {

    private TeacherRepositorySpec() {
    }

    public static Specification<Teacher> byTeacherName(@NonNull String name) {
        return (root, query, builder) -> {
            Predicate conjunction = builder.conjunction();
            List<Expression<Boolean>> expressions = conjunction.getExpressions();
            expressions.add(builder.equal(root.get("name"), name));
            return conjunction;
        };
    }

    public static Specification<Teacher> byReportForm(Map<String, Object> reportForm) {
        return (root, query, builder) -> {
            List<Predicate> sqlList = new ArrayList<>();
            sqlList.add(builder.equal(root.get("status"), "Y"));

            if (!ObjectUtils.isEmpty(reportForm.get("name"))) {
                String name = (String) reportForm.get("name");
                sqlList.add(builder.like(root.get("name"), "%" + name + "%"));
            }
            // join table student
            Join<Teacher, Student> studentJoin = root.join("studentList");
            studentJoin = studentJoin.on(builder.equal(studentJoin.get("status"), "Y"));
            if (!ObjectUtils.isEmpty(reportForm.get("age"))) {
                Integer age = (Integer) reportForm.get("age");
                sqlList.add(builder.gt(studentJoin.get("age"), age));
            }
            query.where(sqlList.toArray(new Predicate[0]));
            return null;
        };
    }


    public static Specification<Teacher> byAgeRange(Integer min,Integer max) {
        return (root, query, builder) -> {
            Assert.isTrue(Integer.compare(max,min) == 1,"max can not more than min");
            List<Predicate> sqlList = new ArrayList<>();
            sqlList.add(builder.equal(root.get("status"), "Y"));
            // join table student
            Join<Teacher, Student> studentJoin = root.join("studentList");
            studentJoin = studentJoin.on(builder.equal(studentJoin.get("status"), "Y"));
            sqlList.add(builder.between(root.get("age"),min,max));
            return builder.and(sqlList.toArray(new Predicate[0]));
        };
    }

}

单元测试

@SpringBootTest
class DemoSpringApplicationTests {

    @Autowired
    private TeacherRepository teacherRepository;

    @Test
    void test_spec() {

        Specification<Teacher> spec1 = TeacherRepositorySpec.byAgeRange(19, 26);
        List<Teacher> rangeTeacherList = teacherRepository.findAll(spec1);
        rangeTeacherList.forEach(System.out::println);
        System.out.println("================================================");
        Specification<Teacher> spec2 = TeacherRepositorySpec.byTeacherName("felixf");
        List<Teacher> nameTeacherList = teacherRepository.findAll(spec2);
        nameTeacherList.forEach(System.out::println);
        System.out.println("================================================");
        HashMap<String,Object> reportForm = new HashMap<String,Object>(){
            {
                put("name","h");
                put("age",20);
            }
        };
        Specification<Teacher> spec3 = TeacherRepositorySpec.byReportForm(reportForm);
        List<Teacher> formTeacherList = teacherRepository.findAll(spec3);
        formTeacherList.forEach(System.out::println);

    
    /* 打印日志以及输出结果如下:
    select
        teacher0_.id as id1_8_,
        teacher0_.age as age2_8_,
        teacher0_.name as name3_8_,
        teacher0_.status as status4_8_,
        teacher0_.teacher_no as teacher_5_8_ 
    from
        jpa.teacher teacher0_ 
    inner join
        jpa.student studentlis1_ 
            on teacher0_.teacher_no=studentlis1_.teacher_no 
            and (
                studentlis1_.status=?
            ) 
    where
        teacher0_.status=? 
        and (
            teacher0_.age between 19 and 26
        )
        
    Teacher(id=1, name=joshuay, age=20, teacherNo=1001, status=Y, studentList=[Student(id=1, name=张三, age=15, teacherNo=1001, status=Y), Student(id=2, name=李四, age=20, teacherNo=1001, status=Y)])
    Teacher(id=1, name=joshuay, age=20, teacherNo=1001, status=Y, studentList=[Student(id=1, name=张三, age=15, teacherNo=1001, status=Y), Student(id=2, name=李四, age=20, teacherNo=1001, status=Y)])
    Teacher(id=3, name=stanh, age=25, teacherNo=1003, status=Y, studentList=[Student(id=5, name=金七, age=35, teacherNo=1003, status=Y)])
================================================
    select
        teacher0_.id as id1_8_,
        teacher0_.age as age2_8_,
        teacher0_.name as name3_8_,
        teacher0_.status as status4_8_,
        teacher0_.teacher_no as teacher_5_8_ 
    from
        jpa.teacher teacher0_ 
    where
        teacher0_.name=?
        
    Teacher(id=2, name=felixf, age=30, teacherNo=1002, status=Y, studentList=[Student(id=3, name=王五, age=25, teacherNo=1002, status=Y), Student(id=4, name=赵六, age=30, teacherNo=1002, status=Y)])
================================================
    select
        teacher0_.id as id1_8_,
        teacher0_.age as age2_8_,
        teacher0_.name as name3_8_,
        teacher0_.status as status4_8_,
        teacher0_.teacher_no as teacher_5_8_ 
    from
        jpa.teacher teacher0_ 
    inner join
        jpa.student studentlis1_ 
            on teacher0_.teacher_no=studentlis1_.teacher_no 
            and (
                studentlis1_.status=?
            ) 
    where
        teacher0_.status=? 
        and (
            teacher0_.name like ?
        ) 
        and studentlis1_.age>20

    Teacher(id=3, name=stanh, age=25, teacherNo=1003, status=Y, studentList=[Student(id=5, name=金七, age=35, teacherNo=1003, status=Y)])
     */
    }
}

标签:基本,status,name,age,teacher,_.,teacher0,使用,Specification
来源: https://www.cnblogs.com/jiehao-yu/p/16460004.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有