Skip to content

Commit 04ee159

Browse files
authored
Merge pull request #64 from codingbaraGo/feat/database/repo-template#62 (see PR #63)
develop <- feat/database/repo template#62
2 parents 531f1b6 + f1a1895 commit 04ee159

13 files changed

Lines changed: 525 additions & 11 deletions

File tree

build.gradle

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ dependencies {
1616
implementation 'ch.qos.logback:logback-classic:1.2.3'
1717
testImplementation 'org.assertj:assertj-core:3.16.1'
1818

19+
runtimeOnly 'com.h2database:h2:2.2.224'
20+
1921
testImplementation 'org.mockito:mockito-core:4.11.0'
2022
testImplementation('org.mockito:mockito-junit-jupiter:4.11.0') {
2123
exclude group: 'org.junit.jupiter'

src/main/java/app/db/Database.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class Database {
1414

1515
public static void addUser(User user) {
1616
long id = sequentialId.getAndIncrement();
17-
user.setUserId(id);
17+
user.setId(id);
1818
users.put(id, user);
1919
}
2020

src/main/java/app/handler/LoginWithPost.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public HandlerResponse handle(QueryParameters params) {
3838
}
3939

4040
SessionEntity session = sessionManager.create(
41-
user.getUserId(),
41+
user.getId(),
4242
user.getUserRole(),
4343
user.getNickname());
4444

src/main/java/app/handler/RegisterWithGet.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
import web.filter.authentication.UserRole;
1212
import web.handler.SingleArgHandler;
1313
import web.response.HandlerResponse;
14-
import web.response.StaticViewResponse;
14+
import web.response.RedirectResponse;
1515

1616
public class RegisterWithGet extends SingleArgHandler<QueryParameters> {
1717
private static final Logger log = LoggerFactory.getLogger(RegisterWithGet.class);
@@ -28,6 +28,6 @@ public HandlerResponse handle(QueryParameters params) {
2828
String nickname = params.getQueryValue("nickname").orElseThrow(()-> new ServiceException(ErrorCode.MISSING_REGISTER_TOKEN, "nickname required"));
2929
Database.addUser(new User(password, nickname, email, UserRole.MEMBER.toString()));
3030
log.info("Registered - password:{}, nickname:{}, email:{}", password, nickname, email);
31-
return StaticViewResponse.of("/login");
31+
return RedirectResponse.to("/login");
3232
}
3333
}

src/main/java/app/model/User.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package app.model;
22

33
public class User {
4-
private Long userId;
4+
private Long id;
55
private String password;
66
private String nickname;
77
private String email;
@@ -14,12 +14,12 @@ public User(String password, String nickname, String email, String userRole) {
1414
this.userRole = userRole;
1515
}
1616

17-
public Long getUserId() {
18-
return userId;
17+
public Long getId() {
18+
return id;
1919
}
2020

21-
public void setUserId(Long userId){
22-
this.userId = userId;
21+
public void setId(Long id){
22+
this.id = id;
2323
}
2424

2525
public String getPassword() {
@@ -40,6 +40,6 @@ public String getUserRole() {
4040

4141
@Override
4242
public String toString() {
43-
return "User [userId=" + userId + ", password=" + password + ", name=" + nickname + ", email=" + email + "]";
43+
return "User [userId=" + id + ", password=" + password + ", name=" + nickname + ", email=" + email + "]";
4444
}
4545
}

src/main/java/bootstrap/WebServer.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.concurrent.Executors;
77

88
import config.AppConfig;
9+
import config.DatabaseConfig;
910
import config.FilterConfig;
1011
import config.SecurityConfig;
1112
import org.slf4j.Logger;
@@ -18,6 +19,7 @@ public class WebServer {
1819
private static final AppConfig LOADER = new AppConfig();
1920
private static final SecurityConfig securityConfig = new SecurityConfig();
2021
private static final FilterConfig filterConfig = new FilterConfig();
22+
private static final DatabaseConfig databaseConfig = new DatabaseConfig();
2123
private static final ExecutorService executor = Executors.newFixedThreadPool(32);
2224

2325
public static void main(String args[]) throws Exception {
@@ -53,5 +55,6 @@ public static void main(String args[]) throws Exception {
5355
private static void config(){
5456
securityConfig.config();
5557
filterConfig.config();
58+
databaseConfig.config();
5659
}
5760
}

src/main/java/config/AppConfig.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package config;
22

33
import app.handler.*;
4+
import database.ConnectionManager;
5+
import database.H2DbManager;
46
import exception.ExceptionHandlerMapping;
57
import exception.handler.ErrorExceptionHandler;
68
import exception.handler.ServiceExceptionHandler;
@@ -96,6 +98,7 @@ public List<WebHandler> webHandlerList() {
9698
);
9799
}
98100

101+
// ===== Handler =====
99102
public StaticContentHandler staticContentHandler() {
100103
return getOrCreate(
101104
"staticContentHandler",
@@ -309,4 +312,21 @@ public SessionStorage sessionStorage() {
309312
return getOrCreate("sessionStorage",
310313
SessionStorage::new);
311314
}
315+
316+
/**
317+
* ===== DB =====
318+
*/
319+
public ConnectionManager connectionManager(){
320+
return h2DbManager();
321+
}
322+
323+
public H2DbManager h2DbManager(){
324+
return getOrCreate(H2DbManager.class.getSimpleName(), H2DbManager::new);
325+
}
326+
327+
public DdlGenerator ddlGenerator(){
328+
return getOrCreate(DdlGenerator.class.getSimpleName(), () ->
329+
new DdlGenerator(connectionManager()));
330+
}
312331
}
332+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package config;
2+
3+
import app.model.User;
4+
import java.util.List;
5+
6+
public class DatabaseConfig {
7+
private final AppConfig appConfig = new AppConfig();
8+
9+
public static final List<Class<?>> ENTITY_CLASSES = List.of(
10+
User.class
11+
);
12+
13+
public static final List<String> RESOLVED_WORD = List.of(
14+
"user"
15+
);
16+
17+
public static final String H2_DB_URL = "jdbc:h2:tcp://localhost//Users/apple/h2/testdb";
18+
public static final String H2_DB_USER = "sa";
19+
public static final String H2_DB_PASSWORD = "";
20+
21+
public static final boolean CREATE_TABLES = false;
22+
public static final boolean DROP_IF_EXISTS = false;
23+
24+
public void config(){
25+
DdlGenerator ddlGenerator = appConfig.ddlGenerator();
26+
if(CREATE_TABLES) ddlGenerator.generateTables();
27+
}
28+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package config;
2+
3+
import database.ConnectionManager;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
7+
import java.lang.reflect.Field;
8+
import java.lang.reflect.Modifier;
9+
import java.sql.Connection;
10+
import java.sql.SQLException;
11+
import java.sql.Statement;
12+
import java.time.LocalDateTime;
13+
import java.util.List;
14+
15+
public class DdlGenerator {
16+
private static final Logger log = LoggerFactory.getLogger(DdlGenerator.class);
17+
private final List<String> resolvedWord = DatabaseConfig.RESOLVED_WORD;
18+
private final ConnectionManager connectionManager;
19+
private final boolean dropIfExists = DatabaseConfig.DROP_IF_EXISTS;
20+
private final List<Class<?>> entityClasses = DatabaseConfig.ENTITY_CLASSES;
21+
22+
public DdlGenerator(ConnectionManager connectionManager) {
23+
this.connectionManager = connectionManager;
24+
}
25+
26+
public void generateTables() {
27+
try (Connection conn = connectionManager.getConnection();
28+
Statement stmt = conn.createStatement()) {
29+
30+
for (Class<?> entityClass : entityClasses) {
31+
String tableName = toTableName(entityClass);
32+
String ddl = buildDdlForEntity(entityClass, tableName);
33+
log.info("DDL for {}:\n{}", tableName, ddl);
34+
stmt.execute(ddl);
35+
}
36+
37+
} catch (SQLException e) {
38+
throw new RuntimeException("DDL 생성/실행 중 오류", e);
39+
}
40+
}
41+
42+
private String buildDdlForEntity(Class<?> entityClass, String tableName) {
43+
StringBuilder ddl = new StringBuilder();
44+
45+
if (dropIfExists) {
46+
ddl.append("DROP TABLE IF EXISTS ").append(tableName).append(";\n");
47+
}
48+
49+
ddl.append("CREATE TABLE ").append(tableName).append(" (\n");
50+
51+
Field[] fields = entityClass.getDeclaredFields();
52+
53+
boolean firstColumn = true;
54+
55+
for (Field field : fields) {
56+
if (Modifier.isStatic(field.getModifiers())) {
57+
continue;
58+
}
59+
60+
String columnName = field.getName();
61+
Class<?> fieldType = field.getType();
62+
63+
if (!firstColumn) {
64+
ddl.append(",\n");
65+
}
66+
firstColumn = false;
67+
68+
if ("id".equals(columnName) && (fieldType == Long.class || fieldType == long.class)) {
69+
ddl.append(" id BIGINT AUTO_INCREMENT PRIMARY KEY");
70+
} else {
71+
String sqlType = toSqlType(fieldType);
72+
ddl.append(" ").append(columnName).append(" ").append(sqlType);
73+
}
74+
}
75+
76+
ddl.append("\n);");
77+
78+
return ddl.toString();
79+
}
80+
81+
private String toSqlType(Class<?> fieldType) {
82+
if (fieldType == Long.class || fieldType == long.class) {
83+
return "BIGINT";
84+
} else if (fieldType == Integer.class || fieldType == int.class) {
85+
return "INT";
86+
} else if (fieldType == String.class) {
87+
return "VARCHAR(255)";
88+
} else if (fieldType == Boolean.class || fieldType == boolean.class) {
89+
return "BOOLEAN";
90+
} else if (fieldType == LocalDateTime.class ||
91+
fieldType == java.util.Date.class ||
92+
fieldType == java.sql.Timestamp.class) {
93+
return "TIMESTAMP";
94+
} else if (fieldType == Double.class || fieldType == double.class) {
95+
return "DOUBLE";
96+
} else if (fieldType == Float.class || fieldType == float.class) {
97+
return "FLOAT";
98+
}
99+
return "VARCHAR(255)";
100+
}
101+
102+
private String toTableName(Class<?> clazz) {
103+
String name = clazz.getSimpleName().toLowerCase();
104+
105+
for(String word : resolvedWord){
106+
if(word.equals(name))
107+
return "`" + word + "`";
108+
}
109+
return name;
110+
}
111+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package database;
2+
3+
import java.sql.Connection;
4+
5+
public interface ConnectionManager {
6+
Connection getConnection();
7+
}

0 commit comments

Comments
 (0)