1. start
Configuring maven
1 <dependency> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-starter-data-jpa</artifactId> 4 </dependency>
Configuration properties
# database spring.datasource.url=jdbc:mysql://127.0.0.1:3306/stuadmin?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8 spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.type = com.alibaba.druid.pool.DruidDataSource spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=none spring.jpa.database-platform=org.hibernate.dialect.MySQL55Dialect
Creating entity
2. one relationship
- Teacher Teacher
@Entity // represents an entity the @Table (name = "t_teacher") // indicates that the database table name @ database sequence json exception @JsonIgnoreProperties (value = { "hibernateLazyInitializer", "Handler", "fieldHandler" }) public class Teacher { @Id // represents the primary key id @GeneratedValue (Strategy = GenerationType.IDENTITY) // growth since the @Column (name = "id", Precision =. 8) // column name total length Private Long id; the @Column (name = " name ", length = 20 is) // length to act only on the type varchar Private String name; the @Column (name= "Subject", columnDefinition = " varchar (25) not null COMMENT ' of the course'") // columnDefinition corresponds to add some minor splice action attribute data Private String Subject; }
- WorkCard work permits
@Entity @Table(name = "t_work_card") @JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"}) public class WorkCard { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "number", unique = true) private Long number; @Column(name = "overtime", columnDefinition = "datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '过期时间'") private Date overtime; // cascade lazy loading @OneToOne (= CascadeType.ALL in Cascade, FETCH = to FetchType.LAZY) // this table id table teacher_id reference teacher no foreign key field (logical foreign key) @JoinColumn (name = "teacher_id", the referencedColumnName = "ID", foreignKey = @ForeignKey (name = "none", value = ConstraintMode.NO_CONSTRAINT)) Private Teacher Teacher; }
- Defines the interface repository
public interface WorkCardRepository extends JpaRepository<WorkCard, Long> { }
- use
@Autowired WorkCardRepository workCardRepository; @GetMapping("/getteacherandworkcard") @ResponseBody public WorkCard queryWorkcardAndTeacher() { // 级联查询 WorkCard one = workCardRepository.getOne(1L); return one; }
Many-to
- Classz classroom
@Entity the @Table (name = "T_CLASS" ) @JsonIgnoreProperties (value = { "hibernateLazyInitializer", "Handler", "fieldHandler" }) public class Classz { @Id @GeneratedValue (Strategy = GenerationType.IDENTITY) the @Column (name = "the above mentioned id" ) Private Long the above mentioned id; @Column (name = "name", columnDefinition = "VARCHAR (25) not null the COMMENT 'class name'" ) Private String name; // many current students and more classrooms 1 / / current property maps to the classz // lazy loading @OneToMany(mappedBy = "classz", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private List<Student> studentList; }
- Student Student
@Entity @Table(name = "t_student") @JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"}) public class Student { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "name", columnDefinition = "varchar(25) not null COMMENT '姓名'") private String name; @Column(name = "age") private Integer age; @Column(name = "gender", columnDefinition = "varchar(2) not null default '男' COMMENT '性别'") private String gender; @Column(name = "distance", columnDefinition = "decimal(5,2) COMMENT '离校距离'") private BigDecimal distance; @ManyToOne(fetch = FetchType.LAZY) // 多对一 // class_id字段映射 Class @JoinColumn(name = "class_id", foreignKey = @ForeignKey(name = "none",value = ConstraintMode.NO_CONSTRAINT)) @JsonIgnore private Classz classz; }
- Defined repository
public interface ClasszRepository extends JpaRepository<Classz, Long> { }
- use
@GetMapping("/getclassz") @ResponseBody public Classz queryClassz() { //查修班级 Classz one = classzRepository.getOne(3L); return one; }
Many to many
- Classroom
@Entity @Table(name = "t_class") @JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"}) public class Classz { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "name", columnDefinition = "varchar(25) not null COMMENT '班级名称'") private String name; @ManyToMany(mappedBy = "classzList", cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JsonIgnore private List<Teacher> teachers; }
- teacher
@Entity @Table(name = "t_teacher") @JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"}) public class Teacher { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", precision = 8) private Long id; @Column(name = "name", length = 20) private String name; @Column(name = "subject", columnDefinition = "varchar(25) not null COMMENT '教授课程'") private String subject; @ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.LAZY) //Teacher是关系的维护端 //将会生成中间关联表 @JoinTable(name = "t_teacher_class_ref", joinColumns = @JoinColumn(name="teacher_id", foreignKey = @ForeignKey(name = "none",value = ConstraintMode.NO_CONSTRAINT)), inverseJoinColumns = @JoinColumn(name = "class_id", foreignKey = @ForeignKey(name = "none",value = ConstraintMode.NO_CONSTRAINT)), uniqueConstraints = {@UniqueConstraint(columnNames={"class_id", "teacher_id"})}) // class_id teacher_id 联合索引 private List<Classz> classzList; }classroom//
- Defined repository
Classrepository defined at this time and will do teacherrepository
public interface TeacherRepository extends JpaRepository<Teacher, Long> { }
- use
@GetMapping("/getteachers") @ResponseBody public Teacher queryTeachers() { // 级联查询 Teacher one = teacherRepository.getOne(1L); return one; }
Custom method name
You can define a number of ways such as findby get in the repository, etc., is called the same as before
public interface UserRepository extends JpaRepository<User, Long> { List<User> findByAge(Integer age); List<User> findAllByAgeBetween(Integer start, Integer end); List<User> findUsersByAgeAndGenderLessThan(Integer age, Integer gender); @Query(nativeQuery = true, value = "select * from t_user where username = :username") List<User> findUsersByName(@Param("username") String username); }
native sql
Equivalent to write their sql
@Query(nativeQuery = true, value = "select * from t_user where username = :username") List<User> findUsersByName(@Param("username") String username);
jpql
Object-level sql
@Query("select s from Student s join s.classz c where c.name = :classname and s.name like :sname%")
List<Student> getStudentByName(@Param("classname") String classname, @Param("sname") String sname);
Paging
Interface can inherit pageAndSortRepository
public interface StudentPagingAndSortRepository extends PagingAndSortingRepository<Student, Long> { } @GetMapping("/get/studensbypage") @ResponseBody public List<Student> getStudentsByPage(@Param("page") Integer page, @Param("size") Integer size) { Pageable pageRequest = PageRequest.of(page, size); Page<Student> findStudentsByPage = studentPagingAndSortRepository.findAll(pageRequest); return findStudentsByPage.getContent(); = the Pageable Pageable Or using dynamic queries and pagerequest JpaSpecificationExecutor combination with } PageRequest.of(page,size); Specification<Student> specification = new Specification<Student>() { @Override public Predicate toPredicate(Root<Student> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { List<Predicate> predicates = new ArrayList<Predicate>(); //age Predicate age = criteriaBuilder.between(root.<Integer>get("age"), agegt, agelt); predicates.add(age); //dis Predicate distance = criteriaBuilder.equal(root.<Double>get("distance"), BigDecimal.valueOf(dis)); predicates.add(distance); //gender Predicate gender = criteriaBuilder.equal(root.<String>get("gender"), gend); predicates.add(gender); Predicate endset = criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); return endset; } }; // 查询 Page<Student> students = studentSpecificationRepository.findAll(specification, pageable); return students.getContent(); }
Cascade relationship - CascadeType
https://www.jianshu.com/p/e8caafce5445
- CascadeType.REMOVE
Cascade remove operation,级联删除操作。
删除当前实体时,与它有映射关系的实体也会跟着被删除。
- CascadeType.MERGE
Cascade merge operation,级联更新(合并)操作。
当Student中的数据改变,会相应地更新Course中的数据。
- CascadeType.DETACH
Cascade detach operation,级联脱管/游离操作。
如果你要删除一个实体,但是它有外键无法删除,你就需要这个级联权限了。它会撤销所有相关的外键关联。
- CascadeType.REFRESH
Cascade refresh operation,级联刷新操作。
假设场景 有一个订单,订单里面关联了许多商品,这个订单可以被很多人操作,那么这个时候A对此订单和关联的商品进行了修改, 与此同时,B也进行了相同的操作,但是B先一步比A保存了数据,那么当A保存数据的时候,就需要先刷新订单信息及关联的商品信息后,再将订单及商品保存。
- CascadeType.ALL
Cascade all operations,清晰明确,拥有以上所有级联操作权限。
@EntityGhpra n + 1 problem solving
n + 1 problem: a classroom when the corresponding number of students, jpa default will first check all the classrooms, then go to the student and then query each classroom through a section of each user id, this will cause the database to perform multiple sql statement, reduce database performance;
-
1. EntityGhpra solving n + 1
@Entity @Table(name = "t_class")
@NamedEntityGraph(name = "Classz.Graph", attributeNodes = {@NamedAttributeNode("studentList")}) //注意这句,先用@NamedEntityGraph指名要加载的studentList属性 @JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"}) public class Classz { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long id; @Column(name = "name", columnDefinition = "varchar(25) not null COMMENT '班级名称'") private String name; //Many current students and more classrooms 1 // maps in the current property to classz // lazy loading @OneToMany (the mappedBy = "classz", Cascade = CascadeType.ALL, FETCH = FetchType.LAZY) Private List <Student> studentList; }
- 2. When calling a method, named to load the optimized object
public interface ClasszRepository extends JpaRepository<Classz, Long> {
// 解决懒加载n+1问题
@EntityGraph(value = "Classz.Graph", type = EntityGraph.EntityGraphType.FETCH)
public List<Classz> findAll(); }
Custom repository
https://blog.csdn.net/chengqiuming/article/details/82531227
Jpa and hibernate the relationship
- JPA
JPA full name: Java Persistence API, JPA through JDK 5.0 annotations or XML description of the object - mapping between relational tables, solid objects and run persistence to the database. JPA emergence of two reasons:
1. First, simplify the existing Java EE objects and Java SE applications persistent development work;
2. Second, Sun hopes the integration of ORM technology, unified persistence areas.
JPA provides technical:
- (1) ORM mapping metadata
XML and JPA support JDK 5.0 annotations forms two kinds of metadata, the metadata mapping between objects and tables description, whereby the entity object holding frame
long to the database tables;
- (2) 的 JPA API
For operating entity object, perform CRUD operations, the framework for us to do everything in the background, the developer from the tedious JDBC and SQL code solutions
come off.
- (3) query language
Object-oriented rather than oriented database query language data, procedures to avoid tight coupling of SQL statements
- Hibernate
JPA Provider is required to achieve its function, Hibernate JPA Provider is in a very strong one.
Java 8 date and time support
SQL mapping fragment
immutable entity type
solid filter
SQL fragments matching
manual flush mode
two cache query
soft delete
These advanced features are owned by hibernate.