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