Last modified by christoph_lechleitner@iteg_at on 2013-01-31 07.32:56
Summary
-
Page properties (1 modified, 0 added, 0 removed)
-
Objects (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -1,6 +1,6 @@ 1 -= {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-Preliminary"/}}Preliminary = 1 +=== {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-Preliminary"/}}Preliminary === 2 2 3 -The SchemaManager and SchemaEngine give you an abstracted access to the database schema of your application, allowing you to add and delete tables, columns,relationsand datainthedatabase on application updates. It uses a designated table to keep track of the current schema status, which it will check whenever it is run, and update the database if it is not at the correct version.3 +The SchemaManager and SchemaEngine give you an abstracted access to the database schema of your application, allowing you to add and delete tables, fields and relations with application updates. It uses a designated table to keep track of the current schema status, which it will check whenever it is run, and update the database if it is not at the correct version. 4 4 5 5 SchemaManager ({{code language="none"}}org.clazzes.jdbc2xml.schema.SchemaManager{{/code}}) will create a table called SCHEMA_HISTORY if it can not find it the first time it is run. This table contains the following columns: 6 6 ... ... @@ -11,21 +11,15 @@ 11 11 SERIALNR:integer(5), not null 12 12 {{/code}} 13 13 14 - ={{idname="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-ProjectConfiguration"/}}ProjectConfiguration=14 +It will also take a list of TableInfo ({{code language="none"}}org.clazzes.jdbc2xml.schema.TableInfo{{/code}}) Objects and create a database from them, if it finds an empty database when it starts. 15 15 16 - Tofunction correctly, SchemaManager needs a DataSource ({{code language="none"}}javax.sql.DataSource{{/code}}) and a list of TableInfo ({{code language="none"}}org.clazzes.jdbc2xml.schema.TableInfo{{/code}}) Objects, from which a database will be created if it finds an empty database. To function properly, it also needs an implementation of ISchemaEngine ({{code language="none"}}org.clazzes.jdbc2xml.schema.ISchemaEngine{{/code}}).16 + 17 17 18 - Optionally, youmay setthebaseversion(default value0.1.00)andbasedescriptionString (default"initialdatabaseschema").18 +=== {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-UsingOSGiandBlueprint"/}}Using OSGi and Blueprint === 19 19 20 - Databaseupdatesarepassedasa Map<String,ISchemaUpdateSnippet> (org.clazzes.jdbc2xml.schema.ISchemaUpdateSnippet)-detailsseebelow.20 +After adding a dependency to the {{code language="none"}}org.clazzes.jdbc2xml{{/code}} library with your favourite package management system, add the following to your blueprint {{code language="none"}}services.xml{{/code}} configuration: 21 21 22 -To perform the operations, call {{code language="none"}}SchemaManager.start(){{/code}}. 23 - 24 -=== {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-UsingSpringorOSGi/Blueprint"/}}Using Spring or OSGi/Blueprint === 25 - 26 -If you are using OSGi with Blueprint or Spring to set up your project, you can configure a SchemaManager instance by adding the following to your blueprint {{code language="none"}}services.xml{{/code}} (or Spring configuration file): 27 - 28 -{{code language="html/xml"}} 22 +{{code language="none"}} 29 29 <bp:reference id="dialectFactory" interface="org.clazzes.jdbc2xml.schema.IDialectFactory"> 30 30 </bp:reference> 31 31 ... ... @@ -33,7 +33,7 @@ 33 33 </bp:reference> 34 34 35 35 <bp:bean id="sqlDialect" factory-ref="dialectFactory" factory-method="newDialect"> 36 -<bp:argument> <!-- PassJDBC URLas an argument-->30 +<bp:argument ref="jdbcUrl"> <!-- JDBC URL --> 37 37 </bp:argument> 38 38 </bp:bean> 39 39 ... ... @@ -42,12 +42,13 @@ 42 42 </bp:property> 43 43 </bp:bean> 44 44 45 -<bp:bean id="databaseSetup" class="org.clazzes.jdbc2xml.schema.SchemaManager" init-method="start"> 39 +<bp:bean id="databaseSetup" class="org.clazzes.jdbc2xml.schema.SchemaManager" 40 +init-method="start"> 46 46 <bp:property name="dataSource" ref="dataSource"></bp:property> 47 47 <bp:property name="schemaEngine" ref="schemaEngine"></bp:property> 48 48 <bp:property name="baseVersion" value="0.1.00" /> 49 49 <bp:property name="baseTables"> 50 -< !--Add ListofTableDefinitionshere(seebelow) -->45 +<bp:bean factory-ref="tableDefinitions" factory-method="getSetup" /> 51 51 </bp:property> 52 52 <bp:property name="upateSnippets"> 53 53 <!-- Add Update-Snippets here --> ... ... @@ -55,189 +55,4 @@ 55 55 </bp:bean> 56 56 {{/code}} 57 57 58 -By default, JDBC2XML provides an implementation of IDialectFactory and ISchemaEngineFactory as an OSGi service or via ServiceRegistry lookup for Spring. 59 - 60 -= {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-Settingupaninitialdatabaseschema"/}}Setting up an initial database schema = 61 - 62 -To create an initial database schema, you will need to provide SchemaManager with a list of TableInfo objects. The recommended way to do this is to provide a class in your project which creates this list in it's constructor and provides it through a getter. You can instantiate this class in your Spring/Blueprint config as a singleton, and feed the provided List to SchemaManager. An example of this class could look like this: 63 - 64 -{{code language="java"}} 65 -package org.clazzes.example.jdbc2xml; 66 - 67 -import java.sql.Types; 68 -import java.util.Arrays; 69 -import java.util.List; 70 - 71 -import org.clazzes.jdbc2xml.schema.ColumnInfo; 72 -import org.clazzes.jdbc2xml.schema.ForeignKeyInfo; 73 -import org.clazzes.jdbc2xml.schema.PrimaryKeyInfo; 74 -import org.clazzes.jdbc2xml.schema.TableInfo; 75 - 76 -public class TableDefinitions { 77 - 78 - // It is adviseable to provide the Strings used as names for tables and columns as constants, so they can be reused outside this object to build sql-statements 79 - public static final String TB_EXAMPLE_TABLE_NAME = "ADDRESSBOOK"; 80 - public static final String COL_EXAMPLE_ID = "ID"; 81 - public static final String COL_EXAMPLE_NAME = "NAME"; 82 - public static final String COL_EXAMPLE_ADDRESS_REF = "ADDRESS"; 83 - public static final String COL_EXAMPLE_BIRTHDAY = "BIRTHDAY"; 84 - 85 - // ... 86 - 87 - private List<TableInfo> setup; 88 - 89 - public TableDefinitions() { 90 -// Create a table 91 -TableInfo exampleTable = new TableInfo(TB_EXAMPLE_TABLE_NAME); 92 -exampleTable.setColumns( 93 - Arrays.asList(new ColumnInfo[] { 94 -new ColumnInfo(COL_EXAMPLE_ID, Types.BIGINT, 20, null, false, null,true), 95 -new ColumnInfo(COL_EXAMPLE_NAME, Types.VARCHAR, 256, null, false, null), 96 -new ColumnInfo(COL_EXAMPLE_ADDRESS_REF, Types.BIGINT, 20, null, true, null), 97 -new ColumnInfo(COL_EXAMPLE_BIRTHDAY, Types.DATE, 12, null, false, null) 98 -})); 99 - 100 -// Example for creating a foreign key reference 101 -exampleTable.setForeignKeys(Arrays.asList(new ForeignKeyInfo[] { 102 -new ForeignKeyInfo("FK_EXAMPLE_ADDRESS", COL_EXAMPLE_ADDRESS_REF, TB_ADDRESS, COL_ADDRESS_ID) 103 -})); 104 - 105 -// Example for creating a primary key 106 -exampleTable.setPrimaryKey( 107 -new PrimaryKeyInfo("PK_EXAMPLE", COL_EXAMPLE_ID) 108 -); 109 - 110 -// ... 111 - 112 -this.setup = Arrays.asList( 113 -exampleTable, 114 -// ... 115 -); 116 - 117 - } 118 - 119 - public List<TableInfo> getSetup() { 120 -return this.setup; 121 - } 122 - 123 -} 124 -{{/code}} 125 - 126 -You must inject {{code language="none"}}TableDefinitions.getSetup(){{/code}} into {{code language="none"}}SchemaManager.setBaseTables(){{/code}} before calling {{code language="none"}}SchemaManager.start(){{/code}}. 127 - 128 -Using Blueprint/Spring, you can do this by inserting the following snippet in the bean definition for SchemaManager: 129 - 130 -{{code language="html/xml"}} 131 -<!-- SchemaManager bean definition starts here ... --> 132 -<bp:property name="baseTables"> 133 -<bp:bean factory-ref="tableDefinitions" factory-method="getSetup" /> 134 -</bp:property> 135 -<!-- ... and continues here --> 136 -{{/code}} 137 - 138 -= {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-UpdatingadatabaseschemawithISchemaUpdateSnippet"/}}Updating a database schema with ISchemaUpdateSnippet = 139 - 140 -To update the database or it's content with schema updates, you must create a new implementation of ISchemaUpdateSnippet ({{code language="none"}}org.clazzes.jdbc2xml.schema.ISchemaUpdateSnippet{{/code}}) for each consecutive update. SchemaManager takes a {{code language="none"}}Map<String, Class<? extends ISchemaUpdateSnippet>>{{/code}} which contains the update classes keyed by the originating (e.g. previous) version. 141 - 142 -An example for an implementation of a schema update snippet could look like this: 143 - 144 -{{code language="java"}} 145 -package org.clazzes.example.jdbc2xml.updates; 146 - 147 -import java.sql.SQLException; 148 -import java.sql.Types; 149 -import java.util.Arrays; 150 -import org.clazzes.jdbc2xml.schema.ColumnInfo; 151 -import org.clazzes.jdbc2xml.schema.ISchemaEngine; 152 -import org.clazzes.jdbc2xml.schema.ISchemaUpdateSnippet; 153 -import org.clazzes.jdbc2xml.schema.PrimaryKeyInfo; 154 -import org.clazzes.jdbc2xml.schema.TableInfo; 155 - 156 -public class SchemaUpdate0_1_01 implements ISchemaUpdateSnippet { 157 - 158 -// This is only accessed through the getter 159 -private static final String TARGET_VERSION = "0.1.01"; 160 - 161 -// Here it is also adviseable to define constants for reuse in statements. 162 -public static final String COL_EXAMPLE_GENDER = "GENDER"; 163 - 164 - 165 -@Override 166 -public String getTargetVersion() { 167 -return TARGET_VERSION; 168 -} 169 - 170 -@Override 171 -public String getUpdateComment() { 172 -return "Adding column "+COL_EXAMPLE_GENDER+" to table "+TableDefinitions.TB_EXAMPLE_TABLE_NAME+"."; 173 -} 174 - 175 -@Override 176 -public void performUpdate(ISchemaEngine schemaEngine) throws SQLException { 177 -TableInfo ti = schemaEngine.fetchTableInfo(TableDefinitions.TB_EXAMPLE_TABLE_NAME, null); 178 - schemaEngine.addColumn(ti, new ColumnInfo(COL_EXAMPLE_GENDER, Types.VARCHAR, 1, null, true, null)); 179 -} 180 -} 181 - 182 - 183 -{{/code}} 184 - 185 -The return values of {{code language="none"}}ISchemaUpdateSnippet.getTargetVersion(){{/code}} and {{code language="none"}}ISchemaUpdateSnippet.getUpdateComment(){{/code}} are written to the {{code language="none"}}SCHEMA_HISTORY{{/code}} table. The update itself is performed in {{code language="none"}}ISchemaUpdateSnippet.performUpdate(){{/code}}. In the above example, it adds a column called {{code language="none"}}GENDER{{/code}} to the example table created by the TableDefinitions class above. 186 - 187 -To add an entire table you would use the {{code language="none"}}ISchemaEngine.createTable(){{/code}} method, like this: 188 - 189 -{{code language="java"}} 190 -@Override 191 -public void performUpdate(ISchemaEngine schemaEngine) throws SQLException { 192 - TableInfo tiGroup = new TableInfo(TB_GROUP); 193 - tiGroup.setColumns(Arrays.asList(new ColumnInfo[] { 194 - new ColumnInfo(TableDefinitions.COL_ID, Types.VARCHAR, 36, null, false, null), 195 - new ColumnInfo(TableDefinitions.COL_NAME, Types.VARCHAR, 100, null, false, null), 196 - new ColumnInfo(TableDefinitions.COL_DESCRIPTION, Types.VARCHAR, 512, null, true, null) 197 - })); 198 - tiGroup.setPrimaryKey(new PrimaryKeyInfo(PK_GROUP, TableDefinitions.COL_ID)); 199 - tiGroup.setIndices(Arrays.asList(new IndexInfo(IDX_GROUP_01, TableDefinitions.COL_NAME, true, null))); 200 - 201 -schemaEngine.createTable(tiGroup, true); 202 -} 203 -{{/code}} 204 - 205 -Executing a PreparedStatement also works, using ISchemaEngine.getConnection() to retrieve the database connection: 206 - 207 -{{code language="java"}} 208 -@Override 209 -public void performUpdate(ISchemaEngine schemaEngine) throws SQLException { 210 - String sql = "UPDATE "+TableDefinitions.TB_EXAMPLE_TABLE_NAME+" SET "+TableDefinitions.COL_EXAMPLE_NAME+"=?"; 211 - 212 - PreparedStatement ps = schemaEngine.getConnection().prepareStatement(sql); 213 - 214 - ps.setNull(1, Types.VARCHAR); 215 - 216 - ps.execute(); 217 -} 218 -{{/code}} 219 - 220 -To create the map of updates in Blueprint/Spring and inject them into SchemaManager, use the following xml-Snippet: 221 - 222 -{{code language="html/xml"}} 223 -<!-- SchemaManager bean definition starts here ... --> 224 -<bp:property name="upateSnippets"> 225 -<bp:map> 226 -<bp:entry key="0.1.00" value="org.clazzes.example.jdbc2xml.updates.SchemaUpdate0_1_01"></bp:entry> 227 -<!-- more entries come here: "key" is the schema version to update, "value" the qualified classname of the schema update --> 228 -</bp:map> 229 -</bp:property> 230 -<!-- ... and continues here --> 231 -{{/code}} 232 - 233 - 234 - 235 - 236 - 237 - 238 - 239 - 240 - 241 - 242 - 243 - 53 +The SchemaManager takes a map of
- Confluence.Code.ConfluencePageClass[0]
-
- Id
-
... ... @@ -1,1 +1,1 @@ 1 -6568 211 +656804 - URL
-
... ... @@ -1,1 +1,1 @@ 1 -https://clazzes.atlassian.net/wiki/spaces/JDBC2XML/pages/6568 21/How To create and update Databases using SchemaManager and SchemaUpdateSnippets1 +https://clazzes.atlassian.net/wiki/spaces/JDBC2XML/pages/656804/How To create and update Databases using SchemaManager and SchemaUpdateSnippets