Skip to content

Instantly share code, notes, and snippets.

@sbcoba
Last active January 5, 2016 15:00
Show Gist options
  • Save sbcoba/90c6c74616f89be2acd1 to your computer and use it in GitHub Desktop.
Save sbcoba/90c6c74616f89be2acd1 to your computer and use it in GitHub Desktop.
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.ImprovedNamingStrategy;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.H2Dialect;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import javax.persistence.Entity;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Properties;
/**
* JPA Entity 클래스를 가지고 DDL 쿼리를 생성할 수 있는 클래스
*
* @author sbcoba
*/
public class JpaEntityDdlExport {
/**
* 생성될 파일명
*/
private static final String SCHEMA_SQL = "schema_%s.sql";
/**
* 도메인 클래스 경로 위치 ( 범위가 넓어도 @Entity 를 가지는 class만 찾음 )
*/
private final static String PATTERN = "classpath*:com/sbcoba/test/domain/*.class";
/**
* DDL 생성할 DB타입
* org.hibernate.dialect.* 패키지 참조*
*
* - 오라클 Oracle10gDialect.class
* - H2 H2Dialect.class
* ...
*
*/
private final static Class<? extends Dialect> DIALECT_CLASS = H2Dialect.class;
public static void main(String[] args) {
Configuration configuration = new Configuration();
String pattern = getPattern(args);
List<Class<?>> classes = getClassesByAnnotation(Entity.class, pattern);
for (Class<?> clazz : classes) {
configuration.addAnnotatedClass(clazz);
}
Properties properties = hibernateProperties(args);
configuration.setProperties(properties);
configuration.setNamingStrategy(new ImprovedNamingStrategy());
String outputFile = getOutputFilename(args);
SchemaExport schema = new SchemaExport(configuration);
schema.setOutputFile(outputFile);
schema.create(true, false);
appendSemicolon(outputFile);
}
private static String getPattern(String[] args) {
String pattern = PATTERN;
if(args != null && args.length >= 3
&& StringUtils.hasText(args[2])) {
pattern = args[2];
}
return pattern;
}
/**
* 쿼리의 끝 부분에 세미콜론(;) 추가
* @param outputFile
*/
private static void appendSemicolon(String outputFile) {
String charsetName = "UTF-8";
File ddlFile = new File(outputFile);
try {
String ddlFileContents = StreamUtils.copyToString(new FileInputStream(ddlFile), Charset.forName(charsetName));
ddlFileContents = ddlFileContents.replaceAll("\n\n", ";\n\n");
ddlFileContents = ddlFileContents.replaceAll("\n.*(?![\f\n\r])$", ";\n");
FileCopyUtils.copy(ddlFileContents.getBytes(charsetName), ddlFile);
} catch (IOException e) {
e.printStackTrace();
}
}
private static List<Class<?>> getClassesByAnnotation(Class<? extends Annotation> annotation, String pattern) {
List<Class<?>> classes = new ArrayList<>();
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource[] resources;
try {
resources = resolver.getResources(pattern);
} catch (IOException e) {
System.err.printf(e.getMessage());
return classes;
}
for (Resource r : resources) {
MetadataReader mr;
try {
mr = new SimpleMetadataReaderFactory().getMetadataReader(r);
} catch (IOException e) {
System.err.printf(e.getMessage());
continue;
}
if (mr.getAnnotationMetadata().hasAnnotation(annotation.getName())) {
String className = mr.getClassMetadata().getClassName();
Class<?> clazz;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
System.err.printf("%s Class not found", className);
continue;
}
classes.add(clazz);
}
}
return classes;
}
private static String getOutputFilename(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
if(args != null && args.length > 0
&& StringUtils.hasText(args[0])) {
String customSchemaName = args[0];
if(customSchemaName.contains("%s")) {
return String.format(customSchemaName, sdf.format(Calendar.getInstance().getTime()));
}
return customSchemaName;
}
return String.format(SCHEMA_SQL, sdf.format(Calendar.getInstance().getTime()));
}
private static Properties hibernateProperties(String[] args) {
String dialectClass = null;
if(args != null && args.length >= 2
&& StringUtils.hasText(args[1])) {
dialectClass = args[1];
try {
Class.forName(dialectClass);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
if (dialectClass == null) {
dialectClass = DIALECT_CLASS.getName();
}
Properties properties = new Properties();
properties.put(org.hibernate.cfg.Environment.DIALECT, dialectClass);
return properties;
}
}
@sbcoba
Copy link
Author

sbcoba commented Jan 5, 2016

Maven setting

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>exec-maven-plugin</artifactId>
            <version>1.2.1</version>
            <executions>
                <execution>
                    <id>default-cli</id>
                    <goals>
                        <goal>java</goal>
                    </goals>
                    <configuration>
                      <mainClass>org.sbcoba.test.JpaEntityDdlExport</mainClass>
                    </configuration>
                </execution>
            </executions>
        </plugin>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment