Browse Source

refactor: 将Quiz的questions和QuizStudentAnswer的answers列属性改为json

ChenSiTong 6 years ago
parent
commit
868c2f7853

+ 6 - 0
pom.xml

@@ -111,6 +111,12 @@
             <artifactId>gson</artifactId>
             <version>2.8.6</version>
         </dependency>
+
+        <dependency>
+            <groupId>com.vladmihalcea</groupId>
+            <artifactId>hibernate-types-52</artifactId>
+            <version>2.9.5</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 1 - 1
src/main/java/nju/seec/helper/entity/Admin.java

@@ -15,7 +15,7 @@ public class Admin {
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
 
-    @Column(nullable = false, unique = true)
+    @Column(nullable = false)
     private String username;
 
     @Column(nullable = false)

+ 5 - 2
src/main/java/nju/seec/helper/entity/Comment.java

@@ -2,6 +2,7 @@ package nju.seec.helper.entity;
 
 import lombok.Data;
 import lombok.experimental.Accessors;
+import org.hibernate.annotations.ColumnDefault;
 import org.hibernate.annotations.CreationTimestamp;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
@@ -32,10 +33,12 @@ public class Comment {
     @Column(name = "page_number", nullable = false)
     private Integer pageNumber;
 
-    @Column(name = "`show`", nullable = false, columnDefinition = "bit(1) default true not null")
+    @ColumnDefault("true")
+    @Column(name = "`show`", nullable = false)
     private Boolean show = true;
 
-    @Column(name = "top_number", nullable = false, columnDefinition = "int default 0 not null")
+    @ColumnDefault("0")
+    @Column(name = "top_number", nullable = false)
     private Integer topNumber = 0;
 
     @Column(nullable = false)

+ 3 - 1
src/main/java/nju/seec/helper/entity/Course.java

@@ -2,6 +2,7 @@ package nju.seec.helper.entity;
 
 import lombok.Data;
 import lombok.experimental.Accessors;
+import org.hibernate.annotations.ColumnDefault;
 import org.hibernate.annotations.CreationTimestamp;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
@@ -41,6 +42,7 @@ public class Course {
     @JoinColumn(name = "teacher_id", nullable = false, foreignKey = @ForeignKey(name = "course_teacher"))
     private User teacher;
 
-    @Column(name = "delete_at", columnDefinition = "bigint default 0 not null")
+    @ColumnDefault("0")
+    @Column(name = "delete_at", nullable = false)
     private Long deleteAt = 0L;
 }

+ 3 - 1
src/main/java/nju/seec/helper/entity/Message.java

@@ -3,6 +3,7 @@ package nju.seec.helper.entity;
 import lombok.Data;
 import lombok.experimental.Accessors;
 import nju.seec.helper.enums.MessageType;
+import org.hibernate.annotations.ColumnDefault;
 import org.hibernate.annotations.CreationTimestamp;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
@@ -37,7 +38,8 @@ public class Message {
     @Column(nullable = false)
     private String content;
 
-    @Column(name = "`read`", columnDefinition = "bit(1) default false not null")
+    @ColumnDefault("false")
+    @Column(name = "`read`", nullable = false)
     private Boolean read = false;
 
     @Column(name = "create_at", nullable = false, updatable = false)

+ 9 - 9
src/main/java/nju/seec/helper/entity/Quiz.java

@@ -2,14 +2,14 @@ package nju.seec.helper.entity;
 
 import lombok.Data;
 import lombok.experimental.Accessors;
-import nju.seec.helper.entity.converter.ListConverter;
 import nju.seec.helper.enums.QuizState;
 import nju.seec.helper.enums.QuizType;
-import org.hibernate.annotations.CreationTimestamp;
-import org.hibernate.annotations.DynamicInsert;
-import org.hibernate.annotations.DynamicUpdate;
-import org.hibernate.annotations.UpdateTimestamp;
+import org.hibernate.annotations.*;
 
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.ForeignKey;
+import javax.persistence.Table;
 import javax.persistence.*;
 import java.time.LocalDateTime;
 import java.util.List;
@@ -47,7 +47,8 @@ public class Quiz {
     @JoinColumn(name = "teacher_id", foreignKey = @ForeignKey(name = "quiz_teacher"))
     private User teacher;
 
-    @Convert(converter = ListConverter.class)
+    @Type(type = "json")
+    @Column(columnDefinition = "json", nullable = false)
     private List<String> questions;
 
     @Enumerated(value = EnumType.STRING)
@@ -61,16 +62,15 @@ public class Quiz {
     @Column(name = "max_submit_number", nullable = false)
     private Integer maxSubmitNumber;
 
-    @Basic
     @Column(name = "create_at", nullable = false, updatable = false)
     @CreationTimestamp
     private LocalDateTime createAt;
 
-    @Basic
     @Column(name = "update_at", nullable = false)
     @UpdateTimestamp
     private LocalDateTime updateAt;
 
-    @Column(name = "delete_at", nullable = false, columnDefinition = "bigint default 0 not null")
+    @ColumnDefault("0")
+    @Column(name = "delete_at", nullable = false)
     private Long deleteAt = 0L;
 }

+ 9 - 8
src/main/java/nju/seec/helper/entity/QuizStudentAnswer.java

@@ -3,12 +3,13 @@ package nju.seec.helper.entity;
 
 import lombok.Data;
 import lombok.experimental.Accessors;
-import nju.seec.helper.entity.converter.MapConverter;
-import org.hibernate.annotations.DynamicInsert;
-import org.hibernate.annotations.DynamicUpdate;
-import org.hibernate.annotations.UpdateTimestamp;
+import org.hibernate.annotations.*;
 
 import javax.persistence.*;
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.ForeignKey;
+import javax.persistence.Table;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.util.Map;
@@ -38,16 +39,16 @@ public class QuizStudentAnswer {
     @JoinColumn(name = "student_id", foreignKey = @ForeignKey(name = "answer_student"))
     private User student;
 
-    @SuppressWarnings("all")
-    @Convert(converter = MapConverter.class)
-    @Column(nullable = false)
+    @Type(type = "json")
+    @Column(columnDefinition = "json", nullable = false)
     private Map<String, Object> answers;
 
     @Column(name = "submit_at", nullable = false)
     @UpdateTimestamp
     private LocalDateTime submitAt;
 
-    @Column(name = "submit_number", nullable = false, columnDefinition = "int default 1 not null")
+    @ColumnDefault("1")
+    @Column(name = "submit_number", nullable = false)
     private Integer submitNumber = 0;
 
     @Column(nullable = false)

+ 7 - 5
src/main/java/nju/seec/helper/entity/Slide.java

@@ -3,11 +3,12 @@ package nju.seec.helper.entity;
 import lombok.Data;
 import lombok.experimental.Accessors;
 import nju.seec.helper.enums.SlideState;
-import org.hibernate.annotations.CreationTimestamp;
-import org.hibernate.annotations.DynamicInsert;
-import org.hibernate.annotations.DynamicUpdate;
-import org.hibernate.annotations.UpdateTimestamp;
+import org.hibernate.annotations.*;
 
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.ForeignKey;
+import javax.persistence.Table;
 import javax.persistence.*;
 import java.time.LocalDateTime;
 
@@ -55,6 +56,7 @@ public class Slide {
     @Column(nullable = false)
     private Integer pages;
 
-    @Column(name = "delete_at", columnDefinition = "bigint default 0 not null")
+    @ColumnDefault("0")
+    @Column(name = "delete_at", nullable = false)
     private Long deleteAt = 0L;
 }

+ 5 - 3
src/main/java/nju/seec/helper/entity/User.java

@@ -4,6 +4,7 @@ import lombok.Data;
 import lombok.experimental.Accessors;
 import nju.seec.helper.enums.UserState;
 import nju.seec.helper.enums.UserType;
+import org.hibernate.annotations.ColumnDefault;
 import org.hibernate.annotations.CreationTimestamp;
 import org.hibernate.annotations.DynamicInsert;
 import org.hibernate.annotations.DynamicUpdate;
@@ -30,14 +31,14 @@ public class User {
     @Column(nullable = false)
     private String name;
 
-    @Column(nullable = false, unique = true)
+    @Column(nullable = false)
     private String email;
 
     @Enumerated(EnumType.STRING)
     @Column(nullable = false, updatable = false)
     private UserType type;
 
-    @Column(nullable = false, unique = true)
+    @Column(nullable = false)
     private String phone;
 
     @Column(nullable = false)
@@ -47,7 +48,8 @@ public class User {
     @CreationTimestamp
     private LocalDateTime createAt;
 
+    @ColumnDefault("'NORMAL'")
     @Enumerated(EnumType.STRING)
-    @Column(nullable = false, columnDefinition = "varchar(255) default 'NORMAL' not null")
+    @Column(nullable = false)
     private UserState state;
 }

+ 0 - 23
src/main/java/nju/seec/helper/entity/converter/ListConverter.java

@@ -1,23 +0,0 @@
-package nju.seec.helper.entity.converter;
-
-import com.google.gson.reflect.TypeToken;
-import nju.seec.helper.util.JsonUtils;
-
-import javax.persistence.AttributeConverter;
-import java.util.List;
-
-/**
- * @author cst
- */
-public class ListConverter implements AttributeConverter<List<String>, String> {
-    @Override
-    public String convertToDatabaseColumn(List<String> attribute) {
-        return JsonUtils.toJson(attribute);
-    }
-
-    @Override
-    public List<String> convertToEntityAttribute(String dbData) {
-        return JsonUtils.fromJson(dbData, new TypeToken<List<String>>() {
-        });
-    }
-}

+ 0 - 23
src/main/java/nju/seec/helper/entity/converter/MapConverter.java

@@ -1,23 +0,0 @@
-package nju.seec.helper.entity.converter;
-
-import com.google.gson.reflect.TypeToken;
-import nju.seec.helper.util.JsonUtils;
-
-import javax.persistence.AttributeConverter;
-import java.util.Map;
-
-/**
- * @author cst
- */
-public class MapConverter implements AttributeConverter<Map<String, Object>, String> {
-    @Override
-    public String convertToDatabaseColumn(Map<String, Object> attribute) {
-        return JsonUtils.toJson(attribute);
-    }
-
-    @Override
-    public Map<String, Object> convertToEntityAttribute(String dbData) {
-        return JsonUtils.fromJson(dbData, new TypeToken<Map<String, Object>>() {
-        });
-    }
-}

+ 5 - 0
src/main/java/nju/seec/helper/entity/package-info.java

@@ -0,0 +1,5 @@
+@TypeDef(name = "json", typeClass = JsonStringType.class)
+package nju.seec.helper.entity;
+
+import com.vladmihalcea.hibernate.type.json.JsonStringType;
+import org.hibernate.annotations.TypeDef;

+ 18 - 0
src/main/java/nju/seec/helper/service/AdminService.java

@@ -32,9 +32,27 @@ public interface AdminService {
      */
     Page<UserVO> getUsers(UserType type, UserState state, String key, Pageable pageable);
 
+    /**
+     * 审核通过用户
+     *
+     * @param admin
+     * @param userId
+     */
     void passUser(LoginUser admin, Long userId);
 
+    /**
+     * 封禁用户
+     *
+     * @param admin
+     * @param userId
+     */
     void lockUser(LoginUser admin, Long userId);
 
+    /**
+     * 解封用户
+     *
+     * @param admin
+     * @param userId
+     */
     void unlockUser(LoginUser admin, Long userId);
 }

+ 5 - 14
src/main/java/nju/seec/helper/service/impl/CourseFileServiceImpl.java

@@ -12,9 +12,8 @@ import nju.seec.helper.exception.HelperException;
 import nju.seec.helper.service.CourseFileService;
 import nju.seec.helper.service.CourseService;
 import nju.seec.helper.service.util.AuthUtils;
-import nju.seec.helper.util.Consts;
+import nju.seec.helper.service.util.OssObjectUrlUtils;
 import nju.seec.helper.util.OssUtils;
-import nju.seec.helper.util.RedisCacheUtils;
 import nju.seec.helper.vo.CourseFileVO;
 import org.springframework.data.domain.Page;
 import org.springframework.data.domain.Pageable;
@@ -23,7 +22,6 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
-import java.util.concurrent.TimeUnit;
 
 /**
  * @author cst
@@ -31,7 +29,6 @@ import java.util.concurrent.TimeUnit;
 @Service
 public class CourseFileServiceImpl implements CourseFileService {
     private static final String COURSE_FILE_STORE_DIR = "course_file";
-    private static final long COURSE_FILE_URL_LIVING_SECONDS = 20 * 60;
 
     private final CourseDAO courseDAO;
     private final CourseFileDAO courseFileDAO;
@@ -39,14 +36,14 @@ public class CourseFileServiceImpl implements CourseFileService {
     private final CourseService courseService;
 
     private final OssUtils ossUtils;
-    private final RedisCacheUtils cacheUtils;
+    private final OssObjectUrlUtils ossObjectUrlUtils;
 
-    public CourseFileServiceImpl(CourseDAO courseDAO, CourseFileDAO courseFileDAO, CourseService courseService, OssUtils ossUtils, RedisCacheUtils cacheUtils) {
+    public CourseFileServiceImpl(CourseDAO courseDAO, CourseFileDAO courseFileDAO, CourseService courseService, OssUtils ossUtils, OssObjectUrlUtils ossObjectUrlUtils) {
         this.courseDAO = courseDAO;
         this.courseFileDAO = courseFileDAO;
         this.courseService = courseService;
         this.ossUtils = ossUtils;
-        this.cacheUtils = cacheUtils;
+        this.ossObjectUrlUtils = ossObjectUrlUtils;
     }
 
     @Transactional(rollbackFor = Exception.class)
@@ -101,13 +98,7 @@ public class CourseFileServiceImpl implements CourseFileService {
             throw HelperException.of(ExceptionType.FORBIDDEN, "您无权获取该附件的链接");
         }
 
-        String url = cacheUtils.get(Consts.COURSE_FILE_URL_CACHE_NAME, courseFile.getObjectName());
-        if (url != null) {
-            return url;
-        }
-        url = ossUtils.getUrl(courseFile.getObjectName(), COURSE_FILE_URL_LIVING_SECONDS);
-        cacheUtils.set(Consts.COURSE_FILE_URL_CACHE_NAME, courseFile.getObjectName(), url, COURSE_FILE_URL_LIVING_SECONDS, TimeUnit.SECONDS);
-        return url;
+        return ossObjectUrlUtils.getUrl(courseFile.getObjectName());
     }
 
     private String getCourseFileObjectName(Long courseId, String fileName) {

+ 8 - 16
src/main/java/nju/seec/helper/service/impl/SlideServiceImpl.java

@@ -22,10 +22,9 @@ import nju.seec.helper.service.MessageService;
 import nju.seec.helper.service.QuizService;
 import nju.seec.helper.service.SlideService;
 import nju.seec.helper.service.util.AuthUtils;
+import nju.seec.helper.service.util.OssObjectUrlUtils;
 import nju.seec.helper.service.util.StringUtils;
-import nju.seec.helper.util.Consts;
 import nju.seec.helper.util.OssUtils;
-import nju.seec.helper.util.RedisCacheUtils;
 import nju.seec.helper.util.file.FileInfo;
 import nju.seec.helper.util.file.FileUtils;
 import nju.seec.helper.vo.SlideVO;
@@ -38,7 +37,6 @@ import org.springframework.web.multipart.MultipartFile;
 
 import java.io.File;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 
 /**
  * @author cst
@@ -46,32 +44,32 @@ import java.util.concurrent.TimeUnit;
 @Service
 public class SlideServiceImpl implements SlideService {
     private static final String SLIDE_STORE_DIR = "slide";
-    private static final long SLIDE_URL_LIVING_SECONDS = 20 * 60;
 
     private final CourseDAO courseDAO;
     private final SlideDAO slideDAO;
     private final ChooseDAO chooseDAO;
     private final UserDAO userDAO;
 
-    private final QuizService quizService;
     private final OssUtils ossUtils;
-    private final RedisCacheUtils cacheUtils;
+    private final OssObjectUrlUtils ossObjectUrlUtils;
 
+    private final QuizService quizService;
     private final MessageService messageService;
     private final CourseService courseService;
 
-    public SlideServiceImpl(CourseDAO courseDAO, SlideDAO slideDAO, ChooseDAO chooseDAO, UserDAO userDAO, OssUtils ossUtils, RedisCacheUtils cacheUtils, MessageService messageService, QuizService quizService, CourseService courseService) {
+    public SlideServiceImpl(CourseDAO courseDAO, SlideDAO slideDAO, ChooseDAO chooseDAO, UserDAO userDAO, OssUtils ossUtils, OssObjectUrlUtils ossObjectUrlUtils, QuizService quizService, MessageService messageService, CourseService courseService) {
         this.courseDAO = courseDAO;
         this.slideDAO = slideDAO;
         this.chooseDAO = chooseDAO;
         this.userDAO = userDAO;
         this.ossUtils = ossUtils;
-        this.cacheUtils = cacheUtils;
-        this.messageService = messageService;
+        this.ossObjectUrlUtils = ossObjectUrlUtils;
         this.quizService = quizService;
+        this.messageService = messageService;
         this.courseService = courseService;
     }
 
+
     @Transactional(rollbackFor = Exception.class)
     @SneakyThrows
     @Override
@@ -236,13 +234,7 @@ public class SlideServiceImpl implements SlideService {
             throw HelperException.of(ExceptionType.FORBIDDEN, "您无权获取该课件的链接");
         }
 
-        String url = cacheUtils.get(Consts.SLIDE_URL_CACHE_NAME, slide.getObjectName());
-        if (url != null) {
-            return url;
-        }
-        url = ossUtils.getUrl(slide.getObjectName(), SLIDE_URL_LIVING_SECONDS);
-        cacheUtils.set(Consts.SLIDE_URL_CACHE_NAME, slide.getObjectName(), url, SLIDE_URL_LIVING_SECONDS, TimeUnit.SECONDS);
-        return url;
+        return ossObjectUrlUtils.getUrl(slide.getObjectName());
     }
 
     @Transactional(readOnly = true)

+ 33 - 0
src/main/java/nju/seec/helper/service/util/OssObjectUrlUtils.java

@@ -0,0 +1,33 @@
+package nju.seec.helper.service.util;
+
+import nju.seec.helper.util.Consts;
+import nju.seec.helper.util.OssUtils;
+import nju.seec.helper.util.RedisCacheUtils;
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author cst
+ */
+@Component
+public class OssObjectUrlUtils {
+    private static final String OSS_OBJECT_URL_NAME = Consts.SYS_NAME + "_oss_object_url";
+    private static final long OSS_OBJECT_URL_LIVING_SECONDS = 20 * 60;
+    private final RedisCacheUtils cacheUtils;
+    private final OssUtils ossUtils;
+
+    public OssObjectUrlUtils(RedisCacheUtils cacheUtils, OssUtils ossUtils) {
+        this.cacheUtils = cacheUtils;
+        this.ossUtils = ossUtils;
+    }
+
+    public String getUrl(String objectName) {
+        String url = cacheUtils.get(OSS_OBJECT_URL_NAME, objectName);
+        if (url == null) {
+            url = ossUtils.getUrl(objectName, OSS_OBJECT_URL_LIVING_SECONDS);
+            cacheUtils.set(OSS_OBJECT_URL_NAME, objectName, url, OSS_OBJECT_URL_LIVING_SECONDS, TimeUnit.SECONDS);
+        }
+        return url;
+    }
+}

+ 4 - 5
src/main/java/nju/seec/helper/util/Consts.java

@@ -4,10 +4,9 @@ package nju.seec.helper.util;
  * @author cst
  */
 public class Consts {
-    public static final String SESSION_USER_NAME = "helper_user";
+    public static final String SYS_NAME = "helper";
 
-    public static final String EMAIL_CACHE_NAME = "email";
-    public static final String PHONE_CACHE_NAME = "phone";
-    public static final String SLIDE_URL_CACHE_NAME = "slide_url";
-    public static final String COURSE_FILE_URL_CACHE_NAME = "course_file_url";
+    public static final String SESSION_USER_NAME = SYS_NAME + "_user";
+    public static final String EMAIL_CACHE_NAME = SYS_NAME + "_email";
+    public static final String PHONE_CACHE_NAME = SYS_NAME + "_phone";
 }