<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd"> <!-- saved from url=(0061)http://www.informit.com/articles/printerfriendly.asp?p=353737 --> <HTML xmlns="http://www.w3.org/1999/xhtml"><HEAD><TITLE>Articles</TITLE> <META http-equiv=Content-Type content="text/html; charset=utf-8"> <SCRIPT language=JavaScript src="J2EE_Schema_Management_with_Hibernate.files/global.js" type=text/JavaScript></SCRIPT> <LINK href="J2EE_Schema_Management_with_Hibernate.files/print.css" type=text/css rel=stylesheet> <META content="MSHTML 6.00.2800.1479" name=GENERATOR></HEAD> <BODY> 번역 : 이동국

원문 : http://www.informit.com/articles/printerfriendly.asp?p=353737<br><br> <DIV id=contentPrint> <DIV id=biblio xmlns="">Date: Jan 14, 2005 By <A href="http://www.informit.com/authors/bio.asp?a=39f2b184-10f2-4f74-aff8-60b5329241d1">Will Iverson</A>. Sample Chapter is provided courtesy of <A href="http://www.awprofessional.com/">Addison Wesley Professional</A>. </DIV><br> <DIV id=article xmlns=""> <DIV id=intro>Hibernate의 가장 유용한 기능중에 하나가 스키마 조작 명령어의 자동생성이다. 여기서는 이 기능을 가장 효과적으로 사용할수 있도록 하는 방법에 대해서 대략적인 모습을 제시한다.. </DIV> <DIV id=text> <P>Hibernate의 가장 유용한 기능중 하나는 스키마 조작 명령어의 자동생성이다. 이 기능은 때때로 대상 데이터베이스내의 테이블을 생성하거나 수정하거나 삭제를 가능토록 하는 DDL스크립트(주어진 유요한 <TT>*.hbm.xml</TT>파일)를 생성하기 위한 능력처럼 비유되기도 한다. 당신은 실행중이나 개발중 또는 시스템 관리자에 의해 추후에 사용되기 위해 생성된 스크립트를 통해 이것을 할수 있는가.? 만약에 당신이 (개발중이거나 배치중에)다중 대상 데이터베이스를 지원하길 기대하거나 데이터베이스 스키마변경의 높은 등급(degree)를 가지길 원한다면 가치없는 능력이다..</P> <P>Hibernate는 <B>update</B>와 <B>export</B>의 두가지 기본적인 DDL생성 형태를 지원한다. Update는 새로운 애플리케이션에 의해 필요한 잃어버린 스키마 컴포넌트의 스키마의 일부분을 이미 포함하고 있는 특정 데이터베이스를 대상으로 하는 애클리케이션 내에서 주로 사용이 된다. Export는 스크래치(scratch)로 부터 스키마를 생성하는데 사용이 된다. 만약에 애플리케이션이 직접적인 DDL을 수행하는것을 허락하지 않는다면 이것은 매우 유용하다.(왜냐하면 이 작업을 수행하도록 데이터베이스 관리자에게 말을 해야 하기 때문이다).</P> <H2>존재하는 스키마 수정하기.</H2> <P><TT>net.sf.hibernate.tool.hbm2ddl.SchemaUpdate</TT>는 애플리케이션이 <TT>*.hbm.xml</TT>파일셋에 기초해서 스키마와 함께 스키마를 수정할수 있도록 허락한다. 전형적으로 이것은 새로운 설정값(property)처럼 애플리케이션이 관련된 작은 변경사항을 요구하기 위해 지속적인 수정에서의 위치를 할당한다..</P> <P>예를 들면 유저객체(그리고 관련된 유저테이블)를 가지는 애플리케이션이다. 당신은 유저의 국가코드를 가지고 가지 위한 유저객체에 설정값(property)을 더하도록 결정해야 할것이다. 당신은 당신의 <TT>*.hbm.xml</TT>파일과 관련된 자바코드를 변경한다. 배치된 데이터베이스에 변경을 반영할것이다. 이것은 명령라인으로 부터나 Ant작업또는 당신 애플리케이션내의 내장된 것으로도 수행이 가능하다. </P> <P><TT>SchemaUpdate</TT>는 존재하는 스키마를 이해하기 위해서 데이터베이스 드라이버에 의해서 반환되는 메타데이터를 크게 신뢰한다. 이런 이유로, 적당히 제어하는 <TT>SchemaUpdate</TT>의 능력은 드라이버로부터 드라이버까지(그리고 소스데이터베이스부터 대상데이터베이스까지) 변경할수 있다. 만약에 당신이 당신의 데이터베이스와 함께 <TT>SchemaUpdate</TT>를 사용할수 없다면 당신은 대신에 <TT>SchemaExport</TT>툴을 사용할것이다..</P> <H3>애플리케이션내에서 스키마 수정하기</H3> <P>리스트 11.1은 애플리케이션내에 내장된 <TT>SchemaUpdate</TT>의 예제를 보여준다. <TT>Configuration</TT>객체는 필요하지만 <TT>Session</TT>은 아니라는것은 숙지하라. (분명하게 당신은 데이터베이스를 가지고 작업을 수행하기 전에 스키마 수정작업을 수행해야 한다.).</P> <H4><B>리스트 11.1</B> <TT>SchemaUpdate</TT> 예제</H4> <PRE>package com.cascadetg.ch11;

