From 03894721239b0a6dbb9b965f38fabd6f251d2f7d Mon Sep 17 00:00:00 2001 From: guoc <770292311@qq.com> Date: Sun, 7 Nov 2021 23:32:52 +0800 Subject: [PATCH] feat(jpa): jpa useguid --- orm-demos/jpa-demos/jpa-sample/pom.xml | 41 ++++++ .../main/java/com/gsean/jpa/JpaSampleApp.java | 20 +++ .../com/gsean/jpa/config/MyAuditorAware.java | 21 +++ .../java/com/gsean/jpa/entity/Department.java | 58 ++++++++ .../main/java/com/gsean/jpa/enums/Status.java | 13 ++ .../java/com/gsean/jpa/enums/StatusV2.java | 38 +++++ .../gsean/jpa/enums/StatusV2Converter.java | 23 +++ .../gsean/jpa/repository/DepartmentDao.java | 7 + .../src/main/resources/application.yml | 18 +++ .../src/main/resources/sql/department.sql | 37 +++++ .../java/com/gsean/jpa/JpaSampleAppTest.java | 137 ++++++++++++++++++ orm-demos/jpa-demos/pom.xml | 23 +++ orm-demos/pom.xml | 23 +++ pom.xml | 1 + 14 files changed, 460 insertions(+) create mode 100644 orm-demos/jpa-demos/jpa-sample/pom.xml create mode 100644 orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/JpaSampleApp.java create mode 100644 orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/config/MyAuditorAware.java create mode 100644 orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/entity/Department.java create mode 100644 orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/Status.java create mode 100644 orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/StatusV2.java create mode 100644 orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/StatusV2Converter.java create mode 100644 orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/repository/DepartmentDao.java create mode 100644 orm-demos/jpa-demos/jpa-sample/src/main/resources/application.yml create mode 100644 orm-demos/jpa-demos/jpa-sample/src/main/resources/sql/department.sql create mode 100644 orm-demos/jpa-demos/jpa-sample/src/test/java/com/gsean/jpa/JpaSampleAppTest.java create mode 100644 orm-demos/jpa-demos/pom.xml create mode 100644 orm-demos/pom.xml diff --git a/orm-demos/jpa-demos/jpa-sample/pom.xml b/orm-demos/jpa-demos/jpa-sample/pom.xml new file mode 100644 index 0000000..c57705d --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/pom.xml @@ -0,0 +1,41 @@ + + + + jpa-demos + com.gsean.demos + 1.0-SNAPSHOT + + 4.0.0 + + jpa-sample + + + 11 + 11 + + + + + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-starter-web + + + mysql + mysql-connector-java + runtime + + + com.alibaba + fastjson + + + + \ No newline at end of file diff --git a/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/JpaSampleApp.java b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/JpaSampleApp.java new file mode 100644 index 0000000..92cbe74 --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/JpaSampleApp.java @@ -0,0 +1,20 @@ +package com.gsean.jpa; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +/** + * @ClassName JpaSampleApp + * @Description TODO + * @Author guocheng + * @Date 2021/11/4 22:37 + * @Version 1.0 + **/ +@SpringBootApplication +@EnableJpaAuditing +public class JpaSampleApp { + public static void main(String[] args) { + SpringApplication.run(JpaSampleApp.class,args); + } +} diff --git a/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/config/MyAuditorAware.java b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/config/MyAuditorAware.java new file mode 100644 index 0000000..c31dff1 --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/config/MyAuditorAware.java @@ -0,0 +1,21 @@ +package com.gsean.jpa.config; + +import org.springframework.data.domain.AuditorAware; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +/** + * @ClassName MyAuditorA + * @Description TODO + * @Author guocheng + * @Date 2021/11/7 22:10 + * @Version 1.0 + **/ +@Component +public class MyAuditorAware implements AuditorAware { + @Override + public Optional getCurrentAuditor() { + return Optional.ofNullable(1L); + } +} diff --git a/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/entity/Department.java b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/entity/Department.java new file mode 100644 index 0000000..18759a5 --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/entity/Department.java @@ -0,0 +1,58 @@ +package com.gsean.jpa.entity; + +import com.gsean.jpa.enums.Status; +import lombok.Data; +import lombok.experimental.Accessors; +import org.springframework.data.annotation.CreatedBy; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedBy; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.LocalDateTime; + +@Data +@Entity +@Table(name = "department") +@Accessors(chain = true) +@EntityListeners(AuditingEntityListener.class) +public class Department implements Serializable { + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + private Long id; + + private String name; + + @Column(name = "parent_id") + private Long parentId; + + @Column(name="status") + @Enumerated(value = EnumType.STRING) + private Status status; + + @Column(name="created_by") + @CreatedBy + private Long createdBy; + + @Column(name="last_modified_by") + @LastModifiedBy + private Long lastModifiedBy; + + @Column(name = "created_at") + @CreatedDate + private LocalDateTime createdAt; + + @Column(name = "lastModifiedAt") + @LastModifiedDate + private LocalDateTime lastModifiedAt; + + @Version + private Long version; + + + + +} diff --git a/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/Status.java b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/Status.java new file mode 100644 index 0000000..6443504 --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/Status.java @@ -0,0 +1,13 @@ +package com.gsean.jpa.enums; + +public enum Status { + + ACTIVE("可用"), + UNACTIVE("不可用"); + + private String des; + + Status(String des) { + this.des = des; + } +} diff --git a/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/StatusV2.java b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/StatusV2.java new file mode 100644 index 0000000..26a0273 --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/StatusV2.java @@ -0,0 +1,38 @@ +package com.gsean.jpa.enums; + +import java.util.Objects; + +public enum StatusV2 { + ACTIVE(1,"可用"), + UNACTIVE(2,"不可用"); + + private Integer code; + private String des; + + StatusV2(Integer code,String des) { + this.code=code; + this.des = des; + } + + public Integer getCode() { + return code; + } + + public String getDes() { + return des; + } + + //获取枚举实例 + public static StatusV2 fromValue(Integer value) { + for (StatusV2 statusEnum : StatusV2.values()) { + if (Objects.equals(value, statusEnum.getCode())) { + return statusEnum; + } + } + throw new IllegalArgumentException(); + } + + public static void main(String[] args) { + System.out.println(StatusV2.ACTIVE.getCode()); + } +} diff --git a/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/StatusV2Converter.java b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/StatusV2Converter.java new file mode 100644 index 0000000..45ff50e --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/enums/StatusV2Converter.java @@ -0,0 +1,23 @@ +package com.gsean.jpa.enums; + +import javax.persistence.AttributeConverter; + +/** + * @ClassName StatusV2Converter + * @Description TODO + * @Author guocheng + * @Date 2021/11/5 22:09 + * @Version 1.0 + **/ +public class StatusV2Converter implements AttributeConverter { + @Override + public Integer convertToDatabaseColumn(StatusV2 statusV2) { + return statusV2.getCode(); + } + + @Override + public StatusV2 convertToEntityAttribute(Integer code) { + return StatusV2.fromValue(code); + + } +} diff --git a/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/repository/DepartmentDao.java b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/repository/DepartmentDao.java new file mode 100644 index 0000000..e123774 --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/src/main/java/com/gsean/jpa/repository/DepartmentDao.java @@ -0,0 +1,7 @@ +package com.gsean.jpa.repository; + +import com.gsean.jpa.entity.Department; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface DepartmentDao extends JpaRepository { +} diff --git a/orm-demos/jpa-demos/jpa-sample/src/main/resources/application.yml b/orm-demos/jpa-demos/jpa-sample/src/main/resources/application.yml new file mode 100644 index 0000000..681dddf --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/src/main/resources/application.yml @@ -0,0 +1,18 @@ +server: + port: 8082 + + +spring: + datasource: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://localhost:3306/jpa_test + username: root + password: 123456 + jpa: + show-sql: true + properties.hibernate.format_sql: true + + +logging: + level: + org.hibernate.type.descriptor.sql.BasicBinder: trace \ No newline at end of file diff --git a/orm-demos/jpa-demos/jpa-sample/src/main/resources/sql/department.sql b/orm-demos/jpa-demos/jpa-sample/src/main/resources/sql/department.sql new file mode 100644 index 0000000..f7cdf74 --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/src/main/resources/sql/department.sql @@ -0,0 +1,37 @@ +/* + Navicat Premium Data Transfer + + Source Server : local + Source Server Type : MySQL + Source Server Version : 80022 + Source Host : localhost:3306 + Source Schema : jpa_test + + Target Server Type : MySQL + Target Server Version : 80022 + File Encoding : 65001 + + Date: 07/11/2021 23:31:57 +*/ + +SET NAMES utf8mb4; +SET FOREIGN_KEY_CHECKS = 0; + +-- ---------------------------- +-- Table structure for department +-- ---------------------------- +DROP TABLE IF EXISTS `department`; +CREATE TABLE `department` ( + `id` bigint unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `parent_id` bigint unsigned NOT NULL, + `status` varchar(10) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL, + `created_by` bigint NOT NULL COMMENT '创建人', + `last_modified_by` bigint NOT NULL COMMENT '最后更改人', + `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `last_modified_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间', + `version` bigint NOT NULL COMMENT '版本', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; + +SET FOREIGN_KEY_CHECKS = 1; diff --git a/orm-demos/jpa-demos/jpa-sample/src/test/java/com/gsean/jpa/JpaSampleAppTest.java b/orm-demos/jpa-demos/jpa-sample/src/test/java/com/gsean/jpa/JpaSampleAppTest.java new file mode 100644 index 0000000..78272b8 --- /dev/null +++ b/orm-demos/jpa-demos/jpa-sample/src/test/java/com/gsean/jpa/JpaSampleAppTest.java @@ -0,0 +1,137 @@ +package com.gsean.jpa; + +import com.alibaba.fastjson.JSON; +import com.gsean.jpa.entity.Department; +import com.gsean.jpa.enums.Status; +import com.gsean.jpa.repository.DepartmentDao; +import org.hamcrest.Matchers; +import org.junit.Assert; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.data.domain.Example; +import org.springframework.data.domain.ExampleMatcher; +import org.springframework.transaction.annotation.Transactional; + +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.List; + +@SpringBootTest +class JpaSampleAppTest { + + private static final Long AUDITOR_ID=1L; + private static final String DEPT_NAME="技术部"; + private static final String UPDATE_DEPT_NAME="管理部"; + + @Autowired + private DepartmentDao departmentDao; + + private Department department; + + @BeforeEach + public void init(){ + createDept(); + } + + private void createDept(){ + department=new Department(); + department.setName(DEPT_NAME).setParentId(2L); + } + + + + @Test + @DisplayName("缺省插入") + public void testA(){ + Department addDepartment = new Department(); + addDepartment.setName("test").setParentId(2L).setStatus(Status.ACTIVE); + Department redepartment=departmentDao.saveAndFlush(addDepartment); + System.out.println(addDepartment); + } + + + @Test + @DisplayName("审计测试") + @Transactional + public void testB(){ + LocalDateTime nowTime = LocalDateTime.now(); + System.out.println("当前时间:"+nowTime); + long beforeCount = departmentDao.count(); + departmentDao.saveAndFlush(department); + System.out.println(JSON.toJSONString(department)); + long afterCount = departmentDao.count(); + Assert.assertTrue(afterCount==beforeCount+1); + Assert.assertEquals(AUDITOR_ID,department.getCreatedBy()); + Assert.assertEquals(AUDITOR_ID,department.getLastModifiedBy()); + Assert.assertThat(department.getCreatedAt(), Matchers.greaterThan(nowTime)); + } + + @Test + @DisplayName("更新审计时间测试") + @Transactional + public void testB1() throws Exception{ + LocalDateTime nowTime = LocalDateTime.now(); + System.out.println("当前时间:"+nowTime); + long beforeCount = departmentDao.count(); + departmentDao.saveAndFlush(department); + System.out.println("插入数据:"+JSON.toJSONString(department)); + long afterCount = departmentDao.count(); + Assert.assertTrue(afterCount==beforeCount+1); + Assert.assertEquals(DEPT_NAME,department.getName()); + LocalDateTime lastModifiedAt = department.getLastModifiedAt(); + Thread.sleep(2000); + department.setName(UPDATE_DEPT_NAME); + departmentDao.saveAndFlush(department); + System.out.println("更新后数据:"+JSON.toJSONString(department)); + Assert.assertEquals(UPDATE_DEPT_NAME,department.getName()); + Assert.assertThat(department.getLastModifiedAt(), Matchers.not(lastModifiedAt)); + } + + @Test + @DisplayName("乐观锁测试") + @Transactional + public void testC(){ + long beforeCount = departmentDao.count(); + departmentDao.saveAndFlush(department); + System.out.println("插入数据:"+JSON.toJSONString(department)); + long afterCount = departmentDao.count(); + Assert.assertTrue(afterCount==beforeCount+1); + Long initVersion = department.getVersion(); + Assert.assertNotNull(initVersion); + department.setName(UPDATE_DEPT_NAME); + departmentDao.saveAndFlush(department); + System.out.println("更新后数据:"+JSON.toJSONString(department)); + Assert.assertTrue(UPDATE_DEPT_NAME.equals(department.getName())); + Assert.assertTrue(department.getVersion()==initVersion+1); + } + + + @Test + @DisplayName("QBE查询测试") + @Transactional + public void testD(){ + Department dept01 = new Department().setName("dept01").setStatus(Status.ACTIVE).setParentId(1L); + Department dept02 = new Department().setName("dept02").setStatus(Status.ACTIVE).setParentId(1L); + Department dept03 = new Department().setName("dept03").setStatus(Status.UNACTIVE).setParentId(1L); + List departments = Arrays.asList(dept01, dept02, dept03); + departmentDao.saveAll(departments); + List departmentList = departmentDao.findAll(); + System.out.println("所有部门:"+JSON.toJSONString(departmentList)); + + Department qDept=new Department().setName("dept"); + ExampleMatcher matcher = ExampleMatcher.matching() + .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.startsWith()); + Example departmentExample = Example.of(qDept, matcher); + List exampleAll = departmentDao.findAll(departmentExample); + System.out.println("匹配查询部门:"+JSON.toJSONString(departmentList)); + Assert.assertTrue(exampleAll.size()==3); + + + } + + + +} \ No newline at end of file diff --git a/orm-demos/jpa-demos/pom.xml b/orm-demos/jpa-demos/pom.xml new file mode 100644 index 0000000..3621282 --- /dev/null +++ b/orm-demos/jpa-demos/pom.xml @@ -0,0 +1,23 @@ + + + + orm-demos + com.gsean.demos + 1.0-SNAPSHOT + + 4.0.0 + + jpa-demos + pom + + jpa-sample + + + + 11 + 11 + + + \ No newline at end of file diff --git a/orm-demos/pom.xml b/orm-demos/pom.xml new file mode 100644 index 0000000..e114b65 --- /dev/null +++ b/orm-demos/pom.xml @@ -0,0 +1,23 @@ + + + + gsean-springboot-demos + com.gsean.demos + 1.0-SNAPSHOT + + 4.0.0 + + orm-demos + pom + + jpa-demos + + + + 11 + 11 + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index b607017..54f4e9c 100644 --- a/pom.xml +++ b/pom.xml @@ -38,6 +38,7 @@ docker-demos git-demos mongodb-demes + orm-demos -- Gitee