You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@empire-db.apache.org by do...@apache.org on 2015/09/25 12:25:38 UTC

[1/2] empire-db git commit: EMPIREDB-227 Spring JDBC Template contributed by Ivan Nemeth

Repository: empire-db
Updated Branches:
  refs/heads/master cedc9788e -> 20ecbae8b


http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeDaoImpl.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeDaoImpl.java b/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeDaoImpl.java
new file mode 100644
index 0000000..7a384f9
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeDaoImpl.java
@@ -0,0 +1,225 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring.example2;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.empire.db.DBCommand;
+import org.apache.empire.db.DBJoinType;
+import org.apache.empire.db.DBRecord;
+import org.apache.empire.db.DBRecordData;
+import org.apache.empire.spring.EmpireDaoSupport;
+import org.apache.empire.spring.EmpireDataReader;
+import org.apache.empire.spring.EmpireRecord;
+import org.apache.empire.spring.EmpireRecordWriter;
+import org.apache.empire.spring.example1.SampleDB;
+import org.apache.empire.spring.example1.SampleDB.Departments;
+import org.apache.empire.spring.example1.SampleDB.Employees;
+import org.springframework.transaction.annotation.Transactional;
+
+public class EmployeeDaoImpl extends EmpireDaoSupport implements EmployeeDao {
+
+	private Employees EMPLOYEES;
+	private Departments DEPARTMENTS;
+
+	@Override
+	protected void initEmpireDao() {
+		SampleDB db = getDatabase();
+		this.EMPLOYEES = db.EMPLOYEES;
+		this.DEPARTMENTS = db.DEPARTMENTS;
+	}
+
+	private DBCommand createEmployeeSelectCommand() {
+		DBCommand cmd = getDatabase().createCommand();
+		cmd.select(EMPLOYEES.getColumns());
+		cmd.select(DEPARTMENTS.getColumns());
+
+		cmd.join(EMPLOYEES.DEPARTMENT_ID, DEPARTMENTS.DEPARTMENT_ID, DBJoinType.INNER);
+		return cmd;
+	}
+
+	private DBCommand createDepartmentSelectCommand() {
+		DBCommand cmd = getDatabase().createCommand();
+		cmd.select(DEPARTMENTS.getColumns());
+		return cmd;
+	}
+
+	@Transactional(readOnly = true)
+	public Employee openEmployee(Integer id) {
+		DBCommand cmd = createEmployeeSelectCommand();
+		cmd.where(EMPLOYEES.EMPLOYEE_ID.is(id));
+		return getEmpireTemplate().queryForObject(cmd, new EmployeeMapper());
+	}
+
+	@Transactional(readOnly = true)
+	public Employee findEmployee(String firstName, String lastName) {
+		DBCommand cmd = createEmployeeSelectCommand();
+		cmd.where(EMPLOYEES.FIRSTNAME.is(firstName));
+		cmd.where(EMPLOYEES.LASTNAME.is(lastName));
+		return getEmpireTemplate().queryForObject(cmd, new EmployeeMapper());
+	}
+	
+	@Transactional(readOnly = true)
+	public Department openDepartment(Integer id) {
+		DBCommand cmd = createDepartmentSelectCommand();
+		cmd.where(DEPARTMENTS.DEPARTMENT_ID.is(id));
+		return getEmpireTemplate().queryForObject(cmd, new DepartmentMapper());
+	}
+
+	@Transactional(readOnly = true)
+	public Department findDepartment(String name) {
+		DBCommand cmd = createDepartmentSelectCommand();
+		cmd.where(DEPARTMENTS.NAME.is(name));
+		return getEmpireTemplate().queryForObject(cmd, new DepartmentMapper());
+	}
+
+	@Transactional
+	public void renameDepartment(Integer id, String name) {
+		DBCommand cmd = getDatabase().createCommand();
+		cmd.where(DEPARTMENTS.DEPARTMENT_ID.is(id));
+		cmd.set(DEPARTMENTS.NAME.to(name));
+		getEmpireTemplate().executeUpdate(cmd);
+	}
+
+	@Transactional(readOnly = true)
+	public List<Employee> getEmployees() {
+		DBCommand cmd = createEmployeeSelectCommand();
+		return getEmpireTemplate().query(cmd, new EmployeeMapper());
+	}
+
+	@Transactional
+	public Integer createEmployee(Employee employee) {
+		DBRecord record = new EmpireRecord();
+		record.create(EMPLOYEES);
+		new EmployeeWriter().write(record, employee);
+		getEmpireTemplate().updateRecord(record);
+		return record.getInt(EMPLOYEES.EMPLOYEE_ID);
+	}
+
+	@Transactional
+	public void updateEmployee(Employee employee) {
+		DBRecord record = getEmpireTemplate().openRecord(EMPLOYEES, employee.getEmployeeId());
+		new EmployeeWriter().write(record, employee);
+		getEmpireTemplate().updateRecord(record);
+	}
+
+	@Transactional
+	public Integer createDepartment(Department department) {
+		DBRecord record = new EmpireRecord();
+		record.create(DEPARTMENTS);
+		new DepartmentWriter().write(record, department);
+		getEmpireTemplate().updateRecord(record);
+		return record.getInt(DEPARTMENTS.DEPARTMENT_ID);
+	}
+
+	@Transactional
+	public void updateDepartment(Department department) {
+		DBRecord record = getEmpireTemplate().openRecord(DEPARTMENTS, department.getDepartmentId());
+		new DepartmentWriter().write(record, department);
+		getEmpireTemplate().updateRecord(record);
+	}
+
+	private class EmployeeMapper implements EmpireDataReader<Employee> {
+
+		DepartmentMapper departmentMapper = new DepartmentMapper();
+
+        @Override
+		public Employee read(DBRecordData record) {
+			Employee result = new Employee();
+            // Auto-copy all properties
+			record.getBeanProperties(result);
+			/*
+			result.setEmployeeId(record.getInt(EMPLOYEES.EMPLOYEE_ID));
+			result.setFirstName(record.getString(EMPLOYEES.FIRSTNAME));
+			result.setLastName(record.getString(EMPLOYEES.LASTNAME));
+			result.setGender(Employee.Gender.valueOf(record.getString(EMPLOYEES.GENDER)));
+			result.setPhoneNumber(record.getString(EMPLOYEES.PHONE_NUMBER));
+			*/
+			result.setDepartment(departmentMapper.read(record));
+			return result;
+		}
+
+	}
+
+	private class EmployeeWriter implements EmpireRecordWriter<Employee> {
+
+        @Override
+		public void write(DBRecord record, Employee entity) {
+			// Auto-copy all properties
+		    record.setBeanValues(entity);
+			/*
+		    record.setValue(EMPLOYEES.EMPLOYEE_ID, entity.getEmployeeId());
+			record.setValue(EMPLOYEES.FIRSTNAME, entity.getFirstName());
+			record.setValue(EMPLOYEES.LASTNAME, entity.getLastName());
+			record.setValue(EMPLOYEES.GENDER, entity.getGender().name());
+			record.setValue(EMPLOYEES.PHONE_NUMBER, entity.getPhoneNumber());
+			*/
+			record.setValue(EMPLOYEES.DEPARTMENT_ID, entity.getDepartment().getDepartmentId());
+		}
+
+	}
+
+	private class DepartmentMapper implements EmpireDataReader<Department> {
+
+		// reader cache, in case of joined resultset the same object is returned
+
+		Map<Integer, Department> cache = new HashMap<Integer, Department>();
+
+        @Override
+		public Department read(DBRecordData record) {
+
+			Integer id = record.getInt(DEPARTMENTS.DEPARTMENT_ID);
+
+			Department department = cache.get(id);
+			if (department == null) {
+				department = new Department();
+                // Auto-copy all properties
+				record.getBeanProperties(department);
+				/*
+				department.setDepartmentId(id);
+				department.setName(record.getString(DEPARTMENTS.NAME));
+				department.setHead(record.getString(DEPARTMENTS.HEAD));
+				department.setBusinessUnit(record.getString(DEPARTMENTS.BUSINESS_UNIT));
+				*/		
+				cache.put(id, department);
+			}
+			return department;
+		}
+
+	}
+
+	private class DepartmentWriter implements EmpireRecordWriter<Department> {
+
+		@Override
+        public void write(DBRecord record, Department entity) {
+            // Auto-copy all properties
+		    record.setBeanValues(entity);
+		    /*
+			record.setValue(DEPARTMENTS.DEPARTMENT_ID, entity.getDepartmentId());
+			record.setValue(DEPARTMENTS.NAME, entity.getName());
+			record.setValue(DEPARTMENTS.HEAD, entity.getHead());
+			record.setValue(DEPARTMENTS.BUSINESS_UNIT, entity.getBusinessUnit());
+			*/
+		}
+
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeSpringApp.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeSpringApp.java b/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeSpringApp.java
new file mode 100644
index 0000000..90d964a
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeSpringApp.java
@@ -0,0 +1,220 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring.example2;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Logger;
+
+import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.db.DBCommand;
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBDatabaseDriver;
+import org.apache.empire.db.DBSQLScript;
+import org.apache.empire.db.DBTable;
+import org.apache.empire.spring.EmpireTemplate;
+import org.apache.empire.spring.example1.SampleDB;
+import org.apache.empire.spring.example2.Employee.Gender;
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.ConnectionCallback;
+
+/**
+ * 
+ */
+public class EmployeeSpringApp {
+    private static final Logger log = Logger.getLogger(EmployeeSpringApp.class.getName());
+
+    //creates the application context
+    //this is usually in some bootstrapping code; so your application will
+    //just have one at runtime.
+    static ApplicationContext ctx = getContext();
+
+    //get the service that is the entry point into the application
+    //normally this is injected by spring into classes that need it
+    static EmployeeDao employeeDao = ctx.getBean("employeeDao", EmployeeDao.class);
+    static SampleDB sampleDb = ctx.getBean("sampleDb", SampleDB.class);
+
+    public static void main(String[] args) throws Exception {
+
+        System.out.println("Running Spring Example...");
+
+        setupDatabase();
+        clearDatabase();
+        
+        Department depDevelopment, depSales;
+        
+        System.out.println("*** Create Departments ***");
+        
+        {
+        	depDevelopment = new Department();
+        	depDevelopment.setName("Development");
+        	depDevelopment.setBusinessUnit("ITTK");
+        	Integer id = employeeDao.createDepartment(depDevelopment);
+        	depDevelopment = employeeDao.openDepartment(id);
+        }
+        {
+        	depSales = new Department();
+        	depSales.setName("Sales");
+        	depSales.setBusinessUnit("ITTK");
+        	Integer id = employeeDao.createDepartment(depSales);
+        	depSales = employeeDao.openDepartment(id);
+        }
+        
+        System.out.println("*** Create Employees ***");
+
+        Employee peter = new Employee();
+        peter.setFirstName("Peter");
+        peter.setLastName("Sharp");
+        peter.setGender(Gender.M);
+        peter.setDepartment(depDevelopment);
+        
+        Integer peterId = employeeDao.createEmployee(peter);
+        peter = employeeDao.openEmployee(peterId);
+        
+        
+        
+        Employee fred = new Employee();
+        fred.setFirstName("Fred");
+        fred.setLastName("Bloggs");
+        fred.setGender(Gender.M);
+        fred.setDepartment(depDevelopment);
+
+        Integer fredId = employeeDao.createEmployee(fred);
+        fred = employeeDao.openEmployee(fredId);
+
+        
+        Employee emma = new Employee();
+        emma.setFirstName("Emma");
+        emma.setLastName("White");
+        emma.setGender(Gender.F);
+        emma.setDepartment(depSales);
+        
+        Integer emmaId = employeeDao.createEmployee(emma);
+        emma = employeeDao.openEmployee(emmaId);
+        
+
+        System.out.println("*** updateEmployees ***");
+        
+        peter.setPhoneNumber("+49-7531-457160");
+        employeeDao.updateEmployee(peter);
+        
+        fred.setPhoneNumber("+49-5555-505050");
+        employeeDao.updateEmployee(fred);
+        
+        emma.setPhoneNumber("+49-040-125486");
+        employeeDao.updateEmployee(emma);
+
+        System.out.println("*** List employees ***");
+        
+        List<Employee> employees = employeeDao.getEmployees();
+        for (Iterator<Employee> iterator = employees.iterator(); iterator.hasNext();) {
+			Employee employee = iterator.next();
+			System.out.println(employee);
+		}
+        
+        
+    }
+
+    private static void clearDatabase() {
+        // Delete all Employees (no constraints)
+        
+        EmpireTemplate empireTemplate = ctx.getBean("empireTemplate", EmpireTemplate.class);
+        empireTemplate.executeDelete(sampleDb.EMPLOYEES, sampleDb.createCommand());
+        empireTemplate.executeDelete(sampleDb.DEPARTMENTS, sampleDb.createCommand());
+		
+	}
+
+
+
+
+	public static void setupDatabase() {
+		if (!databaseExists()) {
+			createDatabase();
+		}
+	}
+	
+
+	public static boolean databaseExists() {
+		try {
+			DBDatabase db = sampleDb;
+			if (db.getTables() == null || db.getTables().isEmpty()) {
+				throw new AssertionError(
+						"There are no tables in this database!");
+			}
+			DBCommand cmd = db.createCommand();
+			if (cmd == null) {
+				throw new AssertionError("The DBCommand object is null.");
+			}
+			DBTable t = db.getTables().get(0);
+			DBColumnExpr COUNT = t.count();
+			
+			cmd.select(COUNT);
+			
+			EmpireTemplate empireTemplate = ctx.getBean("empireTemplate", EmpireTemplate.class);
+			return (empireTemplate.queryForInteger(cmd, COUNT, -1) >= 0);
+		} catch (Exception e) {
+			return false;
+		}
+	}
+
+
+	private static void createDatabase() {
+
+		// create DLL for Database Definition
+		final DBSQLScript script = new DBSQLScript();
+		final DBDatabaseDriver driver = sampleDb.getDriver();
+		sampleDb.getCreateDDLScript(driver, script);
+
+		// Show DLL Statement
+		System.out.println(script.toString());
+		// Execute Script
+		EmpireTemplate empireTemplate = ctx.getBean("empireTemplate", EmpireTemplate.class);
+		empireTemplate.execute(new ConnectionCallback<Object>() {
+
+			@Override
+            public Object doInConnection(Connection con) throws SQLException,
+					DataAccessException {
+        				script.executeAll(driver, con, false);
+        				return null;
+        			}
+		});
+
+	}
+
+
+
+	static GenericApplicationContext getContext() {
+        log.info("Creating Spring Application Context ...");
+        GenericApplicationContext ctx = new GenericApplicationContext();
+        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(ctx);
+        reader.loadBeanDefinitions(new ClassPathResource("/example2/applicationContext-employee.xml"));
+
+        ctx.refresh();
+        return ctx;
+    }
+    
+    
+    
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/resources/example1/applicationContext.xml
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/resources/example1/applicationContext.xml b/empire-db-spring/src/main/resources/example1/applicationContext.xml
new file mode 100644
index 0000000..56b0699
--- /dev/null
+++ b/empire-db-spring/src/main/resources/example1/applicationContext.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+   http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="
+       	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
+		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+
+    <!-- one option is to use a class from spring that will read the properties file
+         and replaces the ${...} placeholders with the appropriate values -->
+    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+        <property name="locations">
+            <value>classpath:/settings.properties</value>
+        </property>
+    </bean>
+
+    <!-- Data Source / DB Settings -->
+    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
+        <property name="driverClassName" value="${jdbc.driverClass}"/>
+        <property name="url" value="${jdbc.url}"/>
+        <property name="username" value="${jdbc.username}"/>
+        <property name="password" value="${jdbc.password}"/>
+    </bean>
+
+    <!-- Transaction manager for a single JDBC DataSource (alternative to JTA) -->
+    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
+        <constructor-arg ref="dataSource"/>
+    </bean>
+    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
+        <property name="transactionManager" ref="transactionManager"/>
+    </bean>
+
+    <!-- @Transactional -->
+    <tx:annotation-driven transaction-manager="transactionManager"/>
+
+    <!-- Empire-DB classes -->
+    
+    <!-- application dao/services -->
+    <bean id="empireApp" class="org.apache.empire.spring.example1.EmpireAppImpl" parent="empireDao"/>
+
+    
+    <bean id="empireDb" class="org.apache.empire.spring.DbDatabaseFactoryBean">
+    	<property name="driverClass" value="${empire.driver}"/>
+    	<property name="schema" value="${empire.schemaname}"/>
+    	<property name="databaseClass" value="org.apache.empire.spring.example1.SampleDB"/>
+    </bean>
+    
+    <bean id="empireDao" abstract="true">
+    	<property name="database" ref="empireDb"/>
+    	<property name="dataSource" ref="dataSource"/>
+    </bean>
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/resources/example2/applicationContext-employee.xml
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/resources/example2/applicationContext-employee.xml b/empire-db-spring/src/main/resources/example2/applicationContext-employee.xml
new file mode 100644
index 0000000..349122d
--- /dev/null
+++ b/empire-db-spring/src/main/resources/example2/applicationContext-employee.xml
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+  
+   http://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing,
+  software distributed under the License is distributed on an
+  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  KIND, either express or implied.  See the License for the
+  specific language governing permissions and limitations
+  under the License.
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:tx="http://www.springframework.org/schema/tx"
+       xmlns:aop="http://www.springframework.org/schema/aop"
+       xsi:schemaLocation="
+       	http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
+       	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
+		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">
+
+
+    <!-- one option is to use a class from spring that will read the properties file
+         and replaces the ${...} placeholders with the appropriate values -->
+    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
+        <property name="locations">
+            <value>classpath:/settings.properties</value>
+        </property>
+    </bean>
+
+    <!-- Data Source / DB Settings -->
+    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
+        <property name="driverClassName" value="${jdbc.driverClass}"/>
+        <property name="url" value="${jdbc.url}"/>
+        <property name="username" value="${jdbc.username}"/>
+        <property name="password" value="${jdbc.password}"/>
+    </bean>
+
+    <!-- Transaction manager for a single JDBC DataSource (alternative to JTA) -->
+    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
+        <constructor-arg ref="dataSource"/>
+    </bean>
+    <bean id="transactionTemplate" class="org.springframework.transaction.support.TransactionTemplate">
+        <property name="transactionManager" ref="transactionManager"/>
+    </bean>
+
+    <!-- @Transactional -->
+    <tx:annotation-driven transaction-manager="transactionManager"/>
+
+    <!-- Empire-DB classes -->
+    
+    <!-- application dao/services -->
+    <bean id="employeeDao" class="org.apache.empire.spring.example2.EmployeeDaoImpl" parent="empireDao"/>
+
+    
+    <bean id="sampleDb" class="org.apache.empire.spring.DbDatabaseFactoryBean">
+    	<property name="driverClass" value="${empire.driver}"/>
+    	<property name="schema" value="${empire.schemaname}"/>
+    	<property name="databaseClass" value="org.apache.empire.spring.example1.SampleDB"/>
+    </bean>
+    
+    <bean id="empireDao" abstract="true">
+    	<property name="database" ref="sampleDb"/>
+    	<property name="dataSource" ref="dataSource"/>
+    </bean>
+    
+    
+    <bean id="empireTemplate" class="org.apache.empire.spring.EmpireTemplate">
+    	<property name="dataSource" ref="dataSource"/>
+    </bean>
+    
+    
+    
+    
+    
+    
+    
+</beans>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/resources/log4j.properties b/empire-db-spring/src/main/resources/log4j.properties
new file mode 100644
index 0000000..031ae65
--- /dev/null
+++ b/empire-db-spring/src/main/resources/log4j.properties
@@ -0,0 +1,21 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+log4j.rootCategory=FATAL, console
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.conversionPattern = %d{ISO8601} %-5p [%c] - %m%n

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/resources/settings.properties
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/resources/settings.properties b/empire-db-spring/src/main/resources/settings.properties
new file mode 100644
index 0000000..e5ba794
--- /dev/null
+++ b/empire-db-spring/src/main/resources/settings.properties
@@ -0,0 +1,44 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+## HSQLDB settings (tested)
+jdbc.url=jdbc:hsqldb:file:target/hsqldb/sample;shutdown=true
+jdbc.driverClass=org.hsqldb.jdbcDriver
+jdbc.username=sa
+jdbc.password=
+
+empire.driver= org.apache.empire.db.hsql.DBDatabaseDriverHSql
+empire.schemaname=
+
+
+## Derby settings (tested)
+#jdbc.url=jdbc:derby:target/dbsample1;create=true
+#jdbc.driverClass=org.apache.derby.jdbc.EmbeddedDriver
+#jdbc.username=
+#jdbc.password=
+#
+#empire.driver=org.apache.empire.db.derby.DBDatabaseDriverDerby
+#empire.schemaname=DBSAMPLE1
+
+## MySQL settings (tested)
+#jdbc.url=jdbc:mysql://localhost
+#jdbc.driverClass=com.mysql.jdbc.Driver
+#jdbc.username=test
+#jdbc.password=test
+#
+#empire.driver=org.apache.empire.db.mysql.DBDatabaseDriverMySQL
+#empire.schemaname=dbsample1

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 672948d..997fb6a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -38,6 +38,7 @@
 		<module>empire-db-jsf2</module>
 		<module>empire-db-codegen</module>
 		<module>empire-db-maven-plugin</module>
+		<module>empire-db-spring</module>
 		<module>empire-db-examples</module>
 	</modules>
 	


[2/2] empire-db git commit: EMPIREDB-227 Spring JDBC Template contributed by Ivan Nemeth

Posted by do...@apache.org.
EMPIREDB-227
Spring JDBC Template
contributed by Ivan Nemeth

Project: http://git-wip-us.apache.org/repos/asf/empire-db/repo
Commit: http://git-wip-us.apache.org/repos/asf/empire-db/commit/20ecbae8
Tree: http://git-wip-us.apache.org/repos/asf/empire-db/tree/20ecbae8
Diff: http://git-wip-us.apache.org/repos/asf/empire-db/diff/20ecbae8

Branch: refs/heads/master
Commit: 20ecbae8b347846cc9ba6c26324ecfac339af35c
Parents: cedc978
Author: Rainer Döbele <do...@apache.org>
Authored: Fri Sep 25 12:25:31 2015 +0200
Committer: Rainer Döbele <do...@apache.org>
Committed: Fri Sep 25 12:25:31 2015 +0200

----------------------------------------------------------------------
 empire-db-spring/pom.xml                        |  47 +++
 .../empire/spring/DbDatabaseFactoryBean.java    | 137 ++++++++
 .../apache/empire/spring/EmpireDaoSupport.java  |  91 +++++
 .../apache/empire/spring/EmpireDataReader.java  |  27 ++
 .../empire/spring/EmpireDriverFactory.java      | 101 ++++++
 .../empire/spring/EmpireIntegerValueReader.java |  39 +++
 .../empire/spring/EmpireLongValueReader.java    |  39 +++
 .../org/apache/empire/spring/EmpireReader.java  | 104 ++++++
 .../empire/spring/EmpireReaderExtractor.java    |  27 ++
 .../org/apache/empire/spring/EmpireRecord.java  |  68 ++++
 .../empire/spring/EmpireRecordWriter.java       |  28 ++
 .../empire/spring/EmpireRowCallbackHandler.java |  27 ++
 .../empire/spring/EmpireStringValueReader.java  |  37 ++
 .../apache/empire/spring/EmpireTemplate.java    | 301 +++++++++++++++++
 .../apache/empire/spring/EmpireValueReader.java |  37 ++
 .../empire/spring/example1/EmpireApp.java       |  47 +++
 .../empire/spring/example1/EmpireAppImpl.java   | 337 +++++++++++++++++++
 .../empire/spring/example1/SampleBean.java      | 126 +++++++
 .../apache/empire/spring/example1/SampleDB.java | 148 ++++++++
 .../empire/spring/example1/SampleSpringApp.java |  86 +++++
 .../empire/spring/example2/Department.java      |  90 +++++
 .../apache/empire/spring/example2/Employee.java | 140 ++++++++
 .../empire/spring/example2/EmployeeDao.java     |  45 +++
 .../empire/spring/example2/EmployeeDaoImpl.java | 225 +++++++++++++
 .../spring/example2/EmployeeSpringApp.java      | 220 ++++++++++++
 .../resources/example1/applicationContext.xml   |  83 +++++
 .../example2/applicationContext-employee.xml    |  85 +++++
 .../src/main/resources/log4j.properties         |  21 ++
 .../src/main/resources/settings.properties      |  44 +++
 pom.xml                                         |   1 +
 30 files changed, 2808 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/pom.xml
----------------------------------------------------------------------
diff --git a/empire-db-spring/pom.xml b/empire-db-spring/pom.xml
new file mode 100644
index 0000000..815d675
--- /dev/null
+++ b/empire-db-spring/pom.xml
@@ -0,0 +1,47 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+	<modelVersion>4.0.0</modelVersion>
+	<parent>
+		<artifactId>empire-db-parent</artifactId>
+		<groupId>org.apache.empire-db</groupId>
+		<version>2.4.5-SNAPSHOT</version>
+	</parent>
+	<artifactId>empire-db-spring</artifactId>
+	<name>Apache Empire-db Spring JDBC Template</name>
+	<description>Implementation of Spring JDBC Template with Empire-db.</description>
+
+    <properties>
+        <spring.version>4.2.1.RELEASE</spring.version>
+    </properties>
+	
+	<dependencies>
+
+		<dependency>
+			<groupId>org.apache.empire-db</groupId>
+			<artifactId>empire-db</artifactId>
+		</dependency>
+		<dependency>
+		    <groupId>hsqldb</groupId>
+		    <artifactId>hsqldb</artifactId>
+		</dependency> 
+
+		<dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${spring.version}</version>
+        </dependency>
+	
+		<dependency>
+			<groupId>org.springframework</groupId>
+			<artifactId>spring-jdbc</artifactId>
+            <version>${spring.version}</version>
+		</dependency>
+
+        <dependency>
+            <groupId>commons-dbcp</groupId>
+            <artifactId>commons-dbcp</artifactId>
+            <version>1.2.2</version>
+        </dependency>
+		
+	</dependencies>
+</project>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/DbDatabaseFactoryBean.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/DbDatabaseFactoryBean.java b/empire-db-spring/src/main/java/org/apache/empire/spring/DbDatabaseFactoryBean.java
new file mode 100644
index 0000000..6bb5648
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/DbDatabaseFactoryBean.java
@@ -0,0 +1,137 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBDatabaseDriver;
+import org.springframework.beans.factory.FactoryBean;
+import org.springframework.beans.factory.InitializingBean;
+
+public class DbDatabaseFactoryBean implements FactoryBean<DBDatabase>,
+		InitializingBean {
+
+	private boolean singleton = true;
+
+	private DBDatabase singletonInstance;
+	private String schema;
+	private String linkName;
+	private DBDatabaseDriver driver;
+	private boolean preparedStatementsEnabled = true;
+	private Class<? extends DBDatabase> databaseClass = null;
+	private boolean earlyOpen = true;
+
+	private Class<DBDatabaseDriver> driverClass;
+
+	public final void setSingleton(boolean singleton) {
+		this.singleton = singleton;
+	}
+
+	public void setDatabaseClass(Class<? extends DBDatabase> databaseClass) {
+		this.databaseClass = databaseClass;
+	}
+
+	public void setEarlyOpen(boolean earlyOpen) {
+		this.earlyOpen = earlyOpen;
+	}
+
+	public void setSchema(String schema) {
+		this.schema = schema;
+	}
+
+	public void setLinkName(String linkName) {
+		this.linkName = linkName;
+	}
+
+	public void setDriver(DBDatabaseDriver driver) {
+		this.driver = driver;
+	}
+	
+	public void setDriverClass(Class<DBDatabaseDriver> driverClass) {
+		this.driverClass = driverClass;
+	}
+
+
+	public void setPreparedStatementsEnabled(boolean preparedStatementsEnabled) {
+		this.preparedStatementsEnabled = preparedStatementsEnabled;
+	}
+
+	public DBDatabase getObject() throws Exception {
+		if (this.singleton) {
+			return this.singletonInstance;
+		} else {
+			return createInstance();
+		}
+	}
+
+	public Class<?> getObjectType() {
+		return DBDatabase.class;
+	}
+
+	public boolean isSingleton() {
+		return false;
+	}
+
+	public void afterPropertiesSet() throws Exception {
+		if (driver == null && driverClass == null){
+			throw new RuntimeException("driver or driverClass must be set");	
+		}
+		
+		if (driver == null){
+			driver = (DBDatabaseDriver) driverClass.newInstance();
+		}
+		
+		if (this.singleton) {
+			this.singletonInstance = createInstance();
+		}
+	}
+
+	protected DBDatabase createInstance() {
+		DBDatabase database = null;
+		if (this.databaseClass == null) {
+			database = new DefaultDb();
+		} else {
+			try {
+				database = this.databaseClass.newInstance();
+			} catch (Exception e) {
+				throw new RuntimeException("Failed to create database: "
+						+ this.databaseClass, e);
+			}
+		}
+		if (this.schema != null && this.schema.trim().length() > 0){
+			database.setSchema(schema);	
+		}
+		if (this.linkName != null && this.linkName.trim().length() > 0){
+			database.setLinkName(linkName);	
+		}
+		
+		
+		database.setPreparedStatementsEnabled(preparedStatementsEnabled);
+		if (earlyOpen) {
+			database.open(driver, null);
+		}
+		return database;
+	}
+
+	public static class DefaultDb extends DBDatabase {
+
+		private static final long serialVersionUID = 1L;
+
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDaoSupport.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDaoSupport.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDaoSupport.java
new file mode 100644
index 0000000..387d004
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDaoSupport.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBDatabaseDriver;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.ConnectionCallback;
+import org.springframework.jdbc.core.support.JdbcDaoSupport;
+import org.springframework.util.Assert;
+
+public abstract class EmpireDaoSupport extends JdbcDaoSupport {
+
+	private EmpireTemplate empireTemplate;
+	private DBDatabase database;
+	private DBDatabaseDriver driver;
+
+	
+	
+	public void setDriver(DBDatabaseDriver driver) {
+		this.driver = driver;
+	}
+
+	protected EmpireTemplate getEmpireTemplate() {
+		if (this.empireTemplate == null) {
+			this.empireTemplate = new EmpireTemplate();
+			this.empireTemplate.setJdbcTemplate(getJdbcTemplate());
+		}
+		return this.empireTemplate;
+	}
+
+	public void setEmpireTemplate(EmpireTemplate empireTemplate) {
+		this.empireTemplate = empireTemplate;
+	}
+
+	protected void initEmpireDao(){
+	}
+
+	@Override
+	protected final void initDao() throws Exception {
+		super.initDao();
+		if (!this.database.isOpen() && this.driver == null){
+			throw new RuntimeException("Database isn't open and no driver set.");
+		}
+		this.initEmpireDao();
+
+	}
+
+	public void setDatabase(DBDatabase database){
+		if (this.database != null){
+			Assert.isTrue(this.database == database, "setting different database not allowed");
+		}
+		this.database = database;
+	}
+	
+	@SuppressWarnings("unchecked")
+	public <T extends DBDatabase> T getDatabase(){
+		if (!this.database.isOpen()){
+			getJdbcTemplate().execute(new ConnectionCallback<Object>() {
+
+				public Object doInConnection(Connection con)
+						throws SQLException, DataAccessException {
+					EmpireDaoSupport.this.database.open(driver, getConnection());
+					return null;
+				}
+			});
+			
+		}
+		return (T) this.database;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDataReader.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDataReader.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDataReader.java
new file mode 100644
index 0000000..b0b2f76
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDataReader.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import org.apache.empire.db.DBRecordData;
+
+public interface EmpireDataReader<K> {
+
+	public abstract K read(DBRecordData record);
+	
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDriverFactory.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDriverFactory.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDriverFactory.java
new file mode 100644
index 0000000..4548482
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireDriverFactory.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import java.sql.Connection;
+
+import org.apache.empire.db.DBDatabaseDriver;
+import org.apache.empire.db.derby.DBDatabaseDriverDerby;
+import org.apache.empire.db.h2.DBDatabaseDriverH2;
+import org.apache.empire.db.hsql.DBDatabaseDriverHSql;
+import org.apache.empire.db.mysql.DBDatabaseDriverMySQL;
+import org.apache.empire.db.oracle.DBDatabaseDriverOracle;
+import org.apache.empire.db.postgresql.DBDatabaseDriverPostgreSQL;
+import org.apache.empire.db.sqlserver.DBDatabaseDriverMSSQL;
+import org.springframework.jdbc.core.support.JdbcDaoSupport;
+
+/**
+ * Creates the Empire-DB Drivers. Extends JdbcDaoSupport because it needs a Connection
+ */
+public class EmpireDriverFactory extends JdbcDaoSupport {
+
+    // copy&paste from the SampleApp
+
+    public DBDatabaseDriver createDriver(String driverclass, String schema) {
+        if (isClass(DBDatabaseDriverMySQL.class, driverclass))
+        {
+            DBDatabaseDriverMySQL driver = new DBDatabaseDriverMySQL();
+            // Set Driver specific properties (if any)
+            driver.setDatabaseName(schema);
+            return driver;
+        }
+        else if (isClass(DBDatabaseDriverOracle.class, driverclass))
+        {
+            DBDatabaseDriverOracle driver = new DBDatabaseDriverOracle();
+            // Set Driver specific properties (if any)
+            return driver;
+        }
+        else if (isClass(DBDatabaseDriverMSSQL.class, driverclass))
+        {
+            DBDatabaseDriverMSSQL driver = new DBDatabaseDriverMSSQL();
+            // Set Driver specific properties (if any)
+            driver.setDatabaseName(schema);
+            return driver;
+        }
+        else if (isClass(DBDatabaseDriverHSql.class, driverclass))
+        {
+            DBDatabaseDriverHSql driver = new DBDatabaseDriverHSql();
+            // Set Driver specific properties (if any)
+            return driver;
+        }
+        else if (isClass(DBDatabaseDriverPostgreSQL.class, driverclass))
+        {
+            DBDatabaseDriverPostgreSQL driver = new DBDatabaseDriverPostgreSQL();
+            // Set Driver specific properties (if any)
+            driver.setDatabaseName(schema);
+            // Create the reverse function that is needed by this sample
+            Connection conn = getConnection();
+            driver.createReverseFunction(conn);
+            releaseConnection(conn);
+            return driver;
+        }
+        else if (isClass(DBDatabaseDriverH2.class, driverclass))
+        {
+            DBDatabaseDriverH2 driver = new DBDatabaseDriverH2();
+            // Set Driver specific properties (if any)
+            driver.setDatabaseName(schema);
+            return driver;
+        }
+        else if (isClass(DBDatabaseDriverDerby.class, driverclass))
+        {
+            DBDatabaseDriverDerby driver = new DBDatabaseDriverDerby();
+            // Set Driver specific properties (if any)
+            driver.setDatabaseName(schema);
+            return driver;
+        }
+        else
+        {   // Unknown Provider
+            throw new RuntimeException("Unknown Database Driver " + driverclass);
+        }
+    }
+
+    private boolean isClass(Class<? extends DBDatabaseDriver> clazz, String name) {
+        return name.equals(clazz.getName());
+    }
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireIntegerValueReader.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireIntegerValueReader.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireIntegerValueReader.java
new file mode 100644
index 0000000..f707a8c
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireIntegerValueReader.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.db.DBRecordData;
+
+public class EmpireIntegerValueReader implements EmpireDataReader<Integer> {
+
+	DBColumnExpr column;
+	Integer defaultValue = null;
+
+	public EmpireIntegerValueReader(DBColumnExpr column, Integer defaultValue) {
+		super();
+		this.column = column;
+		this.defaultValue = defaultValue;
+	}
+
+	public Integer read(DBRecordData record) {
+		return record.isNull(column) ? defaultValue : record.getInt(column);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireLongValueReader.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireLongValueReader.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireLongValueReader.java
new file mode 100644
index 0000000..7e68f22
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireLongValueReader.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.db.DBRecordData;
+
+public class EmpireLongValueReader implements EmpireDataReader<Long> {
+
+	DBColumnExpr column;
+	private Long defaultValue;
+
+	public EmpireLongValueReader(DBColumnExpr column, Long defaultValue) {
+		super();
+		this.column = column;
+		this.defaultValue = defaultValue;
+	}
+
+	public Long read(DBRecordData record) {
+		return record.isNull(column) ? defaultValue : record.getLong(column);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireReader.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireReader.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireReader.java
new file mode 100644
index 0000000..cfac81a
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireReader.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.beanutils.BeanUtilsBean;
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.empire.commons.ObjectUtils;
+import org.apache.empire.commons.StringUtils;
+import org.apache.empire.db.DBReader;
+import org.apache.empire.exceptions.BeanPropertySetException;
+import org.apache.empire.exceptions.InvalidArgumentException;
+import org.apache.empire.exceptions.ItemNotFoundException;
+
+public class EmpireReader extends DBReader
+{
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    protected void getBeanProperty(Object bean, String property, Object value)
+    {
+        try
+        {
+            if (bean == null)
+                throw new InvalidArgumentException("bean", bean);
+            if (StringUtils.isEmpty(property))
+                throw new InvalidArgumentException("property", property);
+
+            // Get descriptor
+            PropertyDescriptor descriptor = BeanUtilsBean.getInstance().getPropertyUtils().getPropertyDescriptor(bean, property);
+            if (descriptor == null)
+            {
+                return; // Skip this property setter
+            }
+            // Check enum
+            Class<?> type = descriptor.getPropertyType();
+            if (type.isEnum())
+            {
+                // Enum<?> ev = Enum.valueOf(type, value);
+                boolean found = false;
+                Enum<?>[] items = (Enum[]) type.getEnumConstants();
+                for (int i = 0; i < items.length; i++)
+                {
+                    Enum<?> item = items[i];
+                    if (ObjectUtils.compareEqual(item.name(), value))
+                    {
+                        value = item;
+                        found = true;
+                        break;
+                    }
+                }
+                // Enumeration value not found
+                if (!found)
+                    throw new ItemNotFoundException(value);
+            }
+            
+            // Set Property Value
+            if (value != null)
+            { // Bean utils will convert if necessary
+                BeanUtils.setProperty(bean, property, value);
+            }
+            else
+            { // Don't convert, just set
+                PropertyUtils.setProperty(bean, property, null);
+            }
+        }
+        catch (IllegalAccessException e)
+        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+        }
+        catch (InvocationTargetException e)
+        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+        }
+        catch (NoSuchMethodException e)
+        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+        }
+        catch (NullPointerException e)
+        {   log.error(bean.getClass().getName() + ": unable to set property '" + property + "'");
+            throw new BeanPropertySetException(bean, property, e);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireReaderExtractor.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireReaderExtractor.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireReaderExtractor.java
new file mode 100644
index 0000000..81255d7
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireReaderExtractor.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import org.apache.empire.db.DBReader;
+
+public interface EmpireReaderExtractor<K> {
+
+	K process(DBReader reader);
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRecord.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRecord.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRecord.java
new file mode 100644
index 0000000..e3efca1
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRecord.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.commons.beanutils.BeanUtilsBean;
+import org.apache.commons.beanutils.PropertyUtilsBean;
+import org.apache.empire.data.Column;
+import org.apache.empire.db.DBRecord;
+import org.apache.empire.exceptions.BeanPropertyGetException;
+
+public class EmpireRecord extends DBRecord
+{
+    private static final long serialVersionUID = 1L;
+
+    @Override
+    protected void setBeanValue(Object bean, String property, Column column)
+    {
+        try
+        {
+            // Get descriptor
+            Object value;
+            PropertyUtilsBean pub = BeanUtilsBean.getInstance().getPropertyUtils();
+            PropertyDescriptor descriptor = pub.getPropertyDescriptor(bean, property);
+            if (descriptor == null) {
+                return; // Skip this property setter
+            }
+            
+            // Get Property Value
+            value = pub.getSimpleProperty(bean, property);
+
+            // Check enum
+            if (value instanceof Enum<?>)
+                value = ((Enum<?>)value).name();
+                    
+            // Set the record value
+            setValue( column, value ); 
+
+        } catch (IllegalAccessException e)
+        {   log.error(bean.getClass().getName() + ": unable to get property '" + property + "'");
+            throw new BeanPropertyGetException(bean, property, e);
+        } catch (NoSuchMethodException e)
+        {   log.error(bean.getClass().getName() + ": unable to get property '" + property + "'");
+            throw new BeanPropertyGetException(bean, property, e);
+        } catch (InvocationTargetException e)
+        {   log.error(bean.getClass().getName() + ": unable to get property '" + property + "'");
+            throw new BeanPropertyGetException(bean, property, e);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRecordWriter.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRecordWriter.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRecordWriter.java
new file mode 100644
index 0000000..2ecea4d
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRecordWriter.java
@@ -0,0 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import org.apache.empire.db.DBRecord;
+
+
+public interface EmpireRecordWriter<K> {
+
+	public abstract void write(DBRecord record, K entity);
+	
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRowCallbackHandler.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRowCallbackHandler.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRowCallbackHandler.java
new file mode 100644
index 0000000..9a24bce
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireRowCallbackHandler.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import org.apache.empire.db.DBRecordData;
+
+public interface EmpireRowCallbackHandler {
+
+	void processRow(DBRecordData record);
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireStringValueReader.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireStringValueReader.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireStringValueReader.java
new file mode 100644
index 0000000..9f16a6c
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireStringValueReader.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.db.DBRecordData;
+
+public class EmpireStringValueReader implements EmpireDataReader<String> {
+
+	DBColumnExpr column;
+
+	public EmpireStringValueReader(DBColumnExpr column) {
+		super();
+		this.column = column;
+	}
+
+	public String read(DBRecordData record) {
+		return record.getString(column);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireTemplate.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireTemplate.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireTemplate.java
new file mode 100644
index 0000000..9202bbc
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireTemplate.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.sql.DataSource;
+
+import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.db.DBCommand;
+import org.apache.empire.db.DBReader;
+import org.apache.empire.db.DBRecord;
+import org.apache.empire.db.DBRowSet;
+import org.apache.empire.db.DBTable;
+import org.apache.empire.db.exceptions.RecordNotFoundException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.dao.DataAccessException;
+import org.springframework.dao.support.DataAccessUtils;
+import org.springframework.jdbc.core.ConnectionCallback;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.util.Assert;
+
+public class EmpireTemplate implements InitializingBean {
+
+	private JdbcTemplate jdbcTemplate;
+
+	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
+		this.jdbcTemplate = jdbcTemplate;
+	}
+
+	public JdbcTemplate getJdbcTemplate() {
+		return this.jdbcTemplate;
+	}
+
+	public final void setDataSource(DataSource dataSource) {
+		if (this.jdbcTemplate == null || dataSource != this.jdbcTemplate.getDataSource()) {
+			this.jdbcTemplate = new JdbcTemplate(dataSource);
+			this.jdbcTemplate.afterPropertiesSet();
+		}
+	}
+
+	public void afterPropertiesSet() throws Exception {
+		if (getJdbcTemplate() == null) {
+			throw new IllegalArgumentException("Property 'jdbcTemplate' is required");
+		}
+
+	}
+
+	public <K> List<K> query(final DBCommand cmd, final EmpireDataReader<K> dataReader) {
+		return query(cmd, new EmpireDataReaderExtractor<K>(dataReader));
+
+	}
+
+	public List<Object> queryForList(final DBCommand cmd, final DBColumnExpr col) {
+		return query(cmd, new EmpireValueReader(col));
+
+	}
+
+	public Long queryForLong(final DBCommand cmd, final DBColumnExpr col, Long defaultValue) {
+		return DataAccessUtils.uniqueResult(queryForLongList(cmd, col, defaultValue));
+	}
+
+	public List<Long> queryForLongList(final DBCommand cmd, final DBColumnExpr col, final Long defaultValue) {
+		return query(cmd, new EmpireLongValueReader(col, defaultValue));
+
+	}
+
+	public Integer queryForInteger(final DBCommand cmd, final DBColumnExpr col, Integer defaultValue) {
+		return DataAccessUtils.uniqueResult(queryForIntegerList(cmd, col, defaultValue));
+	}
+
+	public List<Integer> queryForIntegerList(final DBCommand cmd, final DBColumnExpr col, final Integer defaultValue) {
+		return query(cmd, new EmpireIntegerValueReader(col, defaultValue));
+	}
+
+	public String queryForString(final DBCommand cmd, final DBColumnExpr col) {
+		return DataAccessUtils.uniqueResult(queryForStringList(cmd, col));
+	}
+
+	public List<String> queryForStringList(final DBCommand cmd, final DBColumnExpr col) {
+		return query(cmd, new EmpireStringValueReader(col));
+	}
+
+	public <K> K query(final DBCommand cmd, final EmpireReaderExtractor<K> readerHandler) {
+
+		class QueryCallback implements ConnectionCallback<K> {
+			public K doInConnection(Connection connection) throws SQLException, DataAccessException {
+				return query(connection, cmd, readerHandler);
+			}
+		}
+		return getJdbcTemplate().execute(new QueryCallback());
+
+	}
+
+	public void query(final DBCommand cmd, final EmpireRowCallbackHandler rowCallbackHandler) {
+		query(cmd, new EmpireRowCallbackHandlerExtractor(rowCallbackHandler));
+	}
+
+	public <K> K queryForObject(final DBCommand cmd, final EmpireDataReader<K> dataReader) {
+
+		return DataAccessUtils.uniqueResult(query(cmd, dataReader));
+
+	}
+
+	public void deleteRecord(final DBRecord record) {
+
+		class DeleteRecordCallback implements ConnectionCallback<Object> {
+			public Object doInConnection(Connection connection) throws SQLException, DataAccessException {
+				record.delete(connection);
+				return null;
+			}
+		}
+		getJdbcTemplate().execute(new DeleteRecordCallback());
+
+	}
+
+	public void deleteRecord(final DBTable table, final Object key) {
+		deleteRecord(table, new Object[] { key });
+	}
+
+	public void deleteRecord(final DBTable table, final Object[] keys) {
+
+		class DeleteRecordCallback implements ConnectionCallback<Object> {
+			public Object doInConnection(Connection connection) throws SQLException, DataAccessException {
+				DBRecord record = new EmpireRecord();
+				record.read(table, keys, connection);
+				record.delete(connection);
+				return null;
+			}
+		}
+		getJdbcTemplate().execute(new DeleteRecordCallback());
+
+	}
+
+	public DBRecord updateRecord(final DBRecord record) {
+
+		class UpdateRecordCallback implements ConnectionCallback<DBRecord> {
+			public DBRecord doInConnection(Connection connection) throws SQLException, DataAccessException {
+				record.update(connection);
+				return record;
+			}
+		}
+
+		return getJdbcTemplate().execute(new UpdateRecordCallback());
+
+	}
+
+	public int executeUpdate(final DBCommand cmd) {
+
+		class UpdateRecordCallback implements ConnectionCallback<Integer> {
+			public Integer doInConnection(Connection connection) throws SQLException, DataAccessException {
+				return cmd.getDatabase().executeUpdate(cmd, connection);
+			}
+		}
+
+		return getJdbcTemplate().execute(new UpdateRecordCallback());
+
+	}
+
+	public int executeDelete(final DBTable table, final DBCommand cmd) {
+
+		class DeleteRecordCallback implements ConnectionCallback<Integer> {
+			public Integer doInConnection(Connection connection) throws SQLException, DataAccessException {
+				return cmd.getDatabase().executeDelete(table, cmd, connection);
+			}
+		}
+
+		return getJdbcTemplate().execute(new DeleteRecordCallback());
+
+	}
+
+	public int executeInsert(final DBCommand cmd) {
+
+		class InsertRecordCallback implements ConnectionCallback<Integer> {
+			public Integer doInConnection(Connection connection) throws SQLException, DataAccessException {
+				return cmd.getDatabase().executeInsert(cmd, connection);
+			}
+		}
+
+		return getJdbcTemplate().execute(new InsertRecordCallback());
+
+	}
+
+	public DBRecord newRecord(final DBRowSet table) {
+		DBRecord record = new EmpireRecord();
+		record.create(table);
+		return record;
+	}
+
+	public DBRecord openRecord(final DBRowSet table, final Object key) {
+		return openRecord(table, new Object[] { key });
+	}
+
+	public DBRecord openRecord(final DBRowSet table, final Object[] keys) {
+
+		class ReadRecordCallback implements ConnectionCallback<DBRecord> {
+			public DBRecord doInConnection(Connection connection) throws SQLException, DataAccessException {
+				DBRecord record = new EmpireRecord();
+				try {
+					record.read(table, keys, connection);
+				} catch (RecordNotFoundException e) {
+					return null;
+				}
+				return record;
+			}
+		}
+
+		return getJdbcTemplate().execute(new ReadRecordCallback());
+
+	}
+
+	public <K> K execute(ConnectionCallback<K> connectionCallback) {
+		return getJdbcTemplate().execute(connectionCallback);
+	}
+
+	private <K> K query(Connection connection, DBCommand command, EmpireReaderExtractor<K> callback) {
+		DBReader reader = newDBReader();
+		try {
+			reader.open(command, connection);
+
+			return callback.process(reader);
+
+		} finally {
+			reader.close();
+		}
+	}
+
+	private DBReader newDBReader() {
+		return new EmpireReader();
+	}
+	
+	public static class EmpireRowCallbackHandlerExtractor implements EmpireReaderExtractor<Object> {
+
+		private final EmpireRowCallbackHandler rowCallbackHandler;
+
+		public EmpireRowCallbackHandlerExtractor(EmpireRowCallbackHandler rowCallbackHandler) {
+			Assert.notNull(rowCallbackHandler, "RowCallbackHandler is required");
+			this.rowCallbackHandler = rowCallbackHandler;
+		}
+
+//		@Override
+		public Object process(DBReader reader) {
+			try {
+				while (reader.moveNext()) {
+					this.rowCallbackHandler.processRow(reader);
+				}
+				return null;
+			} finally {
+				reader.close();
+			}
+		}
+		
+	}
+
+	public static class EmpireDataReaderExtractor<K> implements EmpireReaderExtractor<List<K>> {
+
+		private final EmpireDataReader<K> dataReader;
+
+		public EmpireDataReaderExtractor(EmpireDataReader<K> rowMapper) {
+			Assert.notNull(rowMapper, "DataReader is required");
+			this.dataReader = rowMapper;
+		}
+
+//		@Override
+		public List<K> process(DBReader reader) {
+			try {
+				List<K> results = new ArrayList<K>();
+
+				while (reader.moveNext()) {
+					results.add(this.dataReader.read(reader));
+				}
+
+				return results;
+
+			} finally {
+				reader.close();
+			}
+		}
+
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireValueReader.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireValueReader.java b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireValueReader.java
new file mode 100644
index 0000000..95e1b9b
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/EmpireValueReader.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring;
+
+import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.db.DBRecordData;
+
+public class EmpireValueReader implements EmpireDataReader<Object> {
+
+	DBColumnExpr column;
+
+	public EmpireValueReader(DBColumnExpr column) {
+		super();
+		this.column = column;
+	}
+
+	public Object read(DBRecordData record) {
+		return record.getValue(column);
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/example1/EmpireApp.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/example1/EmpireApp.java b/empire-db-spring/src/main/java/org/apache/empire/spring/example1/EmpireApp.java
new file mode 100644
index 0000000..ddf809f
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/example1/EmpireApp.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring.example1;
+
+
+/**
+ * This is the interface to the application. It is usually some high level interface; for this basic
+ * example this is the dao object.
+ *
+ */
+public interface EmpireApp {
+
+    void clearDatabase();
+
+    void setupDatabase();
+    
+    Integer insertDepartment(String departmentName, String businessUnit);
+
+    Integer insertEmployee(String firstName, String lastName, String gender, int departmentId);
+
+    void updateEmployee(int idPers, String phoneNumber);
+
+    void doQuery(QueryType type);
+
+    public enum QueryType
+    {
+	    Reader,
+        BeanList,
+	    XmlDocument
+	}
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/example1/EmpireAppImpl.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/example1/EmpireAppImpl.java b/empire-db-spring/src/main/java/org/apache/empire/spring/example1/EmpireAppImpl.java
new file mode 100644
index 0000000..41fcd52
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/example1/EmpireAppImpl.java
@@ -0,0 +1,337 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring.example1;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.empire.db.DBColumn;
+import org.apache.empire.db.DBColumnExpr;
+import org.apache.empire.db.DBCommand;
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBDatabaseDriver;
+import org.apache.empire.db.DBReader;
+import org.apache.empire.db.DBRecord;
+import org.apache.empire.db.DBRecordData;
+import org.apache.empire.db.DBSQLScript;
+import org.apache.empire.db.DBTable;
+import org.apache.empire.db.derby.DBDatabaseDriverDerby;
+import org.apache.empire.db.h2.DBDatabaseDriverH2;
+import org.apache.empire.db.hsql.DBDatabaseDriverHSql;
+import org.apache.empire.db.postgresql.DBDatabaseDriverPostgreSQL;
+import org.apache.empire.spring.EmpireDaoSupport;
+import org.apache.empire.spring.EmpireDataReader;
+import org.apache.empire.spring.EmpireReaderExtractor;
+import org.apache.empire.spring.EmpireRecord;
+import org.apache.empire.spring.EmpireRowCallbackHandler;
+import org.apache.empire.xml.XMLWriter;
+import org.springframework.dao.DataAccessException;
+import org.springframework.jdbc.core.ConnectionCallback;
+import org.springframework.transaction.annotation.Transactional;
+import org.w3c.dom.Document;
+
+/**
+ *
+ */
+public class EmpireAppImpl extends EmpireDaoSupport implements EmpireApp {
+
+	@Transactional
+	public void clearDatabase() {
+		SampleDB db = getDatabase();
+
+		DBCommand cmd = db.createCommand();
+		// Delete all Employees (no constraints)
+		getEmpireTemplate().executeDelete(db.EMPLOYEES, cmd);
+		// Delete all Departments (no constraints)
+		getEmpireTemplate().executeDelete(db.DEPARTMENTS, cmd);
+	}
+
+
+	@Transactional
+	public Integer insertDepartment(String departmentName, String businessUnit) {
+		SampleDB db = getDatabase();
+
+		DBRecord rec = new EmpireRecord();
+		rec.create(db.DEPARTMENTS);
+		rec.setValue(db.DEPARTMENTS.NAME, departmentName);
+		rec.setValue(db.DEPARTMENTS.BUSINESS_UNIT, businessUnit);
+
+		getEmpireTemplate().updateRecord(rec);
+		// Return Department ID
+		return rec.getInt(db.DEPARTMENTS.DEPARTMENT_ID);
+	}
+
+	@Transactional
+	public Integer insertEmployee(String firstName, String lastName,
+			String gender, int departmentId) {
+		SampleDB db = getDatabase();
+
+		DBRecord rec = new EmpireRecord();
+		rec.create(db.EMPLOYEES);
+		rec.setValue(db.EMPLOYEES.FIRSTNAME, firstName);
+		rec.setValue(db.EMPLOYEES.LASTNAME, lastName);
+		rec.setValue(db.EMPLOYEES.GENDER, gender);
+		rec.setValue(db.EMPLOYEES.DEPARTMENT_ID, departmentId);
+		getEmpireTemplate().updateRecord(rec);
+		// Return Employee ID
+		return rec.getInt(db.EMPLOYEES.EMPLOYEE_ID);
+	}
+
+	@Transactional
+	public void updateEmployee(int idPers, String phoneNumber) {
+		if (getEmployee(idPers) == null) {
+			// if you like more verbose exceptions for the app
+			throw new IllegalArgumentException(
+					"The specified employee does not exist.");
+		}
+
+		SampleDB db = getDatabase();
+
+		DBRecord rec = getEmpireTemplate().openRecord(db.EMPLOYEES, idPers);
+		// Set
+		rec.setValue(db.EMPLOYEES.PHONE_NUMBER, phoneNumber);
+		getEmpireTemplate().updateRecord(rec);
+	}
+
+	@Transactional(readOnly = true)
+	public void doQuery(QueryType type) {
+		SampleDB db = getDatabase();
+
+		// Define the query
+		DBCommand cmd = db.createCommand();
+		// Define shortcuts for tables used - not necessary but convenient
+		final SampleDB.Employees EMP = db.EMPLOYEES;
+		final SampleDB.Departments DEP = db.DEPARTMENTS;
+
+		// The following expression concats lastname + ', ' + firstname
+		final DBColumnExpr EMPLOYEE_FULLNAME = EMP.LASTNAME.append(", ")
+				.append(EMP.FIRSTNAME).as("FULL_NAME");
+
+		// The following expression extracts the extension number from the phone
+		// field
+		// e.g. substr(PHONE_NUMBER,
+		// length(PHONE_NUMBER)-instr(reverse(PHONE_NUMBER), '-')+2) AS
+		// PHONE_EXTENSION
+		// Hint: Since the reverse() function is not supported by HSQLDB there
+		// is special treatment for HSQL
+		final DBColumnExpr PHONE_LAST_DASH;
+		if (db.getDriver() instanceof DBDatabaseDriverHSql
+				|| db.getDriver() instanceof DBDatabaseDriverDerby
+				|| db.getDriver() instanceof DBDatabaseDriverH2)
+			PHONE_LAST_DASH = EMP.PHONE_NUMBER.indexOf("-",
+					EMP.PHONE_NUMBER.indexOf("-").plus(1)).plus(1); // HSQLDB
+																	// only
+		else
+			PHONE_LAST_DASH = EMP.PHONE_NUMBER.length()
+					.minus(EMP.PHONE_NUMBER.reverse().indexOf("-")).plus(2);
+		final DBColumnExpr PHONE_EXT_NUMBER = EMP.PHONE_NUMBER.substring(
+				PHONE_LAST_DASH).as("PHONE_EXTENSION");
+
+		// DBColumnExpr genderExpr =
+		// cmd.select(EMP.GENDER.decode(EMP.GENDER.getOptions()).as(EMP.GENDER.getName()));
+		// Select required columns
+		cmd.select(EMP.EMPLOYEE_ID, EMPLOYEE_FULLNAME);
+		if (db.getDriver() instanceof DBDatabaseDriverPostgreSQL) {
+			// postgres does not support the substring expression
+			cmd.select(EMP.GENDER, EMP.PHONE_NUMBER);
+		} else {
+			cmd.select(EMP.GENDER, EMP.PHONE_NUMBER, PHONE_EXT_NUMBER);
+
+		}
+		cmd.select(DEP.NAME.as("DEPARTMENT"));
+		cmd.select(DEP.BUSINESS_UNIT);
+		cmd.join(EMP.DEPARTMENT_ID, DEP.DEPARTMENT_ID);
+		// Set constraints and order
+		cmd.where(EMP.LASTNAME.length().isGreaterThan(0));
+		cmd.orderBy(EMP.LASTNAME, EMP.FIRSTNAME);
+
+		// Query Records and print output
+		try {
+			// Open Reader
+			System.out.println("Running Query:");
+			System.out.println(cmd.getSelect());
+			// Print output
+			System.out.println("---------------------------------");
+			switch (type) {
+			case BeanList:
+				// Text-Output by iterating through all records.
+				EmpireRowCallbackHandler readerImpl = new EmpireRowCallbackHandler() {
+
+					public void processRow(DBRecordData reader) {
+						System.out.println(reader.getString(EMP.EMPLOYEE_ID)
+								+ "\t"
+								+ reader.getString(EMPLOYEE_FULLNAME)
+								+ "\t"
+								+ EMP.GENDER.getOptions().get(
+										reader.getString(EMP.GENDER)) + "\t"
+								+ reader.getString(PHONE_EXT_NUMBER) + "\t"
+								+ reader.getString(DEP.NAME));
+
+					}
+				};
+				getEmpireTemplate().query(cmd, readerImpl);
+				break;
+			case Reader:
+				// Text-Output using a list of Java Beans supplied by the
+				// DBReader
+				EmpireReaderExtractor<List<SampleBean>> beanListImpl = new EmpireReaderExtractor<List<SampleBean>>() {
+
+					public List<SampleBean> process(DBReader reader) {
+						return reader.getBeanList(SampleBean.class);
+					}
+				};
+				List<SampleBean> beanList = getEmpireTemplate().query(cmd,
+						beanListImpl);
+				System.out.println(String.valueOf(beanList.size())
+						+ " SampleBeans returned from Query.");
+				for (SampleBean b : beanList) {
+					System.out.println(b.toString());
+				}
+				break;
+			case XmlDocument:
+				// XML Output
+				XmlDocumentExtractor xmlImpl = new XmlDocumentExtractor();
+				Document doc = getEmpireTemplate().query(cmd, xmlImpl);
+				// Print XML Document to System.out
+				XMLWriter.debug(doc);
+				break;
+			}
+
+		} finally {
+
+			// always close Reader
+
+			// reader is closed in EmpireTemplate's methods
+
+			// reader.close();
+		}
+	}
+
+	public Map<Object, Object> getDepartment(int id) {
+		SampleDB db = getDatabase();
+		return get(db.DEPARTMENTS, id);
+	}
+
+	public Map<Object, Object> getEmployee(int id) {
+		SampleDB db = getDatabase();
+		return get(db.EMPLOYEES, id);
+	}
+
+	private Map<Object, Object> get(DBTable table, int pk) {
+
+		SampleDB db = getDatabase();
+
+		DBCommand cmd = db.createCommand();
+		cmd.select(table.getColumns());
+		cmd.where(table.getPrimaryKey().getColumns()[0].is(pk)); // i know there
+																	// is just
+																	// one
+																	// pk-column
+																	// ;-)
+		Map<Object, Object> dep = getEmpireTemplate().queryForObject(cmd,
+				new RowToObjectMapDataMapper(table));
+
+		return dep;
+	}
+
+	public static class XmlDocumentExtractor implements
+			EmpireReaderExtractor<Document> {
+
+		public Document process(DBReader reader) {
+			return reader.getXmlDocument();
+		}
+
+	}
+
+	public static class RowToObjectMapDataMapper implements
+			EmpireDataReader<Map<Object, Object>> {
+
+		DBTable table;
+
+		public RowToObjectMapDataMapper(DBTable table) {
+			super();
+			this.table = table;
+		}
+
+		public Map<Object, Object> read(DBRecordData record) {
+			Map<Object, Object> dep = new HashMap<Object, Object>();
+			for (DBColumn col : table.getColumns()) {
+				dep.put(col.getName(), record.getValue(col));
+			}
+			return dep;
+		}
+
+	}
+
+	public boolean databaseExists() {
+		Connection conn = getConnection();
+		try {
+			DBDatabase db = getDatabase();
+			if (db.getTables() == null || db.getTables().isEmpty()) {
+				throw new AssertionError(
+						"There are no tables in this database!");
+			}
+			DBCommand cmd = db.createCommand();
+			if (cmd == null) {
+				throw new AssertionError("The DBCommand object is null.");
+			}
+			DBTable t = db.getTables().get(0);
+			cmd.select(t.count());
+			return (db.querySingleInt(cmd, -1, conn) >= 0);
+		} catch (Exception e) {
+			return false;
+		}
+	}
+
+	public void initializeDatabase() {
+		if (!databaseExists()) {
+			createDatabase();
+		}
+	}
+
+	@Transactional
+	public void setupDatabase() {
+		initializeDatabase();
+	}
+
+	public void createDatabase() {
+
+		// create DLL for Database Definition
+		final DBSQLScript script = new DBSQLScript();
+		final DBDatabaseDriver driver = getDatabase().getDriver();
+		getDatabase().getCreateDDLScript(driver, script);
+
+		// Show DLL Statement
+		System.out.println(script.toString());
+		// Execute Script
+		getEmpireTemplate().execute(new ConnectionCallback<Object>() {
+
+			public Object doInConnection(Connection con) throws SQLException,
+					DataAccessException {
+				script.executeAll(driver, con, false);
+				return null;
+			}
+		});
+
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleBean.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleBean.java b/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleBean.java
new file mode 100644
index 0000000..efe89b1
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleBean.java
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring.example1;
+
+
+/**
+ * The SampleBean class is used to demonstrate JavaBean support for SQL-Queries.
+ * The SampleBean is used in the SampleApp's queryRecords function.
+ */
+public class SampleBean
+{
+    private int    employeeId;
+    private String fullName;
+    private String gender;
+    private String phoneNumber;
+    private String department;
+    private String businessUnit;
+
+    /*
+     * Uncomment this if you want to use constructor instead of setters
+     * However, number of arguments and data types must match query!
+     *
+    public SampleBean(int employeeId, String fullName, String gender, String phoneNumber, String department, String businessUnit)
+    {
+        this.employeeId = employeeId;
+        this.fullName = fullName;
+        this.gender = gender;
+        this.phoneNumber = phoneNumber;
+        this.department = department;
+        this.businessUnit = businessUnit;
+    }
+    */
+    
+    public int getEmployeeId()
+    {
+        return employeeId;
+    }
+
+    public void setEmployeeId(int employeeId)
+    {
+        this.employeeId = employeeId;
+    }
+
+    public String getFullName()
+    {
+        return fullName;
+    }
+
+    public void setFullName(String fullName)
+    {
+        this.fullName = fullName;
+    }
+
+    public String getGender()
+    {
+        return gender;
+    }
+
+    public void setGender(String gender)
+    {
+        this.gender = gender;
+    }
+
+    public String getPhoneNumber()
+    {
+        return phoneNumber;
+    }
+
+    public void setPhoneNumber(String phoneNumber)
+    {
+        this.phoneNumber = phoneNumber;
+    }
+
+    public String getDepartment()
+    {
+        return department;
+    }
+
+    public void setDepartment(String department)
+    {
+        this.department = department;
+    }
+
+    public String getBusinessUnit()
+    {
+        return businessUnit;
+    }
+
+    public void setBusinessUnit(String businessUnit)
+    {
+        this.businessUnit = businessUnit;
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuffer buf = new StringBuffer();
+        buf.append(employeeId);
+        buf.append("\t");
+        buf.append(fullName);
+        buf.append("\t");
+        buf.append(gender);
+        buf.append("\t");
+        buf.append(department);
+        buf.append("\t");
+        buf.append(businessUnit);
+        return buf.toString();
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleDB.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleDB.java b/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleDB.java
new file mode 100644
index 0000000..c8f3284
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleDB.java
@@ -0,0 +1,148 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring.example1;
+
+import org.apache.empire.commons.Options;
+import org.apache.empire.data.DataType;
+import org.apache.empire.data.DataMode;
+import org.apache.empire.db.DBColumn;
+import org.apache.empire.db.DBDatabase;
+import org.apache.empire.db.DBTable;
+import org.apache.empire.db.DBTableColumn;
+
+/**
+ * <PRE>
+ * This file contains the definition of the data model in Java.
+ * The SampleDB data model consists of two tables and a foreign key relation.
+ * The tables are defined as nested classes here, but you may put the in separate files if you want.
+ *
+ * PLEASE NOTE THE NAMING CONVENTION:
+ * Since all tables, views and columns are declared as "final" constants they are all in upper case.
+ * We recommend using a prefix of T_ for tables and C_ for columns in order to keep them together
+ * when listed in your IDE's code completion.
+ * There is no need to stick to this convention but it makes life just another little bit easier.
+ *
+ * You may declare other database tables or views in the same way.
+ * </PRE>
+ */
+public class SampleDB extends DBDatabase
+{
+    private final static long serialVersionUID = 1L;
+
+    /**
+     * This class represents the definition of the Departments table.
+     */
+    public static class Departments extends DBTable
+    {
+
+        private final static long serialVersionUID = 1L;
+
+        public final DBTableColumn DEPARTMENT_ID;
+        public final DBTableColumn NAME;
+        public final DBTableColumn HEAD;
+        public final DBTableColumn BUSINESS_UNIT;
+        public final DBTableColumn UPDATE_TIMESTAMP;
+
+        public Departments(DBDatabase db)
+        {
+            super("DEPARTMENTS", db);
+            // ID
+            DEPARTMENT_ID   = addColumn("DEPARTMENT_ID",    DataType.AUTOINC,       0, true, "DEP_ID_SEQUENCE");
+            NAME            = addColumn("NAME",             DataType.TEXT,         80, true);
+            HEAD            = addColumn("HEAD",             DataType.TEXT,         80, false);
+            BUSINESS_UNIT   = addColumn("BUSINESS_UNIT",    DataType.TEXT,          4, true, "ITTK");
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,      0, true);
+
+            // Primary Key
+            setPrimaryKey(DEPARTMENT_ID);
+            // Set other Indexes
+            addIndex("DEARTMENT_NAME_IDX", true, new DBColumn[] { NAME });
+            // Set timestamp column for save updates
+            setTimestampColumn(UPDATE_TIMESTAMP);
+        }
+    }
+
+    /**
+     * This class represents the definition of the Employees table.
+     */
+    public static class Employees extends DBTable
+    {
+        private final static long serialVersionUID = 1L;
+      
+        public final DBTableColumn EMPLOYEE_ID;
+        public final DBTableColumn SALUTATION;
+        public final DBTableColumn FIRSTNAME;
+        public final DBTableColumn LASTNAME;
+        public final DBTableColumn DATE_OF_BIRTH;
+        public final DBTableColumn DEPARTMENT_ID;
+        public final DBTableColumn GENDER;
+        public final DBTableColumn PHONE_NUMBER;
+        public final DBTableColumn EMAIL;
+        public final DBTableColumn SALARY;
+        public final DBTableColumn RETIRED;
+        public final DBTableColumn UPDATE_TIMESTAMP;
+
+        public Employees(DBDatabase db)
+        {
+            super("EMPLOYEES", db);
+            // ID
+            EMPLOYEE_ID     = addColumn("EMPLOYEE_ID",      DataType.AUTOINC,      0, true, "EMPLOYEE_ID_SEQUENCE");
+            SALUTATION      = addColumn("SALUTATION",       DataType.TEXT,        20, false);
+            FIRSTNAME       = addColumn("FIRST_NAME",       DataType.TEXT,        40, true);
+            LASTNAME        = addColumn("LAST_NAME",        DataType.TEXT,        40, true);
+            DATE_OF_BIRTH   = addColumn("DATE_OF_BIRTH",    DataType.DATE,         0, false);
+            DEPARTMENT_ID   = addColumn("DEPARTMENT_ID",    DataType.INTEGER,      0, true);
+            GENDER          = addColumn("GENDER",           DataType.TEXT,         1, false);
+            PHONE_NUMBER    = addColumn("PHONE_NUMBER",     DataType.TEXT,        40, false);
+            EMAIL           = addColumn("EMAIL",            DataType.TEXT,        80, false);
+            SALARY          = addColumn("SALARY",           DataType.DECIMAL,   10.2, false);
+            RETIRED         = addColumn("RETIRED",          DataType.BOOL,         0, true, false);
+            UPDATE_TIMESTAMP= addColumn("UPDATE_TIMESTAMP", DataType.DATETIME,     0, true);
+
+            // Primary Key
+            setPrimaryKey(EMPLOYEE_ID);
+            // Set other Indexes
+            addIndex("EMPLOYEE_NAME_IDX", true, new DBColumn[] { FIRSTNAME, LASTNAME, DATE_OF_BIRTH });
+            // Set timestamp column for save updates
+            setTimestampColumn(UPDATE_TIMESTAMP);
+
+            // Create Options for GENDER column
+            Options genders = new Options();
+            genders.set("M", "Male");
+            genders.set("F", "Female");
+            GENDER.setOptions(genders);
+        }
+    }
+
+    // Declare all Tables and Views here
+    public final Departments  DEPARTMENTS = new Departments(this);
+    public final Employees    EMPLOYEES   = new Employees(this);
+
+    /**
+     * Constructor of the SampleDB data model description
+     *
+     * Put all foreign key relations here.
+     */
+    public SampleDB()
+    {
+        // Define Foreign-Key Relations
+        addRelation( EMPLOYEES.DEPARTMENT_ID.referenceOn( DEPARTMENTS.DEPARTMENT_ID ));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleSpringApp.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleSpringApp.java b/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleSpringApp.java
new file mode 100644
index 0000000..3ff0230
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/example1/SampleSpringApp.java
@@ -0,0 +1,86 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring.example1;
+
+import java.util.logging.Logger;
+
+import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.core.io.ClassPathResource;
+
+/**
+ * 
+ */
+public class SampleSpringApp {
+    private static final Logger log = Logger.getLogger(SampleSpringApp.class.getName());
+
+    //creates the application context
+    //this is usually in some bootstrapping code; so your application will
+    //just have one at runtime.
+    static ApplicationContext ctx = getContext();
+
+    //get the service that is the entry point into the application
+    //normally this is injected by spring into classes that need it
+    static EmpireApp appBean = ctx.getBean("empireApp", EmpireApp.class);
+
+    public static void main(String[] args) throws Exception {
+
+        System.out.println("Running Spring Example...");
+
+        appBean.setupDatabase();
+        appBean.clearDatabase();
+        
+        System.out.println("*** Step 6: insertDepartment() & insertEmployee() ***");
+        int idDevDep = appBean.insertDepartment("Development", "ITTK");
+		int idSalDep = appBean.insertDepartment("Sales", "ITTK");
+
+        int idPers1 = appBean.insertEmployee("Peter", "Sharp", "M", idDevDep);
+		int idPers2 = appBean.insertEmployee("Fred", "Bloggs", "M", idDevDep);
+		int idPers3 = appBean.insertEmployee("Emma", "White", "F", idSalDep);
+
+        System.out.println("*** Step 7: updateEmployee() ***");
+        appBean.updateEmployee(idPers1, "+49-7531-457160");
+        appBean.updateEmployee(idPers2, "+49-5555-505050");
+        appBean.updateEmployee(idPers3, "+49-040-125486");
+
+        System.out.println("*** Step 8 Option 1: queryRecords() / Tab-Output ***");
+        appBean.doQuery(EmpireApp.QueryType.Reader);
+
+        System.out.println("*** Step 8 Option 2: queryRecords() / Bean-List-Output ***");
+        appBean.doQuery(EmpireApp.QueryType.BeanList);
+
+        System.out.println("*** Step 8 Option 3: queryRecords() / XML-Output ***");
+        appBean.doQuery(EmpireApp.QueryType.XmlDocument);
+        
+        
+    }
+
+
+
+    static GenericApplicationContext getContext() {
+        log.info("Creating Spring Application Context ...");
+        GenericApplicationContext ctx = new GenericApplicationContext();
+        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(ctx);
+        reader.loadBeanDefinitions(new ClassPathResource("/example1/applicationContext.xml"));
+
+        ctx.refresh();
+        return ctx;
+    }
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/example2/Department.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/example2/Department.java b/empire-db-spring/src/main/java/org/apache/empire/spring/example2/Department.java
new file mode 100644
index 0000000..e56953c
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/example2/Department.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring.example2;
+
+public class Department {
+
+	private Integer departmentId;
+	private String name;
+	private String businessUnit;
+	private String head;
+
+	public Integer getDepartmentId() {
+		return departmentId;
+	}
+
+	public void setDepartmentId(Integer departmentId) {
+		this.departmentId = departmentId;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public String getBusinessUnit() {
+		return businessUnit;
+	}
+
+	public void setBusinessUnit(String businessUnit) {
+		this.businessUnit = businessUnit;
+	}
+
+	public String getHead() {
+		return head;
+	}
+
+	public void setHead(String head) {
+		this.head = head;
+	}
+
+	@Override
+	public String toString() {
+		return this.name;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+
+		if (obj.getClass().equals(this.getClass())) {
+			Department other = (Department) obj;
+			if (other.departmentId == null || this.departmentId == null) {
+				return false;
+			}
+			return this.departmentId.equals(other.departmentId);
+		}
+
+		return super.equals(obj);
+	}
+
+	@Override
+	public int hashCode() {
+		return 1;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/example2/Employee.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/example2/Employee.java b/empire-db-spring/src/main/java/org/apache/empire/spring/example2/Employee.java
new file mode 100644
index 0000000..5a07ce9
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/example2/Employee.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring.example2;
+
+public class Employee {
+
+	public static enum Gender {
+
+		M("Male"), F("Female");
+
+		private String label;
+
+		private Gender(String label) {
+			this.label = label;
+		}
+
+		@Override
+		public String toString() {
+			return this.label;
+		}
+	}
+
+	private Integer employeeId;
+	private String firstName;
+	private String lastName;
+	private Gender gender;
+	private String phoneNumber;
+
+	private Department department;
+
+	public Integer getEmployeeId() {
+		return employeeId;
+	}
+
+	public void setEmployeeId(Integer employeeId) {
+		this.employeeId = employeeId;
+	}
+
+	public String getFirstName() {
+		return firstName;
+	}
+
+	public void setFirstName(String firstName) {
+		this.firstName = firstName;
+	}
+
+	public String getLastName() {
+		return lastName;
+	}
+
+	public void setLastName(String lastName) {
+		this.lastName = lastName;
+	}
+
+	public Gender getGender() {
+		return gender;
+	}
+
+	public void setGender(Gender gender) {
+		this.gender = gender;
+	}
+
+	public String getPhoneNumber() {
+		return phoneNumber;
+	}
+
+	public void setPhoneNumber(String phoneNumber) {
+		this.phoneNumber = phoneNumber;
+	}
+
+	public Department getDepartment() {
+		return department;
+	}
+
+	public void setDepartment(Department department) {
+		this.department = department;
+	}
+
+	@Override
+	public String toString() {
+		StringBuffer buf = new StringBuffer();
+		buf.append(employeeId);
+		buf.append("\t");
+		buf.append(firstName);
+		buf.append(" ");
+		buf.append(lastName);
+		buf.append("\t");
+		buf.append(gender);
+		
+		if (department != null){
+			buf.append("\t");
+			buf.append(department.getName());	
+			buf.append("\t");
+			buf.append(department.getBusinessUnit());	
+		}
+		return buf.toString();
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj) {
+			return true;
+		}
+		if (obj == null) {
+			return false;
+		}
+
+		if (obj.getClass().equals(this.getClass())) {
+			Employee other = (Employee) obj;
+			if (other.employeeId == null || this.employeeId == null) {
+				return false;
+			}
+			return this.employeeId.equals(other.employeeId);
+		}
+
+		return super.equals(obj);
+	}
+
+	@Override
+	public int hashCode() {
+		return 1;
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/empire-db/blob/20ecbae8/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeDao.java
----------------------------------------------------------------------
diff --git a/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeDao.java b/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeDao.java
new file mode 100644
index 0000000..ad02b46
--- /dev/null
+++ b/empire-db-spring/src/main/java/org/apache/empire/spring/example2/EmployeeDao.java
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.empire.spring.example2;
+
+import java.util.List;
+
+public interface EmployeeDao {
+
+	public List<Employee> getEmployees();
+
+	public Integer createEmployee(Employee employee);
+
+	public void updateEmployee(Employee employee);
+
+	public Employee openEmployee(Integer id);
+
+	public Employee findEmployee(String firstName, String lastName);
+
+	public Department openDepartment(Integer id);
+
+	public Department findDepartment(String name);
+
+	public Integer createDepartment(Department department);
+
+	public void updateDepartment(Department department);
+
+	public void renameDepartment(Integer id, String name);
+
+}