/** Various Hibernate-related imports */ import net.sf.hibernate.*; import net.sf.hibernate.cfg.*; import net.sf.hibernate.tool.hbm2ddl.SchemaUpdate;

public class SchemaUpdaterExample {

/** We use this session factory to create our sessions */ public static SessionFactory sessionFactory;

public static void main(String args) { initialization(); }

/** * Loads the Hibernate configuration information, sets up * the database and the Hibernate session factory. */ public static void initialization() { System.out.println("initialization"); Try { Configuration myConfiguration = new Configuration();

myConfiguration.addClass(com.cascadetg.ch03.Owner.class); myConfiguration.addClass(com.cascadetg.ch03.Artifact.class);

// Load the *.hbm.xml files as set in the // config, and set the dialect. new SchemaUpdate(myConfiguration).execute(true, true);

} catch (Exception e) { e.printStackTrace(); } }</PRE> <H3>명령어라인으로 스키마 수정</H3> <P>명령어 라인으로 부터 <TT>SchemaUpdate</TT>를 사용하기 위해서, 당신은 <TT>java net.sf.hibernate.tool.hbm2ddl.SchemaUpdate</TT>명령어를 사용해야만 한다. 테이블 11.1에서 보여지는 <TT>*.hbm.xml</TT>파일로 경로에 의한 명령어 라인 옵션을 하나 이상 넘겨주어야 한다..</P> <H4>테이블 11.1 SchemaUpdate 명령어 라인 옵션</H4> <TABLE cellSpacing=2 cellPadding=2 border=2> <TBODY> <TR vAlign=top> <TD vAlign=top width=241> <P><TT>--quiet</TT></P></TD> <TD vAlign=top width=328> <P><FONT size=-1>콘솔로 스크립트를 남긴다.(?) </FONT></P></TD></TR> <TR vAlign=top> <TD vAlign=top width=241> <P><TT>--properties= filename.properties</TT></P></TD> <TD vAlign=top width=328> <P><TT>hibernate.properties</TT><FONT size=-1> 파일을 지정한다.</FONT></P></TD></TR> <TR vAlign=top> <TD vAlign=top width=241> <P><TT>--config= filename.cfg.xml</TT></P></TD> <TD vAlign=top width=328> <P><TT>hibernate.cfg.xml</TT><FONT size=-1> 파일을 지정한다.</FONT></P></TD></TR> <TR vAlign=top> <TD vAlign=top width=241> <P><TT>--text</TT></P></TD> <TD vAlign=top width=328> <P><FONT size=-1>업데이트를 수행하지 않는다.</FONT></P></TD></TR> <TR vAlign=top> <TD vAlign=top width=241> <P><TT>--naming=fully.qualified.<BR>class.name</TT></P></TD> <TD vAlign=top width=328> <P><TT>net.sf.hibernate.cfg.Default NamingStrategy</TT><FONT size=-1> 와 </FONT><TT>net.sf.hibernate.cfg.<BR>ImprovedNamingStrategy</TT><FONT size=-1> 를 사용해서 네이밍정책을 지정한다..</FONT></P></TD></TR></TBODY></TABLE><BR> <H3>Ant를 사용해서 스키마 수정</H3> <P>실행시와 명령어 라인 옵션에 추가적으로 당신은 리스트 11.2에서 보여지는 것처럼 ant를 사용할수 있다. </P> <H4><B>리스트 11.2</B> SchemaUpdate ant작업</H4> <PRE><target name="schemaupdate"> <taskdef name="schemaupdate" classname="net.sf.hibernate.tool.hbm2ddl .SchemaUpdateTask" classpathref="class.path"/> <schemaupdate properties="hibernate.properties" quiet="no"> <fileset dir="src"> <include name="**/*.hbm.xml"/> </fileset> </schemaupdate></PRE> <H2>수정및 삭제 스크립트 생성하기 </H2> <P>Hibernate는 스키마를 생성하기 위한 스크립트를 생성하도록 하는(부분적으로 <TT>DROP</TT>구문도 잘 작동하는) <TT>net.sf.hibernate.tool.hbm2ddl.SchemaExport</TT>툴을 포함하고 있다. <TT>SchemaExport</TT>툴은 <TT>SchemaUpdate</TT>이상의 여러가지 장점을 가지고 있다.:</P> <UL> <LI> <P>이것은 대상 데이터베이스에 연결할수 없다 하더라도 개발시간에 실행가능하다. </P> <LI> <P>이것은 드라이버 메타데이터에 의존하지 않는다.</P> <LI> <P>당신의 애플리케이션의 데이터베이스 연결이 DDL수행을 허락하지 않는다면 필요할것이다. </P> <LI> <P>이것은 데이터베이스 관리자에게 애플리케이션의 데이터베이스 요구사항을 보내는것을 허락한다..</P></LI></UL> <P><TT> SchemaUpdate, SchemaExport </TT>처럼 명령어 라인이나 ant에서 실행가능하다. 다양한 데이터베이스를 위해 일제히 스크립트를 생성하기 위해서 <TT>SchemaExport </TT>사용법을 예제에서 보여준다.</P> <H3>명령어 라인 스크립트 생성</H3> <P>당신은 <TT>java net.sf.hibernate.tool.hbm2ddl.SchemaExport options mapping_files</TT>명령어를 사용해서 명령어 라인으로 부터 <TT>SchemaExport</TT>를 실행할수 있다. 가능한 옵션을 테이블 11.2에서 보여준다.</P> <H4>테이블 11.2. SchemaExport 명령어 라인 옵션</H4> <TABLE cellSpacing=2 cellPadding=2 border=2> <TBODY> <TR vAlign=top> <TD vAlign=top width=247> <P><B>Option</B></P></TD> <TD vAlign=top width=267> <P><B>Description</B></P></TD></TR> <TR vAlign=top> <TD vAlign=top width=247> <P><TT>--quiet</TT></P></TD> <TD vAlign=top width=267> <P>콘솔로 스크립트 결과를 출력하지 않는다.</P></TD></TR> <TR vAlign=top> <TD vAlign=top width=247> <P><TT>--drop</TT></P></TD> <TD vAlign=top width=267> <P>테이블 삭제 구분만 생성한다.</P></TD></TR> <TR vAlign=top> <TD vAlign=top width=247> <P><TT>--text</TT></P></TD> <TD vAlign=top width=267> <P>스크립트는 생성하지만 데이터베이스에 대해서는 수행하지 않는다.</P></TD></TR> <TR vAlign=top> <TD vAlign=top width=247> <P><TT>--output=my_schema.sql</TT></P></TD> <TD vAlign=top width=267> <P>스크립트의 이름을 지정한다.</P></TD></TR> <TR vAlign=top> <TD vAlign=top width=247> <P><TT>--config=hibernate.cfg.xml</TT></P></TD> <TD vAlign=top width=267> <P>Hibernate설정 XML파일을 지정한다.</P></TD></TR> <TR vAlign=top> <TD vAlign=top width=247> <P><TT>--properties=hibernate.properties</TT></P></TD> <TD vAlign=top width=267> <P>파일로 부터 Hibernate설정값을 지정한다.</P></TD></TR> <TR vAlign=top> <TD vAlign=top width=247> <P><TT>--format</TT></P></TD> <TD vAlign=top width=267> <P>스크립트내의 생성되는 SQL문의 형태를 지정한다.</P></TD></TR> <TR vAlign=top> <TD vAlign=top width=247> <P><TT>--delimiter=;</TT></P></TD> <TD vAlign=top width=267> <P>스크립트를 위한 라인구분자를 지정한다.</P></TD></TR></TBODY></TABLE><BR> <H3>ant스크립트 생성</H3> <P>리스트 11.3은 스크립트를 생성하기 위해 사용되는 ant작업을 보여준다. 이 옵션들의 의미는 테이블 11.2에서 볼수 있다.</P> <H4><B>리스트 11.3</B> SchemaExport ant작업</H4> <PRE><target name="schemaexport"> <taskdef name="schemaexport" classname="net.sf.hibernate.tool.hbm2ddl.SchemaExportTask" classpathref="class.path"/> <schemaexport properties="hibernate.properties" quiet="no" text="no" drop="no" delimiter=";" output="schema-export.sql"> <fileset dir="src"> <include name="**/*.hbm.xml"/> </fileset> </schemaexport></PRE> <H3>여러개의 스크립트 생성하기.</H3> <P>Hibernate는 데이터베이스를 넓은 범위에서 지원하기 위해 많은 장점의 기능을 가진다. SchemaExport의 장점을 이용함으로써 당신은 개발시에 많은 종류의 데이터베이스를 위한 스키마 생성 스크립트를 생성할수 있고 그것을 애플리케이션 배포판에 포함시킬수 있다. 이것은 테스트를 위한 대용품이 아니다. Hibernate는 많은 종류의 기능을 지원하기 위해 데이터베이스에 의존한다. 하지만 당신이 만약에 새로운 데이터베이스와 함께 애플리케이션을 사용하고자 하는데 관심이 있다면 이것은 유용할 것이다. </P> <P>테이블 6.5는 Hibernate2.1.2에 포함된 dialects의 리스트를 보여준다. 리스트 11.4에서 보여지는 샘플 코드는 많은 데이터베이스를 위한 스키마 생성 스크립트의 셋(set)을 생성하기 위한 리스트의 장점을 가져다준다. dialects의 묶음은 3장에서 보여지는 샘플 애플리케이션을 위한 스크립트를 생성하기 위해 시도하면서 계속 반복된다. </P> <H4><B>리스트 11.4 </B>여러개의 스크립트 생성하기.</H4> <PRE>package com.cascadetg.ch11;

/** Various Hibernate-related imports */ import net.sf.hibernate.*; import net.sf.hibernate.cfg.*; import net.sf.hibernate.tool.hbm2ddl.SchemaExport; import java.util.Properties;

public class SchemaGeneratorExample { // System constants for the current platform directory token static String fileSep = System.getProperty("file.separator");

/** We use this session factory to create our sessions */ public static SessionFactory sessionFactory;

static String db_dialects = { "DB2", // "net.sf.hibernate.dialect.DB2Dialect", // "DB2400", // "net.sf.hibernate.dialect.DB2400Dialect", // "Firebird", // "net.sf.hibernate.dialect.FirebirdDialect", // "FrontBase", // "net.sf.hibernate.dialect.FrontBaseDialect", // "Generic", // "net.sf.hibernate.dialect.GenericDialect", // "HypersonicSQL", // "net.sf.hibernate.dialect.HSQLDialect", // "Informix", // "net.sf.hibernate.dialect.InformixDialect", // "Informix9", // "net.sf.hibernate.dialect.Informix9Dialect", // "Ingres", // "net.sf.hibernate.dialect.IngresDialect", // "Interbase", // "net.sf.hibernate.dialect.InterbaseDialect", // "Mckoi SQL", // "net.sf.hibernate.dialect.MckoiDialect", // "Microsoft SQL Server", // "net.sf.hibernate.dialect.SQLServerDialect", // "MySQL", // "net.sf.hibernate.dialect.MySQLDialect", // "Oracle 9", // "net.sf.hibernate.dialect.Oracle9Dialect", // "Oracle", // "net.sf.hibernate.dialect.OracleDialect", // "Pointbase", // "net.sf.hibernate.dialect.PointbaseDialect", // "PostgreSQL", // "net.sf.hibernate.dialect.PostgreSQLDialect", // "Progress", // "net.sf.hibernate.dialect.ProgressDialect", // "SAP DB", // "net.sf.hibernate.dialect.SAPDBDialect", // "Sybase Anywhere", // "net.sf.hibernate.dialect.SybaseAnywhereDialect", "Sybase 11.9.2", // "net.sf.hibernate.dialect.Sybase11_9_2Dialect", // "Sybase", // "net.sf.hibernate.dialect.SybaseDialect",};

public static void main(String args) { initialization(); }

/** * Loads the Hibernate configuration information, sets up the * database and the Hibernate session factory. */ public static void initialization() { System.out.println("initialization"); try { Configuration myConfiguration = new Configuration();

myConfiguration.addClass(com.cascadetg.ch03.Owner.class); myConfiguration.addClass(com.cascadetg.ch03.Artifact.class);

Properties myProperties = new Properties();

for (int i = 0; i < db_dialects.length; i = i + 2) { String dialect_name = db_dialectsi; String dialect_class = db_dialectsi + 1;

String dialect_file = dialect_name.toLowerCase(); dialect_file = dialect_file.replace(' ', '_'); dialect_file += (".sql");

String path = "com" + fileSep + "cascadetg" + fileSep + "ch11" + fileSep;

System.out.println("Generating " + dialect_name);

// Note that this is the only Hibernate property // set. In particular, there is no JDBC // connectivity data, nor are we specifying a // driver! myProperties.put("hibernate.dialect", dialect_class); try { // Load the *.hbm.xml files as set in the // config, and set the dialect. SchemaExport mySchemaExport = new SchemaExport(myConfiguration, myProperties);

mySchemaExport.setDelimiter(";");

// Despite the name, the generated create // scripts WILL include drop statements at // the top of the script! mySchemaExport.setOutputFile(path + "create_" + dialect_file); mySchemaExport.create(false, false) ;

// Generates DROP statements only mySchemaExport.setOutputFile(path + "drop_" + dialect_file); mySchemaExport.drop(false, false);

System.out.println(dialect_name + " OK.");

} catch (Exception e) { System.out.println(e.getMessage()); } }

} catch (Exception e) { e.printStackTrace(); } }</PRE> <P>리스트 11.4의 애플리케이션의 실행은 리스트 11.5에서 보여지는 결과를 만든다. 볼수 있는것처럼 <TT>native</TT>생성자는 많은 데이터베이스에 의해 지원되지 않는다. 더 넒게 지원받기 위해서 Hibernate생성자는 너 많은 범위의 데이터베이스를 지원하기 위한 좀더 나은 선택이 될것이다. 그림 11.1 스키마 스크립트 파일의 결과를 보여준다.</P> <P><B>그림 11.1<br> 1.jpg <br>스키마 스크립트 생성하기.</B></P><!--<br clear="all" />--> <H4><B>리스트 11.5</B> 여러개의 스크립트 생성하기.</H4> <PRE>initialization Generating DB2 DB2 OK. Generating DB2400 DB2400 OK. Generating Firebird Dialect does not support identity-key generation Generating FrontBase Dialect does not support identity-key generation Generating Generic Dialect does not support identity-key generation Generating HypersonicSQL HypersonicSQL OK. Generating Informix Informix OK. Generating Informix9 Informix9 OK. Generating Ingres Dialect does not support identity-key generation Generating Interbase Dialect does not support identity-key generation Generating Mckoi SQL Dialect does not support identity-key generation Generating Microsoft SQL Server Microsoft SQL Server OK. Generating MySQL MySQL OK. Generating Oracle 9 Dialect does not support identity-key generation Generating Oracle Dialect does not support identity-key generation Generating Pointbase Dialect does not support identity-key generation Generating PostgreSQL Dialect does not support identity-key generation Generating Progress Dialect does not support identity-key generation Generating SAP DB Dialect does not support identity-key generation Generating Sybase Anywhere Sybase Anywhere OK. Generating Sybase 11.9.2 Sybase 11.9.2 OK. Generating Sybase</PRE></DIV></DIV> <HR> </DIV></BODY></HTML>

Add new attachment

Only authorized users are allowed to upload new attachments.

List of attachments

Kind Attachment Name Size Version Date Modified Author Change note
jpg
1.jpg 94.1 kB 2 06-Apr-2006 09:45 218.144.184.36
« This page (revision-1) was last changed on 06-Apr-2006 09:45 by UnknownAuthor