From: <tu...@us...> - 2003-04-03 01:43:34
|
Update of /cvsroot/hibernate/Hibernate2/doc/reference/src In directory sc8-pr-cvs1:/tmp/cvs-serv11450/src Modified Files: index.xml Added Files: toolset_guide.xml Log Message: Added toolset guide to reference docs --- NEW FILE: toolset_guide.xml --- <chapter id="toolsetguide"> <title>Toolset Guide</title> <para> Hibernate supports roundtrip engineering with a set of tools for DDL schema generation from a mapping file, mapping file generation from Java source code, Java class generation from a mapping file and a reverse engineering tool to generate Java classes and mapping files from an existing database schema. </para> <para> A set of example DOS batch files for the toolset is located in the <literal>bin</literal>-directory of the Hibernate distribution. </para> <sect1 id="toolsetguide-s1"> <title>Schema Generation</title> <para> A schema can be generated from your mapping file/s through a command line utility: </para> <para> <literal>net.sf.hibernate.tool.hbm2ddl.SchemaExport</literal> </para> <para> The generated schema include referential integrity constraints (primary and foreign keys) for entity tables, and indexes and foreign keys for collection tables. Tables are also created for all instances of <literal>HiLoGenerator</literal>. <literal>HiLoGenerator</literal> tables are specified in the elements of the <literal><generator></literal> tag. </para> <sect2 id="toolsetguide-s1-1"> <title>SQL Dialects</title> <para> Schema generation works for all officially supported databases (DB2, Postgres, Oracle, MySQL, Sybase, Microsoft SQL Server, HypersonicSQL, Progress, Interbase, Pointbase, McKoi and SAP DB). Other products may be supported by subclassing <literal>net.sf.hibernate.dialect.Dialect</literal>. If you do implement <literal>Dialect</literal> for any database not on our list, please contribute it back to the project. </para> <table frame="all"> <title>Hibernate SQL Dialects (<literal>hibernate.dialect</literal>)</title> <tgroup cols="2"> <colspec colwidth="1*"/> <colspec colwidth="2.5*"/> <thead> <row> <entry>RDBMS</entry> <entry>Dialect</entry> </row> </thead> <tbody> <row> <entry>DB2</entry> <entry><literal>net.sf.hibernate.dialect.DB2Dialect</literal></entry> </row> <row> <entry>MySQL</entry> <entry><literal>net.sf.hibernate.dialect.MySQLDialect</literal></entry> </row> <row> <entry>SAP DB</entry> <entry><literal>net.sf.hibernate.dialect.SAPDBDialect</literal></entry> </row> <row> <entry>Oracle (any version)</entry> <entry><literal>net.sf.hibernate.dialect.OracleDialect</literal></entry> </row> <row> <entry>Oracle 9</entry> <entry><literal>net.sf.hibernate.dialect.Oracle9Dialect</literal></entry> </row> <row> <entry>Sybase</entry> <entry><literal>net.sf.hibernate.dialect.SybaseDialect</literal></entry> </row> <row> <entry>Progress</entry> <entry><literal>net.sf.hibernate.dialect.ProgressDialect</literal></entry> </row> <row> <entry>Mckoi SQL</entry> <entry><literal>net.sf.hibernate.dialect.McKoiDialect</literal></entry> </row> <row> <entry>Interbase</entry> <entry><literal>net.sf.hibernate.dialect.InterbaseDialect</literal></entry> </row> <row> <entry>Pointbase</entry> <entry><literal>net.sf.hibernate.dialect.PointbaseDialect</literal></entry> </row> <row> <entry>PostgreSQL</entry> <entry><literal>net.sf.hibernate.dialect.PostgreSQLDialect</literal></entry> </row> <row> <entry>HypersonicSQL</entry> <entry><literal>net.sf.hibernate.dialect.HSQLDialect</literal></entry> </row> <row> <entry>Microsoft SQL Server</entry> <entry><literal>net.sf.hibernate.dialect.SybaseDialect</literal></entry> </row> <row> <entry>Ingres</entry> <entry><literal>net.sf.hibernate.dialect.IngresDialect</literal></entry> </row> <row> <entry>FrontBase</entry> <entry><literal>net.sf.hibernate.dialect.FrontbaseDialect</literal></entry> </row> </tbody> </tgroup> </table> </sect2> <sect2 id="toolsetguide-s1-2"> <title>Customizing the Schema</title> <para> The <literal><id></literal>, <literal><discriminator></literal>, <literal><property></literal>, <literal><key></literal>, <literal><index></literal>, <literal><element></literal>, <literal><many-to-one></literal>, <literal><many-to-many></literal> and <literal><column></literal> tags take an optional attribute named <literal>length</literal>. You may set the <literal>length</literal> of a generated character or binary column with this attribute. </para> <para> Some tags also accept a <literal>not-null</literal> attribute (for generating a <literal>NOT NULL</literal> constraint on table columns) and a <literal>unique</literal> attribute (for generating <literal>UNIQUE</literal> constraint on table columns). </para> <para> Some tags accept an <literal>index</literal> attribute for specifying the name of an index for that column. </para> <para> Examples: </para> <programlisting><![CDATA[<property name="foo" type="string" length="64" not-null="true"/> <subcollection column="serial_numbers" role="serial-numbers" not-null="true" unique="true"/> <element column="serial_number" type="long" not-null="true" unique="true"/>]]></programlisting> <para> Alternatively, these elements also accept a child <literal><column></literal> element. This is particularly useful for multi-column types: </para> <programlisting><![CDATA[<property name="foo" type="string"> <column name="foo" length="64" not-null="true" sql-type="text"/> </property> <subcollection role="serial-numbers"/> <column name="serial_numbers" not-null="true" unique="true"/> </subcollection> <property name="bar" type="my.customtypes.MultiColumnType"/> <column name="fee" not-null="true" index="bar_idx"/> <column name="fi" not-null="true" index="bar_idx"/> <column name="fo" not-null="true" index="bar_idx"/> </property>]]></programlisting> <para> The <literal>sql-type</literal> attribute allows the user to override the default mapping of Hibernate type to SQL datatype. </para> </sect2> <sect2 id="toolsetguide-s1-3"> <title>Running the tool</title> <para> The <literal>SchemaExport</literal> tool writes a DDL script to standard out and/or executes the script immediately on the database. </para> <para> <literal>java -cp </literal><emphasis>hibernate_classpaths</emphasis> <literal>net.sf.hibernate.tool.hbm2ddl.SchemaExport</literal> <emphasis>options mapping_files</emphasis> </para> <table frame="all"> <title>SchemaExport Command Line Options</title> <tgroup cols="2"> <colspec colwidth="1.5*"/> <colspec colwidth="2*"/> <thead> <row> <entry>Option</entry> <entry>Description</entry> </row> </thead> <tbody> <row> <entry><literal>--quiet</literal></entry> <entry>don't output the script to stdout</entry> </row> <row> <entry><literal>--drop</literal></entry> <entry>only drop the tables</entry> </row> <row> <entry><literal>--text</literal></entry> <entry>don't export to the database</entry> </row> <row> <entry><literal>--output=my_schema.ddl</literal></entry> <entry>output the ddl script to a file</entry> </row> <row> <entry><literal>--properties=hibernate.properties</literal></entry> <entry>read database properties from a file</entry> </row> <row> <entry><literal>--format</literal></entry> <entry>format the generated SQL nicely in the script</entry> </row> <row> <entry><literal>--delimiter=x</literal></entry> <entry>set an end of line delimiter for the script</entry> </row> </tbody> </tgroup> </table> <para> Optionally, you can control the <literal>SchemaExport</literal> tool in your application: </para> <programlisting><![CDATA[Datastore ds; new net.sf.hibernate.tool.hbm2ddl.SchemaExport(ds, properties).create(false, true);]]></programlisting> </sect2> <sect2 id="toolsetguide-s1-4"> <title>Properties</title> <para> Database properties may be specified </para> <itemizedlist spacing="compact"> <listitem> <para>as system properties with -D<emphasis><property></emphasis></para> </listitem> <listitem> <para>in <literal>hibernate.properties</literal></para> </listitem> <listitem> <para>in a named properties file with <literal>--properties</literal></para> </listitem> </itemizedlist> <para> The needed properties are: </para> <itemizedlist spacing="compact"> <listitem> <para><literal>hibernate.connection.driver = </literal> <emphasis>jdbc driver class</emphasis></para> </listitem> <listitem> <para><literal>hibernate.connection.url = </literal> <emphasis>jdbc url</emphasis></para> </listitem> <listitem> <para><literal>hibernate.connection.username = </literal> <emphasis>database user</emphasis></para> </listitem> <listitem> <para><literal>hibernate.connection.password = </literal> <emphasis>user password</emphasis></para> </listitem> <listitem> <para><literal>hibernate.dialect = </literal> <emphasis>dialect</emphasis></para> </listitem> </itemizedlist> </sect2> <sect2 id="toolsetguide-s1-5"> <title>Using Ant</title> <para> You can call the <literal>SchemaExport</literal> tool from your Ant build script: </para> <programlisting><![CDATA[<target name="initdb" depends="compile"> <java classname="cirrus.hibernate.tools.SchemaExport" fork="true"> <!-- mapping file --> <arg value="/projects/smis/src/resources/web/WEB-INF/mapping.xml"/> <jvmarg value="-Dhibernate.dialect=cirrus.hibernate.sql.SybaseDialect"/> <jvmarg value="-Dhibernate.connection.driver_class=com.inet.tds.TdsDriver"/> <jvmarg value="-Dhibernate.connection.url=jdbc:inetdae:localhost:1433"/> <jvmarg value="-Dhibernate.connection.username=xxx"/> <jvmarg value="-Dhibernate.connection.password=xxx"/> <classpath> <fileset dir="${basedir}/lib"> <include name="**/*.jar" /> </fileset> <!-- build output path --> <pathelement location="${build.dir}/classes/web/WEB-INF/classes"/> </classpath> </java> </target>]]></programlisting> </sect2> </sect1> <sect1 id="toolsetguide-s2"> <title>Map Generation</title> <para> A skeleton O-R mapping file may be generated for your persistent classes through a command line utility in </para> <para> <literal>src.net.sf.hibernate.tool.class2hbm.MapGenerator</literal> </para> <para> MapGenerator provides a mechanism to produce a Hibernate XML OR-Mapping from compiled classes. It does this using Java reflection to find <emphasis>properties</emphasis> to be persisted in the classes, and using the types of the properties to further guide the reflection. </para> <para> The generated mapping is intended to be a starting point only. There is no way to produce a full Hibernate O-R mapping without extra input from the user. However, the tool does take away some of the repetitive "grunt" work involved in producing a mapping. </para> <para> Classes are added to the mapping one at a time. <literal>MapGenerator</literal> will reject classes that it judges are are not <emphasis>Hibernate persistable</emphasis>. </para> <para> To be <emphasis>Hibernate persistable</emphasis> a class </para> <itemizedlist spacing="compact"> <listitem> <para>must not be a primitive type</para> </listitem> <listitem> <para>must not be an array</para> </listitem> <listitem> <para>must not be an interface</para> </listitem> <listitem> <para>must not be a nested class</para> </listitem> <listitem> <para>must have a default (zero argument) constructor.</para> </listitem> </itemizedlist> <para> Note that interfaces and nested classes actually are persistable by Hibernate, but this would not usually be intended by the user. </para> <para> <literal>MapGenerator</literal> will climb the superclass chain of all added classes attempting to add as many Hibernate persistable superclasses as possible to the same database table. The search stops as soon as a property is found that has a name appearing on a list of <emphasis>candidate UID names</emphasis>. </para> <para> The default list of candidate UID property names is: <literal>uid</literal>, <literal>UID</literal>, <literal>id</literal>, <literal>ID</literal>, <literal>key</literal>, <literal>KEY</literal>, <literal>pk</literal>, <literal>PK</literal>. </para> <para> Properties are discovered when there are two methods in the class, a setter and a getter, where the type of the setter's single argument is the same as the return type of the zero argument getter, and the setter returns <literal>void</literal>. Furthermore, the setter's name must start with the string <literal>set</literal> and either the getter's name starts with <literal>get</literal> or the getter's name starts with <literal>is</literal> and the type of the property is boolean. In either case, the remainder of their names must match. This matching portion is the name of the property, except that the initial character of the property name is made lower case if the second letter is lower case. </para> <para> The rules for determining the database type of each property are as follows: </para> <orderedlist spacing="compact"> <listitem> <para> If the Java type is <literal>Hibernate.basic()</literal>, then the property is a simple column of that type. </para> </listitem> <listitem> <para> For <literal>hibernate.type.Type</literal> custom types and <literal>PersistentEnum</literal> a simple column is used as well. </para> </listitem> <listitem> <para> If the property type is an array, then a Hibernate array is used, and <literal>MapGenerator</literal> attempts to reflect on the array element type. </para> </listitem> <listitem> <para> If the property has type <literal>java.util.List</literal>, <literal>java.util.Map</literal>, or <literal>java.util.Set</literal>, then the corresponding Hibernate types are used, but <literal>MapGenerator</literal> cannot further process the insides of these types. </para> </listitem> <listitem> <para> If the property's type is any other class, <literal>MapGenerator</literal> defers the decision on the database representation until all classes have been processed. At this point, if the class was discovered through the superclass search described above, then the property is an <literal>many-to-one</literal> association. If the class has any properties, then it is a <literal>component</literal>. Otherwise it is serializable, or not persistable. </para> </listitem> </orderedlist> <sect2 id="toolsetguide-s2-1"> <title>Running the tool</title> <para> The tool writes XML O-R mapping to standard out and/or to a file. </para> <para> When invoking <literal>MapGenerator</literal> you must place your compiled classes on the classpath, and start Java in the <literal>MapGenerator.main()</literal> method. </para> <para> <literal>java -cp </literal><emphasis>hibernate_and_your_class_classpaths</emphasis> <literal>src.net.sf.hibernate.tool.class2hbm.MapGenerator</literal> <emphasis>options and classnames</emphasis> </para> <para> There are two modes of operation: command line or interactive. </para> <para> The interactive mode is selected by providing the single command line argument <literal>--interact</literal>. This mode provides a prompt response console. Using it you can set the UID property name for each class using the <literal>uid=XXX</literal> command where <literal>XXX</literal> is the UID property name. Other command alternatives are simply a fully qualified class name, or the command done which emits the XML and terminates. </para> <para> In command line mode the arguments are the options below interspersed with fully qualified class names of the classes to be processed. Most of the options are meant to be used multiple times; each use affects subsequently added classes. </para> <table frame="all"> <title>MapGenerator Command Line Options</title> <tgroup cols="2"> <colspec colwidth="1*"/> <colspec colwidth="2*"/> <thead> <row> <entry>Option</entry> <entry>Description</entry> </row> </thead> <tbody> <row> <entry><literal>--quiet</literal></entry> <entry>don't output the O-R Mapping to stdout</entry> </row> <row> <entry><literal>--setUID=uid</literal></entry> <entry>set the list of candidate UIDs to the singleton uid</entry> </row> <row> <entry><literal>--addUID=uid</literal></entry> <entry>add uid to the front of the list of candidate UIDs</entry> </row> <row> <entry><literal>--select=</literal><emphasis>mode</emphasis></entry> <entry>mode use select mode <emphasis>mode</emphasis>(e.g., <emphasis>distinct</emphasis> or <emphasis>all</emphasis>) for subsequently added classes</entry> </row> <row> <entry><literal>--depth=<small-int></literal></entry> <entry>limit the depth of component data recursion for subsequently added classes</entry> </row> <row> <entry><literal>--output=my_mapping.xml</literal></entry> <entry>output the O-R Mapping to a file</entry> </row> <row> <entry><emphasis>full.class.Name</emphasis></entry> <entry>add the class to the mapping</entry> </row> <row> <entry><literal>--abstract=</literal><emphasis>full.class.Name</emphasis></entry> <entry>see below</entry> </row> </tbody> </tgroup> </table> <para> The abstract switch directs the map generator tool to ignore specific super classes so that classes with common inheritance are not mapped to one large table. For instance, consider these class hierarchies: </para> <para> <literal>Animal-->Mammal-->Human</literal> </para> <para> <literal>Animal-->Mammal-->Marsupial-->Kangaroo</literal> </para> <para> If the <literal>--abstract</literal>switch is <emphasis>not</emphasis> used, all classes will be mapped as subclasses of <literal>Animal</literal>, resulting in one large table containing all the properties of all the classes plus a discriminator column to indicate which subclass is actually stored. If <literal>Mammal</literal> is marked as <literal>abstract</literal>, <literal>Human</literal> and <literal>Marsupial</literal> will be mapped to separate <literal><class></literal> declarations and stored in separate tables. <literal>Kangaroo</literal> will still be a subclass of <literal>Marsupial</literal> unless <literal>Marsupial</literal> is also marked as <literal>abstract</literal>. </para> </sect2> </sect1> <sect1 id="toolsetguide-s3"> <title>Code Generation</title> <para> The Code Generator may be used to generate skeletal Java implementation classes of a hibernate mapping file. </para> <para> <literal>java -cp</literal> <emphasis>hibernate_classpaths</emphasis> <literal>net.sf.hibernate.tool.hbm2java.CodeGenerator</literal> <emphasis> options mapping_files</emphasis> </para> <table frame="all"> <title>Code Generator Command Line Options</title> <tgroup cols="2"> <colspec colwidth="1*"/> <colspec colwidth="2*"/> <thead> <row> <entry>Option</entry> <entry>Description</entry> </row> </thead> <tbody> <row> <entry><literal>--output=</literal><emphasis>output_dir</emphasis></entry> <entry>root directory for generated code</entry> </row> </tbody> </tgroup> </table> </sect1> <sect1 id="toolsetguide-s4"> <title>Reverse Engineering Tool</title> <para> The Reverse Engineering Tool may be used to generate Hibernate mapping files and Java source files from an existing database schema. Using database metadata, the tool retrieves table and column information and generates appropriate mapping files and Java source. </para> <para> The tool is implemented as a small Swing application with several configuration screens: </para> <sect2 id="toolsetguide-s4-1"> <title>Connection Panel</title> <para> Configure the JDBC connection here. Note that the specified JDBC driver class must be in the classpath. </para> </sect2> <sect2 id="toolsetguide-s4-2"> <title>Tables</title> <para> Select the tables for generation in this panel. Start by clicking the tables button at the top of the panel. Specify a catalog, schema, and table name pattern in the resulting dialog (the table name pattern is specified using SQL <literal>like</literal> syntax). On exiting the dialog, the tables panel will display the selected database tables. You may select one or more tables for generation. </para> </sect2> <sect2 id="toolsetguide-s4-3"> <title>Mapping</title> <para> The mapping panel may be used to configure the mapping file generator. </para> <itemizedlist spacing="compact"> <listitem> <para> <literal>Mapping File</literal> - select to generate one mapping file for each database table, or to generate a single map for all tables. </para> </listitem> <listitem> <para> <literal>Key Field Name</literal> - specify the name of the identifier property used in each Hibernate class. </para> </listitem> <listitem> <para> <literal>Generator</literal> - select the Hibernate generator that will assign identifier values. The <literal>params</literal> button produces a dialog for configuring generator parameters. </para> </listitem> <listitem> <para> <literal>Key Field Type</literal> - select Hibernate types or Java types. Selecting Hibernate types will result in Java source using primitive field types, selecting Java types will result in Java source using object types (<literal>Integer</literal>, etc.). </para> </listitem> <listitem> <para> <literal>Key Field Class</literal> - specify the type of key field to be used in the mapping file and generated source. </para> </listitem> </itemizedlist> </sect2> <sect2 id="toolsetguide-s4-4"> <title>Code</title> <itemizedlist spacing="compact"> <listitem> <para> <literal>Package Name</literal> - sets the package name for generated Java source. </para> </listitem> <listitem> <para> <literal>Base Class Name</literal> - set a base class for generated Java source files. useful if you want to consolidate common behavior in Hibernate classes. </para> </listitem> </itemizedlist> </sect2> <sect2 id="toolsetguide-s4-5"> <title>Output</title> <itemizedlist spacing="compact"> <listitem> <para> <literal>Output Directory</literal> - sets the output directory for the generated mapping file and Java sources. Note that all files will be created in a directory according to the package name, relative to the output directory specified here. </para> </listitem> <listitem> <para> <literal>Base Class Name</literal> - set a base class for generated Java source files. useful if you want to consolidate common behavior in Hibernate classes. </para> </listitem> </itemizedlist> </sect2> </sect1> </chapter> Index: index.xml =================================================================== RCS file: /cvsroot/hibernate/Hibernate2/doc/reference/src/index.xml,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** index.xml 27 Mar 2003 23:15:57 -0000 1.5 --- index.xml 3 Apr 2003 01:43:30 -0000 1.6 *************** *** 13,16 **** --- 13,17 ---- <!ENTITY examples SYSTEM "examples.xml"> <!ENTITY best-practices SYSTEM "best_practices.xml"> + <!ENTITY toolset-guide SYSTEM "toolset_guide.xml"> ]> *************** *** 45,48 **** --- 46,51 ---- &best-practices; + + &toolset-guide; </book> |