diff --git a/src/main/java/domain/Person.java b/src/main/java/domain/Person.java new file mode 100644 index 000000000..0703d4703 --- /dev/null +++ b/src/main/java/domain/Person.java @@ -0,0 +1,30 @@ +package domain; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; + +@Table(name = "users") +@Entity +public class Person { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "nick_name") + private String name; + + @Column(name = "old") + private Integer age; + + @Column(nullable = false) + private String email; + + @Transient + private Integer index; +} diff --git a/src/main/java/persistence/Application.java b/src/main/java/persistence/Application.java index 8809704f5..c2b0ac2be 100644 --- a/src/main/java/persistence/Application.java +++ b/src/main/java/persistence/Application.java @@ -1,8 +1,18 @@ package persistence; +import java.io.Serializable; +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + import database.DatabaseServer; import database.H2; +import domain.Person; import jdbc.JdbcTemplate; +import persistence.sql.ddl.CreateQueryBuilder; +import persistence.sql.ddl.DropQueryBuilder; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,6 +27,9 @@ public static void main(String[] args) { final JdbcTemplate jdbcTemplate = new JdbcTemplate(server.getConnection()); + jdbcTemplate.execute(new CreateQueryBuilder().getCreateTableSql()); + jdbcTemplate.execute(new DropQueryBuilder().getDropTableSql()); + server.stop(); } catch (Exception e) { logger.error("Error occurred", e); diff --git a/src/main/java/persistence/sql/ddl/CreateQueryBuilder.java b/src/main/java/persistence/sql/ddl/CreateQueryBuilder.java new file mode 100644 index 000000000..6e579682f --- /dev/null +++ b/src/main/java/persistence/sql/ddl/CreateQueryBuilder.java @@ -0,0 +1,135 @@ +package persistence.sql.ddl; + +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.lang.reflect.Field; + +import domain.Person; +import jakarta.persistence.Column; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.Table; +import jakarta.persistence.Transient; + +public class CreateQueryBuilder { + Map, String> javaClassTypeToDbTypes = Map.of( + Long.class, "BIGINT", + String.class, "VARCHAR", + Integer.class, "BIGINT" + ); + + public String getCreateTableSql() throws + NoSuchMethodException, + InvocationTargetException, + InstantiationException, + IllegalAccessException { + + Class personClass = Person.class; + + Person person = personClass.getConstructor().newInstance(); + + // 목표 출력의 목표를 스트링으로 적는다 + /* + CREATE TABLE person ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(50), + age INT, + email VARCHAR(50) NOT NULL, + index INT + ); + */ + // 메서드 분리 (3) + Field idField = Arrays.stream(getDeclaredFields(personClass)) + .filter(x -> x.isAnnotationPresent(GeneratedValue.class)) + .findFirst().get(); + + String idFieldName = idField.getName(); + + String idType = javaClassTypeToDbTypes.get(idField.getType()); + + String generatedValue = generateValue(); + + String primaryKey = getPrimaryKey(); + + String idCombi = String.format("%s %s %s %s,", idFieldName, idType, generatedValue, primaryKey); + + // name VARCHAR(50), + Field nameField = Arrays.stream(getDeclaredFields(personClass)) + .filter(x -> x.isAnnotationPresent(Column.class)).findFirst().get(); + + String name = nameField.getName(); + + String nameType = javaClassTypeToDbTypes.get(nameField.getType()); + + String nameCombi = String.format("%s %s,", name, nameType); + + // age INT, + Field ageField = Arrays.stream(getDeclaredFields(personClass)) + .filter(x -> x.isAnnotationPresent(Column.class)) + .filter(x -> x.getAnnotation(Column.class).name().equals("old")) + .findFirst().get(); + String age = ageField.getName(); + String ageType = javaClassTypeToDbTypes.get(ageField.getType()); + + String ageCombi = String.format("%s %s,", age, ageType); + + // email VARCHAR(50) NOT NULL, + Field emailField = Arrays.stream(getDeclaredFields(personClass)) + .filter(x -> x.isAnnotationPresent(Column.class)) + .filter(x -> !x.getAnnotation(Column.class).nullable()) + .findFirst().get(); + String email = emailField.getName(); + String emailType = javaClassTypeToDbTypes.get(emailField.getType()); + boolean isNullable = emailField.getAnnotation(Column.class).nullable(); + + String emialNullable = isNull(isNullable); + + String emailCombi = String.format("%s %s %s", email, emailType, emialNullable); + + // index INT + Field indexField = Arrays.stream(getDeclaredFields(personClass)) + .filter(x -> x.isAnnotationPresent(Transient.class)) + .findFirst().get(); + String indexCombi = ""; + + String tableName = personClass.getSimpleName(); + + // List> fieldTypes = Arrays.stream(getDeclaredFields(personClass)).map(Field::getType).toList(); + // + // List fieldNames = Arrays.stream(getDeclaredFields(personClass)).map(Field::getName).toList(); + + String createTableSql = String.format("create table %s(%s %s %s %s %s)", + tableName, + idCombi, + nameCombi, + ageCombi, + emailCombi, + indexCombi + ); + + return createTableSql; + } + + private String getPrimaryKey() { + + return "PRIMARY KEY"; + } + + private static Field[] getDeclaredFields(Class personClass) { + return personClass.getDeclaredFields(); + } + + // DB에서 가져와야겠다 ai를 // + private static String generateValue() { + return "AUTO_INCREMENT"; + } + + private static String isNull(boolean isNullable) { + if (!isNullable) { + return "NOT NULL"; + } + return ""; + } +} diff --git a/src/main/java/persistence/sql/ddl/DropQueryBuilder.java b/src/main/java/persistence/sql/ddl/DropQueryBuilder.java new file mode 100644 index 000000000..a116a13a1 --- /dev/null +++ b/src/main/java/persistence/sql/ddl/DropQueryBuilder.java @@ -0,0 +1,17 @@ +package persistence.sql.ddl; + +import domain.Person; + +public class DropQueryBuilder { + public String getDropTableSql() { + Class personClass = Person.class; + + String tableName = personClass.getSimpleName(); + // DROP TABLE Person + String dropTableSql = String.format("drop table %s", tableName); + + return dropTableSql; + } + + +} diff --git a/src/test/java/persistence/sql/ddl/CreateQueryBuilderTest.java b/src/test/java/persistence/sql/ddl/CreateQueryBuilderTest.java new file mode 100644 index 000000000..92e05e946 --- /dev/null +++ b/src/test/java/persistence/sql/ddl/CreateQueryBuilderTest.java @@ -0,0 +1,21 @@ +package persistence.sql.ddl; + +import static org.junit.jupiter.api.Assertions.*; + +import java.lang.reflect.InvocationTargetException; + +import org.junit.jupiter.api.Test; + +class CreateQueryBuilderTest { + @Test + void createDDL() throws + InvocationTargetException, + NoSuchMethodException, + InstantiationException, + IllegalAccessException { + CreateQueryBuilder createQueryBuilder = new CreateQueryBuilder(); + String createTableSql = createQueryBuilder.getCreateTableSql(); + + assertEquals(createTableSql, "CREATE TABLE person (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, age INT)"); + } +} diff --git a/src/test/java/persistence/study/ReflectionTest.java b/src/test/java/persistence/study/ReflectionTest.java index 91acebd4d..f48526b17 100644 --- a/src/test/java/persistence/study/ReflectionTest.java +++ b/src/test/java/persistence/study/ReflectionTest.java @@ -11,7 +11,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; public class ReflectionTest { private static final Logger logger = LoggerFactory.getLogger(ReflectionTest.class); @@ -23,21 +23,21 @@ void showCarClass() { logger.debug(carClass.getName()); Field[] fields = carClass.getDeclaredFields(); - System.out.println("필드:"); + logger.debug("필드:"); for (Field field : fields) { - System.out.println(field); + logger.debug(String.valueOf(field)); } Constructor[] constructors = carClass.getDeclaredConstructors(); - System.out.println("생성자:"); + logger.debug("생성자:"); for (Constructor constructor : constructors) { - System.out.println(constructor); + logger.debug(String.valueOf(constructor)); } Method[] methods = carClass.getDeclaredMethods(); - System.out.println("메서드"); + logger.debug("메서드:"); for (Method method : methods) { - System.out.println(method); + logger.debug(String.valueOf(method)); } } @@ -46,7 +46,7 @@ void showCarClass() { Class carClass = Car.class; Car car = carClass.getConstructor().newInstance(); Arrays.stream(carClass.getDeclaredMethods()) - .filter(x -> x.getName().contains("test")) + .filter(x -> x.getName().startsWith("test")) .forEach(x -> { try { x.invoke(car); @@ -88,8 +88,12 @@ void showCarClass() { priceField.setAccessible(true); priceField.set(car, price); - assertThat(car.testGetName()).isEqualTo("test : " + name); - assertThat(car.testGetPrice()).isEqualTo("test : " + price); + assertAll( + () -> { + assertEquals(car.testGetName(), "test : " + name); + assertEquals(car.testGetPrice(), "test : " + price); + } + ); } @Test @@ -103,7 +107,11 @@ void showCarClass() { .findFirst().orElseThrow(); Car car = (Car) constructor.newInstance(name, price); - assertThat(car.testGetName()).isEqualTo("test : " + name); - assertThat(car.testGetPrice()).isEqualTo("test : " + price); + assertAll( + () -> { + assertEquals(car.testGetName(), "test : " + name); + assertEquals(car.testGetPrice(), "test : " + price); + } + ); } }