今天就直接來設定一下MongoDB以及Spring專案的架構,昨天有提到MongoDB是使用Docker運行的container,
運行指令為
docker run -p 27017:27017 --name native-camp -d mongo
因為是本機端使用就沒設定密碼,這是不好的示範。
然後可以使用Mongo Compass來管理資料庫,我自己使用MongoDB管理工具主要有Compass和Robo 3T,我自己會看要做什麼操作而切換使用的管理工具。
根據Day2分析的架構所設定collections
先把專案會用到的資料夾給新增好,以及新增mode、repository和aspect
application.yml 目前只有連接mongoDB設定
spring:
data:
mongodb:
uri: mongodb://localhost:27017/native_camp
然後mode 我自己是習慣使用lombok,真的好用便利,很推薦喔!
這邊先展示Users,但還有些欄位需要新增
package com.mock.nativecamp.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "Users")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Users {
private String id;
private String name;
private String email;
private String status;
private String coin;
private String timezone;
private String payMethod;
private String nextPayCheck;
}
然後repository的話也是對應mode事先新增完畢,我這邊做的是log request和response。
這邊展示UsersRepository
package com.mock.nativecamp.repository;
import com.mock.nativecamp.model.Users;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UsersRepository extends MongoRepository<Users, String> {
}
再來是AOP的設定,我覺得AOP在做request和response時很便利
LogAspect
package com.mock.nativecamp.aspect;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Component
@Aspect
@Slf4j
public class LogAspect {
// this is log API receive request and return response log
@Pointcut("execution(* com.mock.nativecamp.controller.*.*(..))")
public void log() {
}
@Before("log()")
public void deBefore(JoinPoint joinPoint) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String classMethod = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
RequestLog requestLog = new RequestLog(
request.getRequestURL().toString(),
request.getRemoteAddr(),
classMethod,
joinPoint.getArgs()
);
log.info("request: {}", requestLog.toString());
}
@AfterReturning(returning = "result", pointcut = "log()")
public void doAfterReturning(Object result) {
log.info("response: {}", result);
}
@Data
private class RequestLog {
private String url;
private String ip;
private String classMethod;
private Object[] args;
public RequestLog(String url, String ip, String classMethod, Object[] args) {
this.url = url;
this.ip = ip;
this.classMethod = classMethod;
this.args = args;
}
}
}
下一篇會把各model的設計給完善。