Last modified by christoph_lechleitner@iteg_at on 2013-01-31 07.32:56
From version 7.1
edited by christoph_lechleitner@iteg_at
on 2013-01-31 07.32:55
on 2013-01-31 07.32:55
Change comment:
There is no comment for this version
To version 6.1
edited by christoph_lechleitner@iteg_at
on 2013-01-31 07.04:57
on 2013-01-31 07.04:57
Change comment:
There is no comment for this version
Summary
-
Page properties (1 modified, 0 added, 0 removed)
-
Objects (1 modified, 0 added, 0 removed)
Details
- Page properties
-
- Content
-
... ... @@ -92,10 +92,7 @@ 92 92 <bp:property name="dialect" ref="sqlDialect"> 93 93 </bp:property> 94 94 </bp:bean> 95 - 96 96 97 -<bp:bean id="initialSchema" class="foo.schema.InitialSchema"></bp:bean> 98 - 99 99 <bp:bean id="databaseSetup" class="org.clazzes.jdbc2xml.schema.SchemaManager" init-method="start"> 100 100 <bp:property name="dataSource" ref="dataSource"></bp:property> 101 101 <bp:property name="schemaEngine" ref="schemaEngine"></bp:property> ... ... @@ -105,7 +105,7 @@ 105 105 <bp:property name="baseVersion" value="0.1.00" /> 106 106 <bp:property name="baseTables"> 107 107 <!-- List of TableDefinitions here (see below), typical: --> 108 - <bp:bean factory-ref="initi alSchema" factory-method="getSchema" />105 + <!-- <bp:bean factory-ref="tableDefinitions" factory-method="getSetup" /> --> 109 109 </bp:property> 110 110 <!-- Add Update-Snippets here, example for updates from 0.1.00 to 0.1.01 and on to 0.2.00 111 111 <bp:property name="upateSnippets"> ... ... @@ -122,8 +122,6 @@ 122 122 123 123 = {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-Settingupaninitialdatabaseschema"/}}Setting up an initial database schema = 124 124 125 -=== {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-InitalSchema(InitialTableList)"/}}Inital Schema (Initial Table List) === 126 - 127 127 To create an initial database schema, SchemaManager needs a list of TableInfo objects. 128 128 129 129 The recommended strategy is to create an InitialSchema class providing this list through a getter. ... ... @@ -131,7 +131,7 @@ 131 131 (% style="font-size: 10.0pt;line-height: 13.0pt;" %)This is an example: 132 132 133 133 {{code language="java"}} 134 -package foo.schema;129 +package org.clazzes.example.jdbc2xml; 135 135 136 136 import java.sql.Types; 137 137 import java.util.Arrays; ... ... @@ -146,27 +146,27 @@ 146 146 147 147 private List<TableInfo> setup; 148 148 149 - public InitialSchema() {144 + public TableDefinitions() { 150 150 // Create a table 151 -TableInfo exampleTable = new TableInfo(TableDefs.T ABLENAME_ADDRESSBOOK);146 +TableInfo exampleTable = new TableInfo(TableDefs.TB_EXAMPLE_TABLE_NAME); 152 152 exampleTable.setColumns( 153 153 Arrays.asList(new ColumnInfo[] { 154 -new ColumnInfo(TableDefs.COL_A DDRESSBOOK_ID, Types.BIGINT, 20, null, false, null,true),155 -new ColumnInfo(TableDefs.COL_A DDRESSBOOK_NAME, Types.VARCHAR, 256, null, false, null),156 -new ColumnInfo(TableDefs.COL_A DDRESSBOOK_ADDRESS_REF, Types.BIGINT, 20, null, true, null),157 -new ColumnInfo(TableDefs.COL_A DDRESSBOOK_BIRTHDAY, Types.DATE, 12, null, false, null)149 +new ColumnInfo(TableDefs.COL_EXAMPLE_ID, Types.BIGINT, 20, null, false, null,true), 150 +new ColumnInfo(TableDefs.COL_EXAMPLE_NAME, Types.VARCHAR, 256, null, false, null), 151 +new ColumnInfo(TableDefs.COL_EXAMPLE_ADDRESS_REF, Types.BIGINT, 20, null, true, null), 152 +new ColumnInfo(TableDefs.COL_EXAMPLE_BIRTHDAY, Types.DATE, 12, null, false, null) 158 158 })); 159 159 160 -// Example for creating a primary key 161 -exampleTable.setPrimaryKey( 162 -new PrimaryKeyInfo("PK_EXAMPLE", COL_ADDRESSBOOK_ID) 163 -); 164 - 165 165 // Example for creating a foreign key reference 166 166 exampleTable.setForeignKeys(Arrays.asList(new ForeignKeyInfo[] { 167 -new ForeignKeyInfo("FK_EXAMPLE_ADDRESS", TableDefs.COL_ADDRESSBOOK_ADDRESS_REF, TableDefs.TABLENAME_ADDRESSES,TableDefs.COL_ADDRESS_ID)157 +new ForeignKeyInfo("FK_EXAMPLE_ADDRESS", COL_EXAMPLE_ADDRESS_REF, TB_ADDRESS, COL_ADDRESS_ID) 168 168 })); 169 169 160 +// Example for creating a primary key 161 +exampleTable.setPrimaryKey( 162 +new PrimaryKeyInfo("PK_EXAMPLE", COL_EXAMPLE_ID) 163 +); 164 + 170 170 // ... 171 171 172 172 this.setup = Arrays.asList( ... ... @@ -183,49 +183,45 @@ 183 183 } 184 184 {{/code}} 185 185 186 -=== {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-TableDefs,acentralplacefortableandcolumnnames"/}}TableDefs, a central place for table and column names === 181 +{{code language="java"}} 182 +package org.clazzes.example.jdbc2xml; 187 187 188 -You may have notice the usage of {{code language="none"}}TableDefs.*{{/code}} members. 184 +import java.sql.Types; 185 +import java.util.Arrays; 186 +import java.util.List; 189 189 190 -Table and column names should never be re-typed everywhere as literals, it is highly recommended to use constants. 191 - 192 -Putting these constants in a dedicated class, say {{code language="none"}}TableDef{{/code}}, allows to use this as an easily accessible list of all tables and columns in the database. 193 - 194 -This is an example: 195 - 196 -{{code language="java"}} 197 -package foo.schema; 188 +import org.clazzes.jdbc2xml.schema.ColumnInfo; 189 +import org.clazzes.jdbc2xml.schema.ForeignKeyInfo; 190 +import org.clazzes.jdbc2xml.schema.PrimaryKeyInfo; 191 +import org.clazzes.jdbc2xml.schema.TableInfo; 198 198 199 199 public class TableDefs { 200 200 201 201 // It is adviseable to provide the Strings used as names for tables and columns as constants, 202 202 // so they can be reused savely to construct SQL statements 203 - 204 - // 0.1.00 205 205 public static final String TABLENAME_ADDRESSBOOK = "ADDRESSBOOK"; 206 206 public static final String COL_ADDRESSBOOK_ID = "ID"; 207 207 public static final String COL_ADDRESSBOOK_NAME = "NAME"; 208 208 public static final String COL_ADDRESSBOOK_ADDRESS_REF = "ADDRESS"; 209 209 public static final String COL_ADDRESSBOOK_BIRTHDAY = "BIRTHDAY"; 210 - // 0.1.01 211 -public static final String COL_ADDRESSBOOK_GENDER = "GENDER"; 212 - 202 + 213 213 } 214 214 {{/code}} 215 215 216 - ==={{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-Triggeringthecreationoftheinitialschema"/}}Triggering the creation of the initial schema ===206 + 217 217 218 - (%style="font-size: 10.0pt;line-height: 13.0pt;" %)To trigger the creation of the initial schema when coming across an empty database, (% style="font-size: 10.0pt;line-height: 13.0pt;" %){{code language="none"}}InitialSchema.getSchema(){{/code}} has to be injected into (% style="font-size: 10.0pt;line-height: 13.0pt;" %){{code language="none"}}SchemaManager.setBaseTables(){{/code}} before calling (% style="font-size: 10.0pt;line-height: 13.0pt;" %){{code language="none"}}SchemaManager.start(){{/code}}.208 + 219 219 210 +You must inject {{code language="none"}}TableDefinitions.getSetup(){{/code}} into {{code language="none"}}SchemaManager.setBaseTables(){{/code}} before calling {{code language="none"}}SchemaManager.start(){{/code}}. 211 + 220 220 Using Blueprint/Spring, you can do this by inserting the following snippet in the bean definition for SchemaManager: 221 221 222 222 {{code language="html/xml"}} 223 -<bp:bean id="initialSchema" class="foo.schema.InitialSchema"></bp:bean> 224 - 215 +<!-- SchemaManager bean definition starts here ... --> 225 225 <bp:property name="baseTables"> 226 -<bp:bean factory-ref="initi alSchema" factory-method="getSchema" />217 +<bp:bean factory-ref="tableDefinitions" factory-method="getSetup" /> 227 227 </bp:property> 228 - 219 +<!-- ... and continues here --> 229 229 {{/code}} 230 230 231 231 = {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-UpdatingadatabaseschemawithISchemaUpdateSnippet"/}}Updating a database schema with ISchemaUpdateSnippet = ... ... @@ -235,7 +235,7 @@ 235 235 An example for an implementation of a schema update snippet could look like this: 236 236 237 237 {{code language="java"}} 238 -package foo.schema;229 +package org.clazzes.example.jdbc2xml.updates; 239 239 240 240 import java.sql.SQLException; 241 241 import java.sql.Types; ... ... @@ -246,11 +246,15 @@ 246 246 import org.clazzes.jdbc2xml.schema.PrimaryKeyInfo; 247 247 import org.clazzes.jdbc2xml.schema.TableInfo; 248 248 249 -public class SchemaUpdate _0_1_01 implements ISchemaUpdateSnippet {240 +public class SchemaUpdate0_1_01 implements ISchemaUpdateSnippet { 250 250 251 251 // This is only accessed through the getter 252 252 private static final String TARGET_VERSION = "0.1.01"; 253 253 245 +// Here it is also adviseable to define constants for reuse in statements. 246 +public static final String COL_EXAMPLE_GENDER = "GENDER"; 247 + 248 + 254 254 @Override 255 255 public String getTargetVersion() { 256 256 return TARGET_VERSION; ... ... @@ -258,13 +258,13 @@ 258 258 259 259 @Override 260 260 public String getUpdateComment() { 261 -return "Adding column "+ TableDefs.COL_ADDRESSBOOK_GENDER+" to table "+TableDefs.TABLENAME_ADDRESSBOOK+".";256 +return "Adding column "+COL_EXAMPLE_GENDER+" to table "+TableDefinitions.TB_EXAMPLE_TABLE_NAME+"."; 262 262 } 263 263 264 264 @Override 265 265 public void performUpdate(ISchemaEngine schemaEngine) throws SQLException { 266 -TableInfo ti = schemaEngine.fetchTableInfo(TableDefs.T ABLENAME_ADDRESSBOOK, null);267 -schemaEngine.addColumn(ti, new ColumnInfo( TableDefs.COL_ADDRESSBOOK_GENDER, Types.VARCHAR, 1, null, true, null));261 +TableInfo ti = schemaEngine.fetchTableInfo(TableDefinitions.TB_EXAMPLE_TABLE_NAME, null); 262 + schemaEngine.addColumn(ti, new ColumnInfo(COL_EXAMPLE_GENDER, Types.VARCHAR, 1, null, true, null)); 268 268 } 269 269 } 270 270 ... ... @@ -271,7 +271,7 @@ 271 271 272 272 {{/code}} 273 273 274 -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 ADDRESSBOOKtable createdviatheInitialSchemaclass above.269 +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. 275 275 276 276 To add an entire table you would use the {{code language="none"}}ISchemaEngine.createTable(){{/code}} method, like this: 277 277 ... ... @@ -280,12 +280,12 @@ 280 280 public void performUpdate(ISchemaEngine schemaEngine) throws SQLException { 281 281 TableInfo tiGroup = new TableInfo(TB_GROUP); 282 282 tiGroup.setColumns(Arrays.asList(new ColumnInfo[] { 283 - new ColumnInfo(TableDefs.COL_ID, Types.VARCHAR, 36, null, false, null), 284 - new ColumnInfo(TableDefs.COL_NAME, Types.VARCHAR, 100, null, false, null), 285 - new ColumnInfo(TableDefs.COL_DESCRIPTION, Types.VARCHAR, 512, null, true, null) 278 + new ColumnInfo(TableDefinitions.COL_ID, Types.VARCHAR, 36, null, false, null), 279 + new ColumnInfo(TableDefinitions.COL_NAME, Types.VARCHAR, 100, null, false, null), 280 + new ColumnInfo(TableDefinitions.COL_DESCRIPTION, Types.VARCHAR, 512, null, true, null) 286 286 })); 287 - tiGroup.setPrimaryKey(new PrimaryKeyInfo(PK_GROUP, TableDefs.COL_ID)); 288 - tiGroup.setIndices(Arrays.asList(new IndexInfo(IDX_GROUP_01, TableDefs.COL_NAME, true, null))); 282 + tiGroup.setPrimaryKey(new PrimaryKeyInfo(PK_GROUP, TableDefinitions.COL_ID)); 283 + tiGroup.setIndices(Arrays.asList(new IndexInfo(IDX_GROUP_01, TableDefinitions.COL_NAME, true, null))); 289 289 290 290 schemaEngine.createTable(tiGroup, true); 291 291 } ... ... @@ -296,7 +296,7 @@ 296 296 {{code language="java"}} 297 297 @Override 298 298 public void performUpdate(ISchemaEngine schemaEngine) throws SQLException { 299 - String sql = "UPDATE "+TableDefs.TB_EXAMPLE_TABLE_NAME+" SET "+TableDefs.COL_EXAMPLE_NAME+"=?"; 294 + String sql = "UPDATE "+TableDefinitions.TB_EXAMPLE_TABLE_NAME+" SET "+TableDefinitions.COL_EXAMPLE_NAME+"=?"; 300 300 301 301 PreparedStatement ps = schemaEngine.getConnection().prepareStatement(sql); 302 302 ... ... @@ -328,22 +328,22 @@ 328 328 The legacy strategy is: 329 329 330 330 (% style="list-style-type: square;" %) 331 -* At the start of a project, create and use {{code language="none"}}InitalSchema.java{{/code}}332 -* After the first commit, {{code language="none"}}InitalSchema{{/code}}are considered frozen, all changes go into{{code language="none"}}SchemaUpdates{{/code}}, up to one update per source code commit326 +* At the start of a project, create and use TableDefinitions.java 327 +* After the first commit, TableDefinitions are considered frozen, all changes go into SchemaUpdates, up to one update per source code commit 333 333 334 334 Advantage: Rock solid. 335 335 336 -Disadvantage: No place to look for the complete and exact current scheme, except actual databases.{{codelanguage="none"}}TableDefs.java{{/code}} provide someinformation,butmaybecomeconfusinginthe long term.331 +Disadvantage: No place to look for the complete current scheme, except actual databases. See //Recommendation 1// below for a workaround. 337 337 338 338 === {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-Possiblebutdangerous:Evolving(Initial)TableList"/}}Possible but dangerous: Evolving (Initial) Table List === 339 339 340 -To keep the (Initial)Schemaup do date, one might use this strategy:335 +To keep the TableDefinitions up do date, one might use this strategy: 341 341 342 342 (% style="list-style-type: square;" %) 343 -* keep the {{code language="none"}}InitalSchema{{/code}}up to date, so an empty database always gets the current scheme in one shot344 -* {{code language="none"}}SchemaUpdates{{/code}}are only applied to existing databases338 +* keep the TableDefinitions up to date, so an empty database always gets the current scheme in one shot 339 +* SchemaUpdates are only applied to existing databases 345 345 346 -Advantage: Immediate overview over exact current scheme.341 +Advantage: Immediate overview over current scheme. 347 347 348 348 Disadvantage: Very real danger of messing something up, because 349 349 ... ... @@ -351,16 +351,22 @@ 351 351 * schema updates have to be coded in 2 different places in 2 different ways 352 352 * the bean definition has to be maintained in 2 places but just 1 353 353 354 -Conclusion: **DO NOT DO THIS**. This strategy may be ok in very early stages, but at some point it has to be349 +Conclusion: DO NOT DO THIS. This strategy may be ok in very early stages, but at some point it has to be 355 355 356 -=== {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-Recommendation: FreezeInitialTableDefinitionnotlaterthanthefirstReleaseCandidate(RC)"/}}(% style="font-size: 14.0pt;" %)Recommendation:Freeze InitialTableDefinitionnotlater thanthe firstReleaseCandidate(RC)(%%)===351 +=== {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-Recommendation1:SplitTableDefinitionsfrominitialTableList"/}}Recommendation 1: Split TableDefinitions from initial Table List === 357 357 353 +If TableDefinitions (pseudo constants for table and column names) go in a dedicated pseudo class it can serve as good overview over the database structure. 354 + 355 +=== {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-Recommendation2:FreezeTableDefinition,notafterRC/1.0/GA"/}}Recommendation 2: (% style="font-size: 14.0pt;" %)Freeze Table Definition, not after RC/1.0/GA(%%) === 356 + 358 358 It may be ok to start a new project using a fast changing (% style="font-size: 10.0pt;line-height: 13.0pt;" %)(Initial) Table List. 359 359 360 360 (% style="font-size: 10.0pt;line-height: 13.0pt;" %)But, please, freeze it at some point. Once the first test server is setup up, internally or at a friendly customer, the Frozen Initial Table List Strategy is the only valid one! 361 361 362 - ={{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-RealworldExample"/}}Real world Example =361 + 363 363 364 - ThisHowTo is currently evolving while an additional developer gets acostumed to the SchemaEngine, for developing [[SDS' org.clazzes.sds.impl.schema package>>url:http://svn.clazzes.org/svn/sds/trunk/sds.impl/src/main/java/org/clazzes/sds/impl/schema||style="font-size: 10.0pt;line-height: 13.0pt;" shape="rect"]](% style="font-size: 10.0pt;line-height: 13.0pt;" %) which is **work in progress**!363 + 365 365 366 -(% style="font-size: 10.0pt;line-height: 13.0pt;" %)\\ 365 + 366 + 367 +
- Confluence.Code.ConfluencePageClass[0]
-
- Id
-
... ... @@ -1,1 +1,1 @@ 1 -656 7981 +656817 - URL
-
... ... @@ -1,1 +1,1 @@ 1 -https://clazzes.atlassian.net/wiki/spaces/JDBC2XML/pages/656 798/How To create and update Databases using SchemaManager and SchemaUpdateSnippets1 +https://clazzes.atlassian.net/wiki/spaces/JDBC2XML/pages/656817/How To create and update Databases using SchemaManager and SchemaUpdateSnippets