From 5dafba9ed2bb87e0182a9b2e3a28a86cc77dd8aa Mon Sep 17 00:00:00 2001 From: 76peter <412044923@qq.com> Date: Thu, 10 Oct 2019 10:46:38 +0800 Subject: [PATCH] =?UTF-8?q?jpa=E5=A2=9E=E5=8A=A0=E9=83=A8=E9=97=A8?= =?UTF-8?q?=E4=B8=8A=E4=B8=8B=E7=BA=A7=E8=87=AA=E5=85=B3=E8=81=94=EF=BC=8C?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E9=83=A8=E9=97=A8=E5=A4=9A=E5=AF=B9=E5=A4=9A?= =?UTF-8?q?=E5=85=B3=E8=81=94=20(#59)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 添加部门之间多对一关联,部门和用户多对多关联。 --- spring-boot-demo-orm-jpa/pom.xml | 6 ++ .../xkcoding/orm/jpa/entity/Department.java | 66 ++++++++++++++ .../com/xkcoding/orm/jpa/entity/User.java | 27 ++++-- .../orm/jpa/repository/DepartmentDao.java | 26 ++++++ .../src/main/resources/db/schema.sql | 21 +++++ .../orm/jpa/repository/DepartmentDaoTest.java | 86 +++++++++++++++++++ 6 files changed, 227 insertions(+), 5 deletions(-) create mode 100644 spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/entity/Department.java create mode 100644 spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/repository/DepartmentDao.java create mode 100644 spring-boot-demo-orm-jpa/src/test/java/com/xkcoding/orm/jpa/repository/DepartmentDaoTest.java diff --git a/spring-boot-demo-orm-jpa/pom.xml b/spring-boot-demo-orm-jpa/pom.xml index acb2548..7a846de 100644 --- a/spring-boot-demo-orm-jpa/pom.xml +++ b/spring-boot-demo-orm-jpa/pom.xml @@ -59,6 +59,12 @@ lombok true + + com.alibaba + fastjson + 1.2.58 + test + diff --git a/spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/entity/Department.java b/spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/entity/Department.java new file mode 100644 index 0000000..41dadc1 --- /dev/null +++ b/spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/entity/Department.java @@ -0,0 +1,66 @@ +package com.xkcoding.orm.jpa.entity; + +import com.xkcoding.orm.jpa.entity.base.AbstractAuditModel; +import lombok.*; + +import javax.persistence.*; +import java.util.Collection; + +/** + *

+ * 部门实体类 + *

+ * + * @package: com.xkcoding.orm.jpa.entity + * @description: 部门实体类 + * @author: 76peter + * @date: Created in 2019/10/1 18:07 + * @copyright: Copyright (c) 2019 + * @version: V1.0 + * @modified: 76peter + */ +@EqualsAndHashCode(callSuper = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Entity +@Table(name = "orm_department") +@ToString(callSuper = true) +public class Department extends AbstractAuditModel { + + /** + * 部门名 + */ + @Column(name = "name", columnDefinition = "varchar(255) not null") + private String name; + + /** + * 上级部门id + */ + @ManyToOne(cascade = {CascadeType.REFRESH},optional = true) + @JoinColumn(name = "superior",referencedColumnName = "id") + private Department superior; + /** + * 所属层级 + */ + @Column(name = "levels", columnDefinition = "int not null default 0") + private Integer levels; + /** + * 排序 + */ + @Column(name = "orderno", columnDefinition = "int not null default 0") + private Integer orderno; + /** + * 子部门集合 + */ + @OneToMany(cascade={CascadeType.REFRESH, CascadeType.REMOVE}, fetch = FetchType.EAGER,mappedBy="superior") + private Collection children; + + /** + * 部门下用户集合 + */ + @ManyToMany(mappedBy = "departmentList") + private Collection userList; + +} diff --git a/spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/entity/User.java b/spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/entity/User.java index baaeaa0..167a80e 100644 --- a/spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/entity/User.java +++ b/spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/entity/User.java @@ -3,9 +3,8 @@ package com.xkcoding.orm.jpa.entity; import com.xkcoding.orm.jpa.entity.base.AbstractAuditModel; import lombok.*; -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.Table; +import javax.persistence.*; +import java.util.Collection; import java.util.Date; /** @@ -19,12 +18,12 @@ import java.util.Date; * @date: Created in 2018/11/7 14:06 * @copyright: Copyright (c) * @version: V1.0 - * @modified: yangkai.shen + * @modified: 76peter */ @EqualsAndHashCode(callSuper = true) -@Data @NoArgsConstructor @AllArgsConstructor +@Data @Builder @Entity @Table(name = "orm_user") @@ -66,4 +65,22 @@ public class User extends AbstractAuditModel { */ @Column(name = "last_login_time") private Date lastLoginTime; + + + /** + * 关联部门表 + */ + @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) + @JoinTable(name = "orm_usersetdept",joinColumns = @JoinColumn(name = "userid",referencedColumnName="id"), + inverseJoinColumns = @JoinColumn(name = "deptid",referencedColumnName="id")) + //1、关系维护端,负责多对多关系的绑定和解除 + //2、@JoinTable注解的name属性指定关联表的名字,joinColumns指定外键的名字,关联到关系维护端(User) + //3、inverseJoinColumns指定外键的名字,要关联的关系被维护端(Department) + //4、其实可以不使用@JoinTable注解,默认生成的关联表名称为主表表名+下划线+从表表名, + //即表名为user_department + //关联到主表的外键名:主表名+下划线+主表中的主键列名,即user_id,这里使用referencedColumnName指定 + //关联到从表的外键名:主表中用于关联的属性名+下划线+从表的主键列名,department_id + //主表就是关系维护端对应的表,从表就是关系被维护端对应的表 + private Collection departmentList; + } diff --git a/spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/repository/DepartmentDao.java b/spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/repository/DepartmentDao.java new file mode 100644 index 0000000..8173dca --- /dev/null +++ b/spring-boot-demo-orm-jpa/src/main/java/com/xkcoding/orm/jpa/repository/DepartmentDao.java @@ -0,0 +1,26 @@ +package com.xkcoding.orm.jpa.repository; + +import com.xkcoding.orm.jpa.entity.Department; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Collection; + + +/** + *

+ * User Dao + *

+ * + * @package: com.xkcoding.orm.jpa.repository + * @description: Department Dao + * @author: 76peter + * @date: Created in 2019/10/1 18:07 + * @copyright: Copyright (c) 2019 + * @version: V1.0 + * @modified: 76peter + */ +@Repository +public interface DepartmentDao extends JpaRepository { + public Collection findDepartmentsByLevels(Integer level); +} diff --git a/spring-boot-demo-orm-jpa/src/main/resources/db/schema.sql b/spring-boot-demo-orm-jpa/src/main/resources/db/schema.sql index 22804e5..b03402f 100644 --- a/spring-boot-demo-orm-jpa/src/main/resources/db/schema.sql +++ b/spring-boot-demo-orm-jpa/src/main/resources/db/schema.sql @@ -11,3 +11,24 @@ CREATE TABLE `orm_user` ( `last_login_time` DATETIME DEFAULT NULL COMMENT '上次登录时间', `last_update_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '上次更新时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Spring Boot Demo Orm 系列示例表'; + + +DROP TABLE IF EXISTS `orm_department`; +CREATE TABLE `orm_department` ( + `id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键', + `name` VARCHAR(32) NOT NULL COMMENT '部门名称', + `superior` INT(11) COMMENT '上级id', + `levels` INT(11) NOT NULL COMMENT '层级', + `orderno` INT(11) NOT NULL DEFAULT 0 COMMENT '排序', + `create_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '创建时间', + `last_update_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '上次更新时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Spring Boot Demo Orm 系列示例表'; + +--DROP TABLE IF EXISTS `orm_usersetdept`; +CREATE TABLE `orm_usersetdept` ( + `id` INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键', + `userid` INT(11) NOT NULL COMMENT '用户id', + `deptid` INT(11) NOT NULL COMMENT '部门id', + `create_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '创建时间', + `last_update_time` DATETIME NOT NULL DEFAULT NOW() COMMENT '上次更新时间' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Spring Boot Demo Orm 系列示例表'; diff --git a/spring-boot-demo-orm-jpa/src/test/java/com/xkcoding/orm/jpa/repository/DepartmentDaoTest.java b/spring-boot-demo-orm-jpa/src/test/java/com/xkcoding/orm/jpa/repository/DepartmentDaoTest.java new file mode 100644 index 0000000..8dba3cc --- /dev/null +++ b/spring-boot-demo-orm-jpa/src/test/java/com/xkcoding/orm/jpa/repository/DepartmentDaoTest.java @@ -0,0 +1,86 @@ +package com.xkcoding.orm.jpa.repository; + +import com.xkcoding.orm.jpa.SpringBootDemoOrmJpaApplicationTests; +import com.xkcoding.orm.jpa.entity.Department; +import com.xkcoding.orm.jpa.entity.User; +import lombok.extern.slf4j.Slf4j; +import net.minidev.json.JSONArray; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import javax.transaction.Transactional; +import java.util.Collection; +import java.util.List; + +/** + *

+ * jpa 测试类 + *

+ * + * @package: com.xkcoding.orm.jpa.repository + * @description: jpa 测试类 + * @author: 76peter + * @date: Created in 2018/11/7 14:09 + * @copyright: Copyright (c) 2018 + * @version: V1.0 + * @modified: 76peter + */ +@Slf4j +public class DepartmentDaoTest extends SpringBootDemoOrmJpaApplicationTests { + @Autowired + private DepartmentDao departmentDao; + @Autowired + private UserDao userDao; + + /** + * 测试保存 ,根节点 + */ + @Test + @Transactional + public void testSave() { + Collection departmentList = departmentDao.findDepartmentsByLevels(0); + if(departmentList.size()==0){ + Department testSave1 = Department.builder().name("testSave1").orderno(0).levels(0).superior(null).build(); + Department testSave1_1 = Department.builder().name("testSave1_1").orderno(0).levels(1).superior(testSave1).build(); + Department testSave1_2 = Department.builder().name("testSave1_2").orderno(0).levels(1).superior(testSave1).build(); + Department testSave1_1_1 = Department.builder().name("testSave1_1_1").orderno(0).levels(2).superior(testSave1_1).build(); + departmentList.add(testSave1); + departmentList.add(testSave1_1); + departmentList.add(testSave1_2); + departmentList.add(testSave1_1_1); + departmentDao.saveAll(departmentList); + + Collection deptall = departmentDao.findAll(); + log.debug("【部门】= {}", JSONArray.toJSONString((List)deptall)); + } + + + userDao.findById(1L).ifPresent(user -> { + user.setName("添加部门"); + Department dept = departmentDao.findById(2L).get(); + user.setDepartmentList(departmentList); + userDao.save(user); + }); + User users = userDao.findById(1L).get(); + log.debug("用户部门={}", JSONArray.toJSONString((List)userDao.findById(1L).get().getDepartmentList())); + + + departmentDao.findById(2L).ifPresent(dept -> { + Collection userlist = dept.getUserList(); + //关联关系由user维护中间表,department userlist不会发生变化,可以增加查询方法来处理 重写getUserList方法 + log.debug("部门下用户={}", JSONArray.toJSONString((List)userlist)); + }); + + + userDao.findById(1L).ifPresent(user -> { + user.setName("清空部门"); + user.setDepartmentList(null); + userDao.save(user); + }); + log.debug("用户部门={}", userDao.findById(1L).get().getDepartmentList()); + + + } + + +}