學(xué)習(xí)完整課程請(qǐng)移步 互聯(lián)網(wǎng) Java 全棧工程師
本節(jié)視頻
概述
以下代碼按照項(xiàng)目順序新增或變更的類與配置文件,具體操作請(qǐng)參考視頻邑遏;本集視頻包含大量重構(gòu)手法妹懒,喜歡的小伙伴千萬不要錯(cuò)過啊终。
myshop-commons
POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.funtl</groupId>
<artifactId>myshop-dependencies</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../myshop-dependencies/pom.xml</relativePath>
</parent>
<artifactId>myshop-commons</artifactId>
<packaging>jar</packaging>
<name>myshop-commons</name>
<url>http://www.funtl.com</url>
<inceptionYear>2018-Now</inceptionYear>
<dependencies>
<!-- Spring Begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<scope>provided</scope>
</dependency>
<!-- Spring End -->
<!-- Apache Begin -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!-- Apache End -->
<!-- Commons Begin -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
</dependency>
<!-- Commons End -->
<!-- Projects Begin -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- Projects End -->
</dependencies>
</project>
AbstractBaseDomain
package com.funtl.myshop.commons.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable;
import java.util.Date;
/**
* 通用的領(lǐng)域模型
* <p>Title: AbstractBaseDomain</p>
* <p>Description: </p>
*
* @author Lusifer
* @version 1.0.0
* @date 2019/1/23 15:50
*/
@Data
public abstract class AbstractBaseDomain implements Serializable {
/**
* 該注解需要保留,用于 tk.mybatis 回顯 ID
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
/**
* 格式化日期刻蟹,由于是北京時(shí)間(我們是在東八區(qū)),所以時(shí)區(qū) +8
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date created;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date updated;
}
AbstractBaseResult
package com.funtl.myshop.commons.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import java.io.Serializable;
/**
* 通用的響應(yīng)結(jié)果
* <p>Title: AbstractBaseResult</p>
* <p>Description: </p>
*
* @author Lusifer
* @version 1.0.0
* @date 2019/1/23 15:10
*/
@Data
public abstract class AbstractBaseResult implements Serializable {
/**
* 此為內(nèi)部類
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
protected static class Links {
private String self;
private String next;
private String last;
}
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
protected static class DataBean<T extends AbstractBaseDomain> {
private String type;
private Long id;
private T attributes;
private T relationships;
private Links links;
}
}
BaseResultFactory
package com.funtl.myshop.commons.dto;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 通用響應(yīng)結(jié)構(gòu)工廠
* <p>Title: BaseResultFactory</p>
* <p>Description: </p>
*
* @author Lusifer
* @version 1.0.0
* @date 2019/1/23 15:16
*/
@SuppressWarnings("all")
public class BaseResultFactory<T extends AbstractBaseDomain> {
/**
* 設(shè)置日志級(jí)別,用于限制發(fā)生錯(cuò)誤時(shí)蚤吹,是否顯示調(diào)試信息(detail)
*
* @see ErrorResult#detail
*/
public static final String LOGGER_LEVEL_DEBUG = "DEBUG";
private static BaseResultFactory baseResultFactory;
private BaseResultFactory() {
}
// 設(shè)置通用的響應(yīng)
private static HttpServletResponse response;
public static BaseResultFactory getInstance(HttpServletResponse response) {
if (baseResultFactory == null) {
synchronized (BaseResultFactory.class) {
if (baseResultFactory == null) {
baseResultFactory = new BaseResultFactory();
}
}
}
BaseResultFactory.response = response;
// 設(shè)置通用響應(yīng)
baseResultFactory.initResponse();
return baseResultFactory;
}
/**
* 構(gòu)建單筆數(shù)據(jù)結(jié)果集
*
* @param self 當(dāng)前請(qǐng)求路徑
* @return
*/
public AbstractBaseResult build(String self, T attributes) {
return new SuccessResult(self, attributes);
}
/**
* 構(gòu)建多筆數(shù)據(jù)結(jié)果集
*
* @param self 當(dāng)前請(qǐng)求路徑
* @param next 下一頁的頁碼
* @param last 最后一頁的頁碼
* @return
*/
public AbstractBaseResult build(String self, int next, int last, List<T> attributes) {
return new SuccessResult(self, next, last, attributes);
}
/**
* 構(gòu)建請(qǐng)求錯(cuò)誤的響應(yīng)結(jié)構(gòu)
*
* @param code HTTP 狀態(tài)碼
* @param title 錯(cuò)誤信息
* @param detail 調(diào)試信息
* @param level 日志級(jí)別,只有 DEBUG 時(shí)才顯示詳情
* @return
*/
public AbstractBaseResult build(int code, String title, String detail, String level) {
// 設(shè)置請(qǐng)求失敗的響應(yīng)碼
response.setStatus(code);
if (LOGGER_LEVEL_DEBUG.equals(level)) {
return new ErrorResult(code, title, detail);
} else {
return new ErrorResult(code, title, null);
}
}
/**
* 初始化 HttpServletResponse
*/
private void initResponse() {
// 需要符合 JSON API 規(guī)范
response.setHeader("Content-Type", "application/vnd.api+json");
}
}
ErrorResult
package com.funtl.myshop.commons.dto;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* 請(qǐng)求失敗
* <p>Title: ErrorResult</p>
* <p>Description: </p>
*
* @author Lusifer
* @version 1.0.0
* @date 2019/1/23 15:07
*/
@Data
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
// JSON 不顯示為 null 的屬性
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ErrorResult extends AbstractBaseResult {
private int code;
private String title;
/**
* 調(diào)試信息
*/
private String detail;
}
SuccessResult
package com.funtl.myshop.commons.dto;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
/**
* 請(qǐng)求成功
* <p>Title: SuccessResult</p>
* <p>Description: </p>
*
* @author Lusifer
* @version 1.0.0
* @date 2019/1/23 15:07
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class SuccessResult<T extends AbstractBaseDomain> extends AbstractBaseResult {
private Links links;
private List<DataBean> data;
/**
* 請(qǐng)求的結(jié)果(單筆)
* @param self 當(dāng)前請(qǐng)求路徑
* @param attributes 領(lǐng)域模型
*/
public SuccessResult(String self, T attributes) {
links = new Links();
links.setSelf(self);
createDataBean(null, attributes);
}
/**
* 請(qǐng)求的結(jié)果(分頁)
* @param self 當(dāng)前請(qǐng)求路徑
* @param next 下一頁的頁碼
* @param last 最后一頁的頁碼
* @param attributes 領(lǐng)域模型集合
*/
public SuccessResult(String self, int next, int last, List<T> attributes) {
links = new Links();
links.setSelf(self);
links.setNext(self + "?page=" + next);
links.setLast(self + "?page=" + last);
attributes.forEach(attribute -> createDataBean(self, attribute));
}
/**
* 創(chuàng)建 DataBean
* @param self 當(dāng)前請(qǐng)求路徑
* @param attributes 領(lǐng)域模型
*/
private void createDataBean(String self, T attributes) {
if (data == null) {
data = Lists.newArrayList();
}
DataBean dataBean = new DataBean();
dataBean.setId(attributes.getId());
dataBean.setType(attributes.getClass().getSimpleName());
dataBean.setAttributes(attributes);
if (StringUtils.isNotBlank(self)) {
Links links = new Links();
links.setSelf(self + "/" + attributes.getId());
dataBean.setLinks(links);
}
data.add(dataBean);
}
}
RegexpUtils
package com.funtl.myshop.commons.utils;
/**
* 正則表達(dá)式工具類
* <p>Title: RegexpUtils</p>
* <p>Description: </p>
*
* @author Lusifer
* @version 1.0.0
* @date 2018/6/16 23:48
*/
public class RegexpUtils {
/**
* 驗(yàn)證手機(jī)號(hào)
*/
public static final String PHONE = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
/**
* 驗(yàn)證郵箱地址
*/
public static final String EMAIL = "\\w+(\\.\\w)*@\\w+(\\.\\w{2,3}){1,3}";
/**
* 驗(yàn)證手機(jī)號(hào)
* @param phone
* @return
*/
public static boolean checkPhone(String phone) {
return phone.matches(PHONE);
}
/**
* 驗(yàn)證郵箱
* @param email
* @return
*/
public static boolean checkEmail(String email) {
return email.matches(EMAIL);
}
}
AbstractBaseController
package com.funtl.myshop.commons.web;
import com.funtl.myshop.commons.dto.AbstractBaseDomain;
import com.funtl.myshop.commons.dto.AbstractBaseResult;
import com.funtl.myshop.commons.dto.BaseResultFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ModelAttribute;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* 通用的控制器
* <p>Title: AbstractBaseController</p>
* <p>Description: </p>
*
* @author Lusifer
* @version 1.0.0
* @date 2019/1/25 11:11
*/
public abstract class AbstractBaseController<T extends AbstractBaseDomain> {
// 用于動(dòng)態(tài)獲取配置文件的屬性值
private static final String ENVIRONMENT_LOGGING_LEVEL_MY_SHOP = "logging.level.com.funtl.myshop";
protected HttpServletRequest request;
protected HttpServletResponse response;
@Autowired
private ConfigurableApplicationContext applicationContext;
@ModelAttribute
public void initReqAndRes(HttpServletRequest request, HttpServletResponse response) {
this.request = request;
this.response = response;
}
/**
* 請(qǐng)求成功
* @param self
* @param attribute
* @return
*/
protected AbstractBaseResult success(String self, T attribute) {
return BaseResultFactory.getInstance(response).build(self, attribute);
}
/**
* 請(qǐng)求成功
* @param self
* @param next
* @param last
* @param attributes
* @return
*/
protected AbstractBaseResult success(String self, int next, int last, List<T> attributes) {
return BaseResultFactory.getInstance(response).build(self, next, last, attributes);
}
/**
* 請(qǐng)求失敗
* @param title
* @param detail
* @return
*/
protected AbstractBaseResult error(String title, String detail) {
return error(HttpStatus.UNAUTHORIZED.value(), title, detail);
}
/**
* 請(qǐng)求失敗
* @param code
* @param title
* @param detail
* @return
*/
protected AbstractBaseResult error(int code, String title, String detail) {
return BaseResultFactory.getInstance(response).build(code, title, detail, applicationContext.getEnvironment().getProperty(ENVIRONMENT_LOGGING_LEVEL_MY_SHOP));
}
}
myshop-commons-domain
POM
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.funtl</groupId>
<artifactId>myshop-dependencies</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../myshop-dependencies/pom.xml</relativePath>
</parent>
<artifactId>myshop-commons-domain</artifactId>
<packaging>jar</packaging>
<name>myshop-commons-domain</name>
<url>http://www.funtl.com</url>
<inceptionYear>2018-Now</inceptionYear>
<dependencies>
<!-- Spring Begin -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<!-- Spring End -->
<!-- Commons Begin -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<!-- Commons End -->
<!-- Projects Begin -->
<dependency>
<groupId>com.funtl</groupId>
<artifactId>myshop-commons</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- Projects End -->
</dependencies>
</project>
TbUser
package com.funtl.myshop.commons.domain;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.funtl.myshop.commons.dto.AbstractBaseDomain;
import com.funtl.myshop.commons.utils.RegexpUtils;
import org.hibernate.validator.constraints.Length;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
@Table(name = "tb_user")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class TbUser extends AbstractBaseDomain {
/**
* 用戶名
*/
@NotNull(message = "用戶名不可為空")
@Length(min = 5, max = 20, message = "用戶名長(zhǎng)度必須介于 5 和 20 之間")
private String username;
/**
* 密碼随抠,加密存儲(chǔ)
*/
@JsonIgnore
private String password;
/**
* 注冊(cè)手機(jī)號(hào)
*/
private String phone;
/**
* 注冊(cè)郵箱
*/
@NotNull(message = "郵箱不可為空")
@Pattern(regexp = RegexpUtils.EMAIL, message = "郵箱格式不正確")
private String email;
/**
* 獲取用戶名
*
* @return username - 用戶名
*/
public String getUsername() {
return username;
}
/**
* 設(shè)置用戶名
*
* @param username 用戶名
*/
public void setUsername(String username) {
this.username = username;
}
/**
* 獲取密碼裁着,加密存儲(chǔ)
*
* @return password - 密碼,加密存儲(chǔ)
*/
public String getPassword() {
return password;
}
/**
* 設(shè)置密碼拱她,加密存儲(chǔ)
*
* @param password 密碼二驰,加密存儲(chǔ)
*/
public void setPassword(String password) {
this.password = password;
}
/**
* 獲取注冊(cè)手機(jī)號(hào)
*
* @return phone - 注冊(cè)手機(jī)號(hào)
*/
public String getPhone() {
return phone;
}
/**
* 設(shè)置注冊(cè)手機(jī)號(hào)
*
* @param phone 注冊(cè)手機(jī)號(hào)
*/
public void setPhone(String phone) {
this.phone = phone;
}
/**
* 獲取注冊(cè)郵箱
*
* @return email - 注冊(cè)郵箱
*/
public String getEmail() {
return email;
}
/**
* 設(shè)置注冊(cè)郵箱
*
* @param email 注冊(cè)郵箱
*/
public void setEmail(String email) {
this.email = email;
}
}
BeanValidator
package com.funtl.myshop.commons.validator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* JSR303 Validator(Hibernate Validator)工具類.
* <p>
* ConstraintViolation 中包含 propertyPath, message 和 invalidValue 等信息.
* 提供了各種 convert 方法,適合不同的 i18n 需求:
* 1. List<String>, String 內(nèi)容為 message
* 2. List<String>, String 內(nèi)容為 propertyPath + separator + message
* 3. Map<propertyPath, message>
* <p>
* 詳情見wiki: https://github.com/springside/springside4/wiki/HibernateValidator
*
* <p>Title: BeanValidator</p>
* <p>Description: </p>
*
* @author Lusifer
* @version 1.0.0
* @date 2018/6/26 17:21
*/
@Component
public class BeanValidator {
@Autowired
private Validator validatorInstance;
private static Validator validator;
@PostConstruct
public void init() {
BeanValidator.validator = validatorInstance;
}
/**
* 調(diào)用 JSR303 的 validate 方法, 驗(yàn)證失敗時(shí)拋出 ConstraintViolationException.
*/
private static void validateWithException(Validator validator, Object object, Class<?>... groups) throws ConstraintViolationException {
Set constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty()) {
throw new ConstraintViolationException(constraintViolations);
}
}
/**
* 輔助方法, 轉(zhuǎn)換 ConstraintViolationException 中的 Set<ConstraintViolations> 中為 List<message>.
*/
private static List<String> extractMessage(ConstraintViolationException e) {
return extractMessage(e.getConstraintViolations());
}
/**
* 輔助方法, 轉(zhuǎn)換 Set<ConstraintViolation> 為 List<message>
*/
private static List<String> extractMessage(Set<? extends ConstraintViolation> constraintViolations) {
List<String> errorMessages = new ArrayList<>();
for (ConstraintViolation violation : constraintViolations) {
errorMessages.add(violation.getMessage());
}
return errorMessages;
}
/**
* 輔助方法, 轉(zhuǎn)換 ConstraintViolationException 中的 Set<ConstraintViolations> 為 Map<property, message>.
*/
private static Map<String, String> extractPropertyAndMessage(ConstraintViolationException e) {
return extractPropertyAndMessage(e.getConstraintViolations());
}
/**
* 輔助方法, 轉(zhuǎn)換 Set<ConstraintViolation> 為 Map<property, message>.
*/
private static Map<String, String> extractPropertyAndMessage(Set<? extends ConstraintViolation> constraintViolations) {
Map<String, String> errorMessages = new HashMap<>();
for (ConstraintViolation violation : constraintViolations) {
errorMessages.put(violation.getPropertyPath().toString(), violation.getMessage());
}
return errorMessages;
}
/**
* 輔助方法, 轉(zhuǎn)換 ConstraintViolationException 中的 Set<ConstraintViolations> 為 List<propertyPath message>.
*/
private static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e) {
return extractPropertyAndMessageAsList(e.getConstraintViolations(), " ");
}
/**
* 輔助方法, 轉(zhuǎn)換 Set<ConstraintViolations> 為 List<propertyPath message>.
*/
private static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations) {
return extractPropertyAndMessageAsList(constraintViolations, " ");
}
/**
* 輔助方法, 轉(zhuǎn)換 ConstraintViolationException 中的 Set<ConstraintViolations> 為 List<propertyPath + separator + message>.
*/
private static List<String> extractPropertyAndMessageAsList(ConstraintViolationException e, String separator) {
return extractPropertyAndMessageAsList(e.getConstraintViolations(), separator);
}
/**
* 輔助方法, 轉(zhuǎn)換 Set<ConstraintViolation> 為 List<propertyPath + separator + message>.
*/
private static List<String> extractPropertyAndMessageAsList(Set<? extends ConstraintViolation> constraintViolations, String separator) {
List<String> errorMessages = new ArrayList<>();
for (ConstraintViolation violation : constraintViolations) {
errorMessages.add(violation.getPropertyPath() + separator + violation.getMessage());
}
return errorMessages;
}
/**
* 服務(wù)端參數(shù)有效性驗(yàn)證
*
* @param object 驗(yàn)證的實(shí)體對(duì)象
* @param groups 驗(yàn)證組
* @return 驗(yàn)證成功:返回 null秉沼;驗(yàn)證失斖叭浮:返回錯(cuò)誤信息
*/
public static String validator(Object object, Class<?>... groups) {
try {
validateWithException(validator, object, groups);
} catch (ConstraintViolationException ex) {
List<String> list = extractMessage(ex);
list.add(0, "數(shù)據(jù)驗(yàn)證失敗:");
// 封裝錯(cuò)誤消息為字符串
StringBuilder sb = new StringBuilder();
for (int i = 0; i < list.size(); i++) {
String exMsg = list.get(i);
if (i != 0) {
sb.append(String.format("%s. %s", i, exMsg)).append(list.size() > 1 ? "<br/>" : "");
} else {
sb.append(exMsg).append(list.size() > 1 ? "<br/>" : "");
}
}
return sb.toString();
}
return null;
}
}
myshop-commons-service
BaseCrudService
package com.funtl.myshop.commons.service;
import com.funtl.myshop.commons.dto.AbstractBaseDomain;
/**
* 通用的業(yè)務(wù)邏輯
* <p>Title: BaseCrudService</p>
* <p>Description: </p>
*
* @author Lusifer
* @version 1.0.0
* @date 2019/1/25 9:43
*/
public interface BaseCrudService<T extends AbstractBaseDomain> {
/**
* 查詢屬性值是否唯一
*
* @param property
* @param value
* @return true/唯一唬复,false/不唯一
*/
default boolean unique(String property, String value) {
return false;
}
/**
* 保存
* @param domain
* @return
*/
default T save(T domain) {
return null;
}
}
TbUserService
package com.funtl.myshop.commons.service;
import com.funtl.myshop.commons.domain.TbUser;
public interface TbUserService extends BaseCrudService<TbUser> {
}
BaseCrudServiceImpl
package com.funtl.myshop.commons.service.impl;
import com.funtl.myshop.commons.dto.AbstractBaseDomain;
import com.funtl.myshop.commons.service.BaseCrudService;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.MyMapper;
import tk.mybatis.mapper.entity.Example;
import java.lang.reflect.ParameterizedType;
import java.util.Date;
public class BaseCrudServiceImpl<T extends AbstractBaseDomain, M extends MyMapper<T>> implements BaseCrudService<T> {
@Autowired
protected M mapper;
private Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
@Override
public boolean unique(String property, String value) {
Example example = new Example(entityClass);
example.createCriteria().andEqualTo(property, value);
int result = mapper.selectCountByExample(example);
if (result > 0) {
return false;
}
return true;
}
@Override
public T save(T domain) {
int result = 0;
Date currentDate = new Date();
domain.setUpdated(currentDate);
// 創(chuàng)建
if (domain.getId() == null) {
domain.setCreated(currentDate);
/**
* 用于自動(dòng)回顯 ID矗积,領(lǐng)域模型中需要 @ID 注解的支持
* {@link AbstractBaseDomain}
*/
result = mapper.insertUseGeneratedKeys(domain);
}
// 更新
else {
result = mapper.updateByPrimaryKey(domain);
}
// 保存數(shù)據(jù)成功
if (result > 0) {
return domain;
}
// 保存數(shù)據(jù)失敗
return null;
}
}
TbUserServiceImpl
package com.funtl.myshop.commons.service.impl;
import com.funtl.myshop.commons.domain.TbUser;
import com.funtl.myshop.commons.mapper.TbUserMapper;
import com.funtl.myshop.commons.service.TbUserService;
import org.springframework.stereotype.Service;
@Service
public class TbUserServiceImpl extends BaseCrudServiceImpl<TbUser, TbUserMapper> implements TbUserService {
}
myshop-service-reg
MyShopServiceRegApplication
package com.funtl.myshop.service.reg;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication(scanBasePackages = "com.funtl.myshop")
@EnableDiscoveryClient
@MapperScan(basePackages = "com.funtl.myshop.commons.mapper")
public class MyShopServiceRegApplication {
public static void main(String[] args) {
SpringApplication.run(MyShopServiceRegApplication.class, args);
}
}
RegController
package com.funtl.myshop.service.reg.controller;
import com.funtl.myshop.commons.domain.TbUser;
import com.funtl.myshop.commons.dto.AbstractBaseResult;
import com.funtl.myshop.commons.service.TbUserService;
import com.funtl.myshop.commons.validator.BeanValidator;
import com.funtl.myshop.commons.web.AbstractBaseController;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(value = "reg")
public class RegController extends AbstractBaseController<TbUser> {
@Autowired
private TbUserService tbUserService;
@PostMapping(value = "")
public AbstractBaseResult reg(TbUser tbUser) {
// 數(shù)據(jù)校驗(yàn)
String message = BeanValidator.validator(tbUser);
if (StringUtils.isNotBlank(message)) {
return error(message, null);
}
// 驗(yàn)證用戶名是否重復(fù)
if (!tbUserService.unique("username", tbUser.getUsername())) {
return error("用戶名重復(fù),請(qǐng)重試", null);
}
// 驗(yàn)證郵箱是否重復(fù)
if (!tbUserService.unique("email", tbUser.getEmail())) {
return error("郵箱重復(fù)敞咧,請(qǐng)重試", null);
}
// 注冊(cè)用戶
tbUser.setPassword(DigestUtils.md5DigestAsHex(tbUser.getPassword().getBytes()));
TbUser user = tbUserService.save(tbUser);
if (user != null) {
response.setStatus(HttpStatus.CREATED.value());
return success(request.getRequestURI(), user);
}
// 注冊(cè)失敗
return error("注冊(cè)失敗棘捣,請(qǐng)重試", null);
}
}