Wiki source code of How To create and update Databases using SchemaManager and SchemaUpdateSnippets
Version 2.1 by 5fbc055b7cc103006957e1ae on 2012-06-14 06.29:38
Show last authors
| author | version | line-number | content |
|---|---|---|---|
| 1 | = {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-Preliminary"/}}Preliminary = | ||
| 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, relations and data in the database 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. | ||
| 4 | |||
| 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 | |||
| 7 | {{code language="none"}} | ||
| 8 | VERSION:varchar(10), not null, primary key | ||
| 9 | DESCRIPTION:varchar(512), nullable | ||
| 10 | CREATION_DATE:date, nullable | ||
| 11 | SERIALNR:integer(5), not null | ||
| 12 | {{/code}} | ||
| 13 | |||
| 14 | = {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-ProjectConfiguration"/}}Project Configuration = | ||
| 15 | |||
| 16 | To function 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}}). | ||
| 17 | |||
| 18 | Optionally, you may set the base version (default value 0.1.00) and base description String (default "initial database schema"). | ||
| 19 | |||
| 20 | Database updates are passed as a Map<String, ISchemaUpdateSnippet> (org.clazzes.jdbc2xml.schema.ISchemaUpdateSnippet) - details see below. | ||
| 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"}} | ||
| 29 | <bp:reference id="dialectFactory" interface="org.clazzes.jdbc2xml.schema.IDialectFactory"> | ||
| 30 | </bp:reference> | ||
| 31 | |||
| 32 | <bp:reference id="schemaEngineFactory" interface="org.clazzes.jdbc2xml.schema.ISchemaEngineFactory"> | ||
| 33 | </bp:reference> | ||
| 34 | |||
| 35 | <bp:bean id="sqlDialect" factory-ref="dialectFactory" factory-method="newDialect"> | ||
| 36 | <bp:argument> <!-- Pass JDBC URL as an argument --> | ||
| 37 | </bp:argument> | ||
| 38 | </bp:bean> | ||
| 39 | |||
| 40 | <bp:bean id="schemaEngine" factory-ref="schemaEngineFactory" factory-method="newSchemaEngine"> | ||
| 41 | <bp:property name="dialect" ref="sqlDialect"> | ||
| 42 | </bp:property> | ||
| 43 | </bp:bean> | ||
| 44 | |||
| 45 | <bp:bean id="databaseSetup" class="org.clazzes.jdbc2xml.schema.SchemaManager" init-method="start"> | ||
| 46 | <bp:property name="dataSource" ref="dataSource"></bp:property> | ||
| 47 | <bp:property name="schemaEngine" ref="schemaEngine"></bp:property> | ||
| 48 | <bp:property name="baseVersion" value="0.1.00" /> | ||
| 49 | <bp:property name="baseTables"> | ||
| 50 | <!-- Add List of TableDefinitions here --> | ||
| 51 | </bp:property> | ||
| 52 | <bp:property name="upateSnippets"> | ||
| 53 | <!-- Add Update-Snippets here --> | ||
| 54 | </bp:property> | ||
| 55 | </bp:bean> | ||
| 56 | {{/code}} | ||
| 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 | ||
| 79 | constants, so they can be reused to build sql-statements */ | ||
| 80 | public static final String TB_EXAMPLE_TABLE_NAME = "ADDRESSBOOK"; | ||
| 81 | public static final String COL_EXAMPLE_ID = "ID"; | ||
| 82 | public static final String COL_EXAMPLE_NAME = "NAME"; | ||
| 83 | public static final String COL_EXAMPLE_ADDRESS_REF = "ADDRESS"; | ||
| 84 | public static final String COL_EXAMPLE_BIRTHDAY = "BIRTHDAY"; | ||
| 85 | |||
| 86 | /* ... */ | ||
| 87 | |||
| 88 | private List<TableInfo> setup; | ||
| 89 | |||
| 90 | public TableDefinitions() { | ||
| 91 | /* Create a table */ | ||
| 92 | TableInfo exampleTable = new TableInfo(TB_EXAMPLE_TABLE_NAME); | ||
| 93 | exampleTable.setColumns( | ||
| 94 | Arrays.asList(new ColumnInfo[] { | ||
| 95 | new ColumnInfo(COL_EXAMPLE_ID, Types.BIGINT, 20, null, false, null,true), | ||
| 96 | new ColumnInfo(COL_EXAMPLE_NAME, Types.VARCHAR, 256, null, false, null), | ||
| 97 | new ColumnInfo(COL_EXAMPLE_ADDRESS_REF, Types.BIGINT, 20, null, true, null), | ||
| 98 | new ColumnInfo(COL_EXAMPLE_BIRTHDAY, Types.DATE, 12, null, false, null) | ||
| 99 | })); | ||
| 100 | |||
| 101 | /* Example for creating a foreign key reference */ | ||
| 102 | exampleTable.setForeignKeys(Arrays.asList(new ForeignKeyInfo[] { | ||
| 103 | new ForeignKeyInfo("FK_EXAMPLE_ADDRESS", COL_EXAMPLE_ADDRESS_REF, TB_ADDRESS, COL_ADDRESS_ID) | ||
| 104 | })); | ||
| 105 | |||
| 106 | /* Example for creating a primary key */ | ||
| 107 | exampleTable.setPrimaryKey( | ||
| 108 | new PrimaryKeyInfo("PK_EXAMPLE", COL_EXAMPLE_ID) | ||
| 109 | ); | ||
| 110 | |||
| 111 | /* ... */ | ||
| 112 | |||
| 113 | this.setup = Arrays.asList( | ||
| 114 | exampleTable, | ||
| 115 | /* ... */ | ||
| 116 | ); | ||
| 117 | |||
| 118 | } | ||
| 119 | |||
| 120 | public List<TableInfo> getSetup() { | ||
| 121 | return this.setup; | ||
| 122 | } | ||
| 123 | |||
| 124 | } | ||
| 125 | {{/code}} | ||
| 126 | |||
| 127 | You must inject {{code language="none"}}TableDefinitions.getSetup(){{/code}} into {{code language="none"}}SchemaManager.setBaseTables(){{/code}} before calling {{code language="none"}}SchemaManager.start(){{/code}}. | ||
| 128 | |||
| 129 | Using Blueprint/Spring, you can do this with the following snippet: | ||
| 130 | |||
| 131 | {{code language="none"}} | ||
| 132 | |||
| 133 | {{/code}} | ||
| 134 | |||
| 135 | = {{id name="HowTocreateandupdateDatabasesusingSchemaManagerandSchemaUpdateSnippets-UpdatingadatabaseschemawithSchemaUpdateSnippets"/}}Updating a database schema with SchemaUpdateSnippets = | ||
| 136 | |||
| 137 | 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. | ||
| 138 | |||
| 139 | |||
| 140 | |||
| 141 | |||
| 142 | |||
| 143 | |||
| 144 | |||
| 145 | |||
| 146 | |||
| 147 | |||
| 148 | |||
| 149 | |||
| 150 | |||
| 151 | |||
| 152 | |||
| 153 |