Make behavior of mapping consistant between methods and fields, and handle conflicts between underscores and no underscores by picking the most exact match
This commit is contained in:
parent
f7b1a52ba1
commit
375f8b8413
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@
|
|||||||
**/build
|
**/build
|
||||||
**/target
|
**/target
|
||||||
**~
|
**~
|
||||||
|
**derby.log
|
||||||
|
@ -10,6 +10,22 @@
|
|||||||
</parent>
|
</parent>
|
||||||
<artifactId>beehive-jdbc-mapper</artifactId>
|
<artifactId>beehive-jdbc-mapper</artifactId>
|
||||||
<name>${project.artifactId}</name>
|
<name>${project.artifactId}</name>
|
||||||
|
<properties>
|
||||||
|
<maven.test.skip>false</maven.test.skip>
|
||||||
|
<maven.test.failure.ignore>false</maven.test.failure.ignore>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.derby</groupId>
|
||||||
|
<artifactId>derby</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
<finalName>${project.artifactId}</finalName>
|
<finalName>${project.artifactId}</finalName>
|
||||||
</build>
|
</build>
|
||||||
|
@ -19,7 +19,7 @@ public class QueryMapper implements Closeable {
|
|||||||
method.invoke(null);
|
method.invoke(null);
|
||||||
}catch(Throwable e){
|
}catch(Throwable e){
|
||||||
// ignore
|
// ignore
|
||||||
e.printStackTrace();
|
//e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,24 +341,33 @@ public class RowToObjectMapper<T> extends RowMapper {
|
|||||||
//System.out.printf("method: '%s', isSetterMethod: '%s'\n", m, isSetterMethod(m));
|
//System.out.printf("method: '%s', isSetterMethod: '%s'\n", m, isSetterMethod(m));
|
||||||
if (isSetterMethod(m)) {
|
if (isSetterMethod(m)) {
|
||||||
String fieldName = m.getName().substring(3).toUpperCase();
|
String fieldName = m.getName().substring(3).toUpperCase();
|
||||||
//System.out.println("METHOD-fieldName: "+fieldName);
|
//System.out.println("METHOD-fieldName1: "+fieldName);
|
||||||
AccessibleObject field = mapFields.get(fieldName);
|
if (!mapFields.containsKey(fieldName)) {
|
||||||
if (field == null) {
|
|
||||||
fieldName = strippedKeys.get(fieldName);
|
fieldName = strippedKeys.get(fieldName);
|
||||||
if (fieldName == null)
|
if (fieldName == null)
|
||||||
continue;
|
continue;
|
||||||
field = mapFields.get(fieldName);
|
//System.out.println("METHOD-fieldName2: "+fieldName);
|
||||||
}
|
}
|
||||||
|
final AccessibleObject field = mapFields.get(fieldName);
|
||||||
// check for overloads
|
// check for overloads
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
mapFields.put(fieldName, m);
|
mapFields.put(fieldName, m);
|
||||||
} else {
|
} else {
|
||||||
|
// fix for 'overloaded' methods when it comes to stripped keys, we want the exact match
|
||||||
|
final String thisName = m.getName().substring(3).toUpperCase();
|
||||||
|
final String previousName = ((Method) field).getName().substring(3).toUpperCase();
|
||||||
|
//System.out.printf("thisName: '%s', previousName: '%s', mapFields.containsKey(thisName): %b, strippedKeys.containsKey(previousName): %b\n", thisName, previousName, mapFields.containsKey(thisName), strippedKeys.containsKey(previousName));
|
||||||
|
if(mapFields.containsKey(thisName) && strippedKeys.containsKey(previousName)) {
|
||||||
|
mapFields.put(fieldName, m);
|
||||||
|
} else if (!mapFields.containsKey(previousName) || !strippedKeys.containsKey(thisName)) {
|
||||||
throw new MapperException("Unable to choose between overloaded methods '" + m.getName()
|
throw new MapperException("Unable to choose between overloaded methods '" + m.getName()
|
||||||
+ "' and '"+((Method)field).getName()+"' for field '"+fieldName+"' on the " + _returnTypeClass.getName() + " class. Mapping is done using "
|
+ "' and '" + ((Method) field).getName() + "' for field '" + fieldName + "' on the '" + _returnTypeClass.getName() + "' class. Mapping is done using "
|
||||||
+ "a case insensitive comparison of SQL ResultSet columns to field "
|
+ "a case insensitive comparison of SQL ResultSet columns to field "
|
||||||
+ "names and public setter methods on the return class. Columns are also "
|
+ "names and public setter methods on the return class. Columns are also "
|
||||||
+ "stripped of '_' and compared if no match is found with them.");
|
+ "stripped of '_' and compared if no match is found with them.");
|
||||||
}
|
}
|
||||||
|
// then the 'overloaded' method is already correct
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,9 +386,24 @@ public class RowToObjectMapper<T> extends RowMapper {
|
|||||||
if (fieldName == null)
|
if (fieldName == null)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Object field = mapFields.get(fieldName);
|
final AccessibleObject field = mapFields.get(fieldName);
|
||||||
if (field == null) {
|
if (field == null) {
|
||||||
mapFields.put(fieldName, f);
|
mapFields.put(fieldName, f);
|
||||||
|
} else if(field instanceof Field) {
|
||||||
|
// fix for 'overloaded' fields when it comes to stripped keys, we want the exact match
|
||||||
|
final String thisName = f.getName().toUpperCase();
|
||||||
|
final String previousName = ((Field) field).getName().toUpperCase();
|
||||||
|
//System.out.printf("thisName: '%s', previousName: '%s', mapFields.containsKey(thisName): %b, strippedKeys.containsKey(previousName): %b\n", thisName, previousName, mapFields.containsKey(thisName), strippedKeys.containsKey(previousName));
|
||||||
|
if(mapFields.containsKey(thisName) && strippedKeys.containsKey(previousName)) {
|
||||||
|
mapFields.put(fieldName, f);
|
||||||
|
} else if (!mapFields.containsKey(previousName) || !strippedKeys.containsKey(thisName)) {
|
||||||
|
throw new MapperException("Unable to choose between overloaded fields '" + f.getName()
|
||||||
|
+ "' and '" + ((Field) field).getName() + "' for field '" + fieldName + "' on the '" + _returnTypeClass.getName() + "' class. Mapping is done using "
|
||||||
|
+ "a case insensitive comparison of SQL ResultSet columns to field "
|
||||||
|
+ "names and public setter methods on the return class. Columns are also "
|
||||||
|
+ "stripped of '_' and compared if no match is found with them.");
|
||||||
|
}
|
||||||
|
// then the 'overloaded' field is already correct
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,196 @@
|
|||||||
|
package com.moparisthebest.jdbc;
|
||||||
|
|
||||||
|
import com.moparisthebest.jdbc.dto.*;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static com.moparisthebest.jdbc.TryClose.tryClose;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public class QueryMapperTest {
|
||||||
|
|
||||||
|
private static Connection conn;
|
||||||
|
protected static QueryMapper qm;
|
||||||
|
|
||||||
|
protected static final Person fieldPerson1 = new FieldPerson(1, new Date(0), "First", "Person");
|
||||||
|
protected static final Boss fieldBoss1 = new FieldBoss(2, new Date(0), "Second", "Person", "Finance", "Second");
|
||||||
|
protected static final Boss fieldBoss2 = new FieldBoss(3, new Date(0), "Third", "Person", "Finance", null);
|
||||||
|
protected static final Boss fieldBoss3 = new FieldBoss(4, new Date(0), null, "Person", "Finance", "Fourth");
|
||||||
|
|
||||||
|
protected static final Person setPerson1 = new SetPerson(fieldPerson1);
|
||||||
|
protected static final Boss setBoss1 = new SetBoss(fieldBoss1);
|
||||||
|
protected static final Boss setBoss2 = new SetBoss(fieldBoss2);
|
||||||
|
protected static final Boss setBoss3 = new SetBoss(fieldBoss3);
|
||||||
|
|
||||||
|
protected static final Person reverseFieldPerson1 = new ReverseFieldPerson(fieldPerson1);
|
||||||
|
protected static final Boss reverseFieldBoss1 = new ReverseFieldBoss(fieldBoss1);
|
||||||
|
protected static final Boss reverseFieldBoss2 = new ReverseFieldBoss(fieldBoss2);
|
||||||
|
protected static final Boss reverseFieldBoss3 = new ReverseFieldBoss(fieldBoss3);
|
||||||
|
|
||||||
|
protected static final Person reverseSetPerson1 = new ReverseSetPerson(fieldPerson1);
|
||||||
|
protected static final Boss reverseSetBoss1 = new ReverseSetBoss(fieldBoss1);
|
||||||
|
protected static final Boss reverseSetBoss2 = new ReverseSetBoss(fieldBoss2);
|
||||||
|
protected static final Boss reverseSetBoss3 = new ReverseSetBoss(fieldBoss3);
|
||||||
|
|
||||||
|
protected static final String personRegular = "SELECT * FROM person WHERE person_no = ?";
|
||||||
|
protected static final String bossRegularAndUnderscore = "SELECT p.person_no, p.first_name AS firstName, p.last_name, p.birth_date, b.department, p.first_name " +
|
||||||
|
"FROM person p " +
|
||||||
|
"JOIN boss b ON p.person_no = b.person_no " +
|
||||||
|
"WHERE p.person_no = ?";
|
||||||
|
protected static final String bossRegularAndUnderscoreReverse = "SELECT p.person_no, p.first_name, p.last_name, p.birth_date, b.department, p.first_name AS firstName " +
|
||||||
|
"FROM person p " +
|
||||||
|
"JOIN boss b ON p.person_no = b.person_no " +
|
||||||
|
"WHERE p.person_no = ?";
|
||||||
|
protected static final String bossRegular = "SELECT p.person_no, p.first_name AS firstName, p.last_name, p.birth_date, b.department " +
|
||||||
|
"FROM person p " +
|
||||||
|
"JOIN boss b ON p.person_no = b.person_no " +
|
||||||
|
"WHERE p.person_no = ?";
|
||||||
|
protected static final String bossUnderscore = "SELECT p.person_no, p.first_name, p.last_name, p.birth_date, b.department " +
|
||||||
|
"FROM person p " +
|
||||||
|
"JOIN boss b ON p.person_no = b.person_no " +
|
||||||
|
"WHERE p.person_no = ?";
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUp() throws Throwable {
|
||||||
|
Class.forName("org.apache.derby.jdbc.EmbeddedDriver").newInstance();
|
||||||
|
conn = DriverManager.getConnection("jdbc:derby:memory:derbyDB;create=true");
|
||||||
|
qm = new QueryMapper(conn);
|
||||||
|
qm.executeUpdate("CREATE TABLE person (person_no NUMERIC, first_name VARCHAR(40), last_name VARCHAR(40), birth_date TIMESTAMP)");
|
||||||
|
qm.executeUpdate("CREATE TABLE boss (person_no NUMERIC, department VARCHAR(40))");
|
||||||
|
for (final Person person : new Person[]{fieldPerson1})
|
||||||
|
qm.executeUpdate("INSERT INTO person (person_no, birth_date, last_name, first_name) VALUES (?, ?, ?, ?)", person.getPersonNo(), person.getBirthDate(), person.getLastName(), person.getFirstName());
|
||||||
|
for (final Boss boss : new Boss[]{fieldBoss1, fieldBoss2, fieldBoss3}) {
|
||||||
|
qm.executeUpdate("INSERT INTO person (person_no, birth_date, last_name, first_name) VALUES (?, ?, ?, ?)", boss.getPersonNo(), boss.getBirthDate(), boss.getLastName(), boss.getFirstName() == null ? boss.getFirst_name() : boss.getFirstName());
|
||||||
|
qm.executeUpdate("INSERT INTO boss (person_no, department) VALUES (?, ?)", boss.getPersonNo(), boss.getDepartment());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterClass
|
||||||
|
public static void tearDown() throws Throwable {
|
||||||
|
tryClose(qm);
|
||||||
|
tryClose(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fields
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldRegularPerson() throws Throwable {
|
||||||
|
testPerson(fieldPerson1, personRegular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldRegularAndUnderscore() throws Throwable {
|
||||||
|
testPerson(fieldBoss1, bossRegularAndUnderscore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldRegularAndUnderscoreReverse() throws Throwable {
|
||||||
|
testPerson(fieldBoss1, bossRegularAndUnderscoreReverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldRegular() throws Throwable {
|
||||||
|
testPerson(fieldBoss2, bossRegular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFieldUnderscore() throws Throwable {
|
||||||
|
testPerson(fieldBoss3, bossUnderscore);
|
||||||
|
}
|
||||||
|
|
||||||
|
// sets
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetRegularPerson() throws Throwable {
|
||||||
|
testPerson(setPerson1, personRegular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetRegularAndUnderscore() throws Throwable {
|
||||||
|
testPerson(setBoss1, bossRegularAndUnderscore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetRegularAndUnderscoreReverse() throws Throwable {
|
||||||
|
testPerson(setBoss1, bossRegularAndUnderscoreReverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetRegular() throws Throwable {
|
||||||
|
testPerson(setBoss2, bossRegular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetUnderscore() throws Throwable {
|
||||||
|
testPerson(setBoss3, bossUnderscore);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reverse fields
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReverseFieldRegularPerson() throws Throwable {
|
||||||
|
testPerson(reverseFieldPerson1, personRegular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReverseFieldRegularAndUnderscore() throws Throwable {
|
||||||
|
testPerson(reverseFieldBoss1, bossRegularAndUnderscore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReverseFieldRegularAndUnderscoreReverse() throws Throwable {
|
||||||
|
testPerson(reverseFieldBoss1, bossRegularAndUnderscoreReverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReverseFieldRegular() throws Throwable {
|
||||||
|
testPerson(reverseFieldBoss3, bossRegular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReverseFieldUnderscore() throws Throwable {
|
||||||
|
testPerson(reverseFieldBoss2, bossUnderscore);
|
||||||
|
}
|
||||||
|
|
||||||
|
// reverse sets
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReverseSetRegularPerson() throws Throwable {
|
||||||
|
testPerson(reverseSetPerson1, personRegular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReverseSetRegularAndUnderscore() throws Throwable {
|
||||||
|
testPerson(reverseSetBoss1, bossRegularAndUnderscore);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReverseSetRegularAndUnderscoreReverse() throws Throwable {
|
||||||
|
testPerson(reverseSetBoss1, bossRegularAndUnderscoreReverse);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReverseSetRegular() throws Throwable {
|
||||||
|
testPerson(reverseSetBoss3, bossRegular);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReverseSetUnderscore() throws Throwable {
|
||||||
|
testPerson(reverseSetBoss2, bossUnderscore);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testPerson(final Person expected, final String query) throws Throwable {
|
||||||
|
final Person actual = qm.toObject(query, expected.getClass(), expected.getPersonNo());
|
||||||
|
//System.out.println("expected: " + expected);
|
||||||
|
//System.out.println("actual: " + actual);
|
||||||
|
Assert.assertEquals(expected, actual);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,488 @@
|
|||||||
|
package com.moparisthebest.jdbc;
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Derby - Class SimpleApp
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DriverManager;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Statement;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* This sample program is a minimal Java application showing JDBC access to a
|
||||||
|
* Derby database.</p>
|
||||||
|
* <p>
|
||||||
|
* Instructions for how to run this program are
|
||||||
|
* given in <A HREF=example.html>example.html</A>, by default located in the
|
||||||
|
* same directory as this source file ($DERBY_HOME/demo/programs/simple/).</p>
|
||||||
|
* <p>
|
||||||
|
* Derby applications can run against Derby running in an embedded
|
||||||
|
* or a client/server framework.</p>
|
||||||
|
* <p>
|
||||||
|
* When Derby runs in an embedded framework, the JDBC application and Derby
|
||||||
|
* run in the same Java Virtual Machine (JVM). The application
|
||||||
|
* starts up the Derby engine.</p>
|
||||||
|
* <p>
|
||||||
|
* When Derby runs in a client/server framework, the application runs in a
|
||||||
|
* different JVM from Derby. The application only needs to load the client
|
||||||
|
* driver, and the connectivity framework (in this case the Derby Network
|
||||||
|
* Server) provides network connections.</p>
|
||||||
|
*/
|
||||||
|
public class SimpleApp
|
||||||
|
{
|
||||||
|
/* the default framework is embedded*/
|
||||||
|
private String framework = "embedded";
|
||||||
|
private String driver = "org.apache.derby.jdbc.EmbeddedDriver";
|
||||||
|
private String protocol = "jdbc:derby:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Starts the demo by creating a new instance of this class and running
|
||||||
|
* the <code>go()</code> method.</p>
|
||||||
|
* <p>
|
||||||
|
* When you run this application, you may give one of the following
|
||||||
|
* arguments:
|
||||||
|
* <ul>
|
||||||
|
<li><code>embedded</code> - default, if none specified. Will use
|
||||||
|
* Derby's embedded driver. This driver is included in the derby.jar
|
||||||
|
* file.</li>
|
||||||
|
* <li><code>derbyclient</code> - will use the Derby client driver to
|
||||||
|
* access the Derby Network Server. This driver is included in the
|
||||||
|
* derbyclient.jar file.</li>
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* When you are using a client/server framework, the network server must
|
||||||
|
* already be running when trying to obtain client connections to Derby.
|
||||||
|
* This demo program will will try to connect to a network server on this
|
||||||
|
* host (the localhost), see the <code>protocol</code> instance variable.
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* When running this demo, you must include the correct driver in the
|
||||||
|
* classpath of the JVM. See <a href="example.html">example.html</a> for
|
||||||
|
* details.
|
||||||
|
* </p>
|
||||||
|
* @param args This program accepts one optional argument specifying which
|
||||||
|
* connection framework (JDBC driver) to use (see above). The default
|
||||||
|
* is to use the embedded JDBC driver.
|
||||||
|
*/
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
new SimpleApp().go(args);
|
||||||
|
System.out.println("SimpleApp finished");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Starts the actual demo activities. This includes loading the correct
|
||||||
|
* JDBC driver, creating a database by making a connection to Derby,
|
||||||
|
* creating a table in the database, and inserting, updating and retrieving
|
||||||
|
* some data. Some of the retrieved data is then verified (compared) against
|
||||||
|
* the expected results. Finally, the table is deleted and, if the embedded
|
||||||
|
* framework is used, the database is shut down.</p>
|
||||||
|
* <p>
|
||||||
|
* Generally, when using a client/server framework, other clients may be
|
||||||
|
* (or want to be) connected to the database, so you should be careful about
|
||||||
|
* doing shutdown unless you know that no one else needs to access the
|
||||||
|
* database until it is rebooted. That is why this demo will not shut down
|
||||||
|
* the database unless it is running Derby embedded.</p>
|
||||||
|
*
|
||||||
|
* @param args - Optional argument specifying which framework or JDBC driver
|
||||||
|
* to use to connect to Derby. Default is the embedded framework,
|
||||||
|
* see the <code>main()</code> method for details.
|
||||||
|
* @see #main(String[])
|
||||||
|
*/
|
||||||
|
void go(String[] args)
|
||||||
|
{
|
||||||
|
/* parse the arguments to determine which framework is desired*/
|
||||||
|
parseArguments(args);
|
||||||
|
|
||||||
|
System.out.println("SimpleApp starting in " + framework + " mode");
|
||||||
|
|
||||||
|
/* load the desired JDBC driver */
|
||||||
|
loadDriver();
|
||||||
|
|
||||||
|
/* We will be using Statement and PreparedStatement objects for
|
||||||
|
* executing SQL. These objects, as well as Connections and ResultSets,
|
||||||
|
* are resources that should be released explicitly after use, hence
|
||||||
|
* the try-catch-finally pattern used below.
|
||||||
|
* We are storing the Statement and Prepared statement object references
|
||||||
|
* in an array list for convenience.
|
||||||
|
*/
|
||||||
|
Connection conn = null;
|
||||||
|
/* This ArrayList usage may cause a warning when compiling this class
|
||||||
|
* with a compiler for J2SE 5.0 or newer. We are not using generics
|
||||||
|
* because we want the source to support J2SE 1.4.2 environments. */
|
||||||
|
ArrayList statements = new ArrayList(); // list of Statements, PreparedStatements
|
||||||
|
PreparedStatement psInsert = null;
|
||||||
|
PreparedStatement psUpdate = null;
|
||||||
|
Statement s = null;
|
||||||
|
ResultSet rs = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Properties props = new Properties(); // connection properties
|
||||||
|
// providing a user name and password is optional in the embedded
|
||||||
|
// and derbyclient frameworks
|
||||||
|
props.put("user", "user1");
|
||||||
|
props.put("password", "user1");
|
||||||
|
|
||||||
|
/* By default, the schema APP will be used when no username is
|
||||||
|
* provided.
|
||||||
|
* Otherwise, the schema name is the same as the user name (in this
|
||||||
|
* case "user1" or USER1.)
|
||||||
|
*
|
||||||
|
* Note that user authentication is off by default, meaning that any
|
||||||
|
* user can connect to your database using any password. To enable
|
||||||
|
* authentication, see the Derby Developer's Guide.
|
||||||
|
*/
|
||||||
|
|
||||||
|
String dbName = "derbyDB"; // the name of the database
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This connection specifies create=true in the connection URL to
|
||||||
|
* cause the database to be created when connecting for the first
|
||||||
|
* time. To remove the database, remove the directory derbyDB (the
|
||||||
|
* same as the database name) and its contents.
|
||||||
|
*
|
||||||
|
* The directory derbyDB will be created under the directory that
|
||||||
|
* the system property derby.system.home points to, or the current
|
||||||
|
* directory (user.dir) if derby.system.home is not set.
|
||||||
|
*/
|
||||||
|
conn = DriverManager.getConnection(protocol + dbName
|
||||||
|
+ ";create=true", props);
|
||||||
|
|
||||||
|
System.out.println("Connected to and created database " + dbName);
|
||||||
|
|
||||||
|
// We want to control transactions manually. Autocommit is on by
|
||||||
|
// default in JDBC.
|
||||||
|
conn.setAutoCommit(false);
|
||||||
|
|
||||||
|
/* Creating a statement object that we can use for running various
|
||||||
|
* SQL statements commands against the database.*/
|
||||||
|
s = conn.createStatement();
|
||||||
|
statements.add(s);
|
||||||
|
|
||||||
|
// We create a table...
|
||||||
|
s.execute("create table location(num int, addr varchar(40))");
|
||||||
|
System.out.println("Created table location");
|
||||||
|
|
||||||
|
// and add a few rows...
|
||||||
|
|
||||||
|
/* It is recommended to use PreparedStatements when you are
|
||||||
|
* repeating execution of an SQL statement. PreparedStatements also
|
||||||
|
* allows you to parameterize variables. By using PreparedStatements
|
||||||
|
* you may increase performance (because the Derby engine does not
|
||||||
|
* have to recompile the SQL statement each time it is executed) and
|
||||||
|
* improve security (because of Java type checking).
|
||||||
|
*/
|
||||||
|
// parameter 1 is num (int), parameter 2 is addr (varchar)
|
||||||
|
psInsert = conn.prepareStatement(
|
||||||
|
"insert into location values (?, ?)");
|
||||||
|
statements.add(psInsert);
|
||||||
|
|
||||||
|
psInsert.setInt(1, 1956);
|
||||||
|
psInsert.setString(2, "Webster St.");
|
||||||
|
psInsert.executeUpdate();
|
||||||
|
System.out.println("Inserted 1956 Webster");
|
||||||
|
|
||||||
|
psInsert.setInt(1, 1910);
|
||||||
|
psInsert.setString(2, "Union St.");
|
||||||
|
psInsert.executeUpdate();
|
||||||
|
System.out.println("Inserted 1910 Union");
|
||||||
|
|
||||||
|
// Let's update some rows as well...
|
||||||
|
|
||||||
|
// parameter 1 and 3 are num (int), parameter 2 is addr (varchar)
|
||||||
|
psUpdate = conn.prepareStatement(
|
||||||
|
"update location set num=?, addr=? where num=?");
|
||||||
|
statements.add(psUpdate);
|
||||||
|
|
||||||
|
psUpdate.setInt(1, 180);
|
||||||
|
psUpdate.setString(2, "Grand Ave.");
|
||||||
|
psUpdate.setInt(3, 1956);
|
||||||
|
psUpdate.executeUpdate();
|
||||||
|
System.out.println("Updated 1956 Webster to 180 Grand");
|
||||||
|
|
||||||
|
psUpdate.setInt(1, 300);
|
||||||
|
psUpdate.setString(2, "Lakeshore Ave.");
|
||||||
|
psUpdate.setInt(3, 180);
|
||||||
|
psUpdate.executeUpdate();
|
||||||
|
System.out.println("Updated 180 Grand to 300 Lakeshore");
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
We select the rows and verify the results.
|
||||||
|
*/
|
||||||
|
rs = s.executeQuery(
|
||||||
|
"SELECT num, addr FROM location ORDER BY num");
|
||||||
|
|
||||||
|
/* we expect the first returned column to be an integer (num),
|
||||||
|
* and second to be a String (addr). Rows are sorted by street
|
||||||
|
* number (num).
|
||||||
|
*
|
||||||
|
* Normally, it is best to use a pattern of
|
||||||
|
* while(rs.next()) {
|
||||||
|
* // do something with the result set
|
||||||
|
* }
|
||||||
|
* to process all returned rows, but we are only expecting two rows
|
||||||
|
* this time, and want the verification code to be easy to
|
||||||
|
* comprehend, so we use a different pattern.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int number; // street number retrieved from the database
|
||||||
|
boolean failure = false;
|
||||||
|
if (!rs.next())
|
||||||
|
{
|
||||||
|
failure = true;
|
||||||
|
reportFailure("No rows in ResultSet");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((number = rs.getInt(1)) != 300)
|
||||||
|
{
|
||||||
|
failure = true;
|
||||||
|
reportFailure(
|
||||||
|
"Wrong row returned, expected num=300, got " + number);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rs.next())
|
||||||
|
{
|
||||||
|
failure = true;
|
||||||
|
reportFailure("Too few rows");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((number = rs.getInt(1)) != 1910)
|
||||||
|
{
|
||||||
|
failure = true;
|
||||||
|
reportFailure(
|
||||||
|
"Wrong row returned, expected num=1910, got " + number);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rs.next())
|
||||||
|
{
|
||||||
|
failure = true;
|
||||||
|
reportFailure("Too many rows");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failure) {
|
||||||
|
System.out.println("Verified the rows");
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete the table
|
||||||
|
s.execute("drop table location");
|
||||||
|
System.out.println("Dropped table location");
|
||||||
|
|
||||||
|
/*
|
||||||
|
We commit the transaction. Any changes will be persisted to
|
||||||
|
the database now.
|
||||||
|
*/
|
||||||
|
conn.commit();
|
||||||
|
System.out.println("Committed the transaction");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* In embedded mode, an application should shut down the database.
|
||||||
|
* If the application fails to shut down the database,
|
||||||
|
* Derby will not perform a checkpoint when the JVM shuts down.
|
||||||
|
* This means that it will take longer to boot (connect to) the
|
||||||
|
* database the next time, because Derby needs to perform a recovery
|
||||||
|
* operation.
|
||||||
|
*
|
||||||
|
* It is also possible to shut down the Derby system/engine, which
|
||||||
|
* automatically shuts down all booted databases.
|
||||||
|
*
|
||||||
|
* Explicitly shutting down the database or the Derby engine with
|
||||||
|
* the connection URL is preferred. This style of shutdown will
|
||||||
|
* always throw an SQLException.
|
||||||
|
*
|
||||||
|
* Not shutting down when in a client environment, see method
|
||||||
|
* Javadoc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (framework.equals("embedded"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// the shutdown=true attribute shuts down Derby
|
||||||
|
DriverManager.getConnection("jdbc:derby:;shutdown=true");
|
||||||
|
|
||||||
|
// To shut down a specific database only, but keep the
|
||||||
|
// engine running (for example for connecting to other
|
||||||
|
// databases), specify a database in the connection URL:
|
||||||
|
//DriverManager.getConnection("jdbc:derby:" + dbName + ";shutdown=true");
|
||||||
|
}
|
||||||
|
catch (SQLException se)
|
||||||
|
{
|
||||||
|
if (( (se.getErrorCode() == 50000)
|
||||||
|
&& ("XJ015".equals(se.getSQLState()) ))) {
|
||||||
|
// we got the expected exception
|
||||||
|
System.out.println("Derby shut down normally");
|
||||||
|
// Note that for single database shutdown, the expected
|
||||||
|
// SQL state is "08006", and the error code is 45000.
|
||||||
|
} else {
|
||||||
|
// if the error code or SQLState is different, we have
|
||||||
|
// an unexpected exception (shutdown failed)
|
||||||
|
System.err.println("Derby did not shut down normally");
|
||||||
|
printSQLException(se);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SQLException sqle)
|
||||||
|
{
|
||||||
|
printSQLException(sqle);
|
||||||
|
} finally {
|
||||||
|
// release all open resources to avoid unnecessary memory usage
|
||||||
|
|
||||||
|
// ResultSet
|
||||||
|
try {
|
||||||
|
if (rs != null) {
|
||||||
|
rs.close();
|
||||||
|
rs = null;
|
||||||
|
}
|
||||||
|
} catch (SQLException sqle) {
|
||||||
|
printSQLException(sqle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Statements and PreparedStatements
|
||||||
|
int i = 0;
|
||||||
|
while (!statements.isEmpty()) {
|
||||||
|
// PreparedStatement extend Statement
|
||||||
|
Statement st = (Statement)statements.remove(i);
|
||||||
|
try {
|
||||||
|
if (st != null) {
|
||||||
|
st.close();
|
||||||
|
st = null;
|
||||||
|
}
|
||||||
|
} catch (SQLException sqle) {
|
||||||
|
printSQLException(sqle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Connection
|
||||||
|
try {
|
||||||
|
if (conn != null) {
|
||||||
|
conn.close();
|
||||||
|
conn = null;
|
||||||
|
}
|
||||||
|
} catch (SQLException sqle) {
|
||||||
|
printSQLException(sqle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the appropriate JDBC driver for this environment/framework. For
|
||||||
|
* example, if we are in an embedded environment, we load Derby's
|
||||||
|
* embedded Driver, <code>org.apache.derby.jdbc.EmbeddedDriver</code>.
|
||||||
|
*/
|
||||||
|
private void loadDriver() {
|
||||||
|
/*
|
||||||
|
* The JDBC driver is loaded by loading its class.
|
||||||
|
* If you are using JDBC 4.0 (Java SE 6) or newer, JDBC drivers may
|
||||||
|
* be automatically loaded, making this code optional.
|
||||||
|
*
|
||||||
|
* In an embedded environment, this will also start up the Derby
|
||||||
|
* engine (though not any databases), since it is not already
|
||||||
|
* running. In a client environment, the Derby engine is being run
|
||||||
|
* by the network server framework.
|
||||||
|
*
|
||||||
|
* In an embedded environment, any static Derby system properties
|
||||||
|
* must be set before loading the driver to take effect.
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
Class.forName(driver).newInstance();
|
||||||
|
System.out.println("Loaded the appropriate driver");
|
||||||
|
} catch (ClassNotFoundException cnfe) {
|
||||||
|
System.err.println("\nUnable to load the JDBC driver " + driver);
|
||||||
|
System.err.println("Please check your CLASSPATH.");
|
||||||
|
cnfe.printStackTrace(System.err);
|
||||||
|
} catch (InstantiationException ie) {
|
||||||
|
System.err.println(
|
||||||
|
"\nUnable to instantiate the JDBC driver " + driver);
|
||||||
|
ie.printStackTrace(System.err);
|
||||||
|
} catch (IllegalAccessException iae) {
|
||||||
|
System.err.println(
|
||||||
|
"\nNot allowed to access the JDBC driver " + driver);
|
||||||
|
iae.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reports a data verification failure to System.err with the given message.
|
||||||
|
*
|
||||||
|
* @param message A message describing what failed.
|
||||||
|
*/
|
||||||
|
private void reportFailure(String message) {
|
||||||
|
System.err.println("\nData verification failed:");
|
||||||
|
System.err.println('\t' + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints details of an SQLException chain to <code>System.err</code>.
|
||||||
|
* Details included are SQL State, Error code, Exception message.
|
||||||
|
*
|
||||||
|
* @param e the SQLException from which to print details.
|
||||||
|
*/
|
||||||
|
public static void printSQLException(SQLException e)
|
||||||
|
{
|
||||||
|
// Unwraps the entire exception chain to unveil the real cause of the
|
||||||
|
// Exception.
|
||||||
|
while (e != null)
|
||||||
|
{
|
||||||
|
System.err.println("\n----- SQLException -----");
|
||||||
|
System.err.println(" SQL State: " + e.getSQLState());
|
||||||
|
System.err.println(" Error Code: " + e.getErrorCode());
|
||||||
|
System.err.println(" Message: " + e.getMessage());
|
||||||
|
// for stack traces, refer to derby.log or uncomment this:
|
||||||
|
//e.printStackTrace(System.err);
|
||||||
|
e = e.getNextException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the arguments given and sets the values of this class' instance
|
||||||
|
* variables accordingly - that is which framework to use, the name of the
|
||||||
|
* JDBC driver class, and which connection protocol protocol to use. The
|
||||||
|
* protocol should be used as part of the JDBC URL when connecting to Derby.
|
||||||
|
* <p>
|
||||||
|
* If the argument is "embedded" or invalid, this method will not change
|
||||||
|
* anything, meaning that the default values will be used.</p>
|
||||||
|
* <p>
|
||||||
|
* @param args JDBC connection framework, either "embedded", "derbyclient".
|
||||||
|
* Only the first argument will be considered, the rest will be ignored.
|
||||||
|
*/
|
||||||
|
private void parseArguments(String[] args)
|
||||||
|
{
|
||||||
|
if (args.length > 0) {
|
||||||
|
if (args[0].equalsIgnoreCase("derbyclient"))
|
||||||
|
{
|
||||||
|
framework = "derbyclient";
|
||||||
|
driver = "org.apache.derby.jdbc.ClientDriver";
|
||||||
|
protocol = "jdbc:derby://localhost:1527/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package com.moparisthebest.jdbc.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public interface Boss extends Person {
|
||||||
|
public String getDepartment();
|
||||||
|
|
||||||
|
public String getFirst_name();
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package com.moparisthebest.jdbc.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public class FieldBoss extends FieldPerson implements Boss {
|
||||||
|
protected String department;
|
||||||
|
protected String first_name;
|
||||||
|
|
||||||
|
protected FieldBoss() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldBoss(long personNo, Date birthDate, String firstName, String lastName, String department, String first_name) {
|
||||||
|
super(personNo, birthDate, firstName, lastName);
|
||||||
|
this.department = department;
|
||||||
|
this.first_name = first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldBoss(Boss boss) {
|
||||||
|
super(boss);
|
||||||
|
this.department = boss.getDepartment();
|
||||||
|
this.first_name = boss.getFirst_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDepartment() {
|
||||||
|
return department;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirst_name() {
|
||||||
|
return first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof FieldBoss)) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
|
||||||
|
FieldBoss boss = (FieldBoss) o;
|
||||||
|
|
||||||
|
if (department != null ? !department.equals(boss.department) : boss.department != null) return false;
|
||||||
|
if (first_name != null ? !first_name.equals(boss.first_name) : boss.first_name != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = 31 * result + (department != null ? department.hashCode() : 0);
|
||||||
|
result = 31 * result + (first_name != null ? first_name.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName()+"{" +
|
||||||
|
"department='" + department + '\'' +
|
||||||
|
", first_name='" + first_name + '\'' +
|
||||||
|
"} " + super.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package com.moparisthebest.jdbc.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public class FieldPerson implements Person {
|
||||||
|
|
||||||
|
protected long personNo;
|
||||||
|
protected Date birthDate;
|
||||||
|
protected String firstName;
|
||||||
|
protected String lastName;
|
||||||
|
|
||||||
|
protected FieldPerson(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldPerson(long personNo, Date birthDate, String firstName, String lastName) {
|
||||||
|
this.personNo = personNo;
|
||||||
|
this.birthDate = birthDate;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FieldPerson(Person person) {
|
||||||
|
this.personNo = person.getPersonNo();
|
||||||
|
this.birthDate = person.getBirthDate();
|
||||||
|
this.lastName = person.getLastName();
|
||||||
|
this.firstName = person.getFirstName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPersonNo() {
|
||||||
|
return personNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getBirthDate() {
|
||||||
|
return birthDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof FieldPerson)) return false;
|
||||||
|
|
||||||
|
FieldPerson person = (FieldPerson) o;
|
||||||
|
|
||||||
|
if (personNo != person.personNo) return false;
|
||||||
|
if (birthDate != null ? !birthDate.equals(person.birthDate) : person.birthDate != null) return false;
|
||||||
|
if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) return false;
|
||||||
|
if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = (int) (personNo ^ (personNo >>> 32));
|
||||||
|
result = 31 * result + (birthDate != null ? birthDate.hashCode() : 0);
|
||||||
|
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
|
||||||
|
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName()+"{" +
|
||||||
|
"personNo=" + personNo +
|
||||||
|
", birthDate=" + birthDate +
|
||||||
|
", firstName='" + firstName + '\'' +
|
||||||
|
", lastName='" + lastName + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.moparisthebest.jdbc.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public interface Person {
|
||||||
|
|
||||||
|
public long getPersonNo();
|
||||||
|
|
||||||
|
public Date getBirthDate();
|
||||||
|
|
||||||
|
public String getFirstName();
|
||||||
|
|
||||||
|
public String getLastName();
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package com.moparisthebest.jdbc.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public class ReverseFieldBoss extends ReverseFieldPerson implements Boss {
|
||||||
|
protected String department;
|
||||||
|
protected String firstName;
|
||||||
|
|
||||||
|
protected ReverseFieldBoss() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReverseFieldBoss(long personNo, Date birthDate, String firstName, String lastName, String department, String first_name) {
|
||||||
|
super(personNo, birthDate, firstName, lastName);
|
||||||
|
this.department = department;
|
||||||
|
this.firstName = first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReverseFieldBoss(Boss boss) {
|
||||||
|
super(boss);
|
||||||
|
this.department = boss.getDepartment();
|
||||||
|
this.firstName = boss.getFirst_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDepartment() {
|
||||||
|
return department;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirst_name() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof ReverseFieldBoss)) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
|
||||||
|
ReverseFieldBoss boss = (ReverseFieldBoss) o;
|
||||||
|
|
||||||
|
if (department != null ? !department.equals(boss.department) : boss.department != null) return false;
|
||||||
|
if (firstName != null ? !firstName.equals(boss.firstName) : boss.firstName != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = 31 * result + (department != null ? department.hashCode() : 0);
|
||||||
|
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName()+"{" +
|
||||||
|
"department='" + department + '\'' +
|
||||||
|
", firstName='" + firstName + '\'' +
|
||||||
|
"} " + super.toString();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
package com.moparisthebest.jdbc.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public class ReverseFieldPerson implements Person {
|
||||||
|
|
||||||
|
protected long personNo;
|
||||||
|
protected Date birthDate;
|
||||||
|
protected String first_name;
|
||||||
|
protected String lastName;
|
||||||
|
|
||||||
|
protected ReverseFieldPerson(){
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReverseFieldPerson(long personNo, Date birthDate, String firstName, String lastName) {
|
||||||
|
this.personNo = personNo;
|
||||||
|
this.birthDate = birthDate;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.first_name = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReverseFieldPerson(Person person) {
|
||||||
|
this.personNo = person.getPersonNo();
|
||||||
|
this.birthDate = person.getBirthDate();
|
||||||
|
this.lastName = person.getLastName();
|
||||||
|
this.first_name = person.getFirstName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getPersonNo() {
|
||||||
|
return personNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getBirthDate() {
|
||||||
|
return birthDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof ReverseFieldPerson)) return false;
|
||||||
|
|
||||||
|
ReverseFieldPerson person = (ReverseFieldPerson) o;
|
||||||
|
|
||||||
|
if (personNo != person.personNo) return false;
|
||||||
|
if (birthDate != null ? !birthDate.equals(person.birthDate) : person.birthDate != null) return false;
|
||||||
|
if (first_name != null ? !first_name.equals(person.first_name) : person.first_name != null) return false;
|
||||||
|
if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = (int) (personNo ^ (personNo >>> 32));
|
||||||
|
result = 31 * result + (birthDate != null ? birthDate.hashCode() : 0);
|
||||||
|
result = 31 * result + (first_name != null ? first_name.hashCode() : 0);
|
||||||
|
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName()+"{" +
|
||||||
|
"personNo=" + personNo +
|
||||||
|
", birthDate=" + birthDate +
|
||||||
|
", first_name='" + first_name + '\'' +
|
||||||
|
", lastName='" + lastName + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package com.moparisthebest.jdbc.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public class ReverseSetBoss extends ReverseSetPerson implements Boss {
|
||||||
|
protected String department;
|
||||||
|
protected String firstName;
|
||||||
|
|
||||||
|
protected ReverseSetBoss() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReverseSetBoss(long personNo, Date birthDate, String firstName, String lastName, String department, String first_name) {
|
||||||
|
super(personNo, birthDate, firstName, lastName);
|
||||||
|
this.department = department;
|
||||||
|
this.firstName = first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReverseSetBoss(Boss boss) {
|
||||||
|
super(boss);
|
||||||
|
this.department = boss.getDepartment();
|
||||||
|
this.firstName = boss.getFirst_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDepartment() {
|
||||||
|
return department;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirst_name() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof ReverseSetBoss)) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
|
||||||
|
ReverseSetBoss boss = (ReverseSetBoss) o;
|
||||||
|
|
||||||
|
if (department != null ? !department.equals(boss.department) : boss.department != null) return false;
|
||||||
|
if (firstName != null ? !firstName.equals(boss.firstName) : boss.firstName != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = 31 * result + (department != null ? department.hashCode() : 0);
|
||||||
|
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName()+"{" +
|
||||||
|
"department='" + department + '\'' +
|
||||||
|
", firstName='" + firstName + '\'' +
|
||||||
|
"} " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDepartment(String department) {
|
||||||
|
this.department = department;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.moparisthebest.jdbc.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public class ReverseSetPerson extends ReverseFieldPerson {
|
||||||
|
protected ReverseSetPerson() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReverseSetPerson(long personNo, Date birthDate, String firstName, String lastName) {
|
||||||
|
super(personNo, birthDate, firstName, lastName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReverseSetPerson(Person person) {
|
||||||
|
super(person);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPersonNo(long personNo) {
|
||||||
|
this.personNo = personNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBirthDate(Date birthDate) {
|
||||||
|
this.birthDate = birthDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirst_name(String first_name) {
|
||||||
|
this.first_name = first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package com.moparisthebest.jdbc.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public class SetBoss extends SetPerson implements Boss {
|
||||||
|
protected String department;
|
||||||
|
protected String first_name;
|
||||||
|
|
||||||
|
protected SetBoss() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SetBoss(long personNo, Date birthDate, String firstName, String lastName, String department, String first_name) {
|
||||||
|
super(personNo, birthDate, firstName, lastName);
|
||||||
|
this.department = department;
|
||||||
|
this.first_name = first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SetBoss(Boss boss) {
|
||||||
|
super(boss);
|
||||||
|
this.department = boss.getDepartment();
|
||||||
|
this.first_name = boss.getFirst_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDepartment() {
|
||||||
|
return department;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirst_name() {
|
||||||
|
return first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof SetBoss)) return false;
|
||||||
|
if (!super.equals(o)) return false;
|
||||||
|
|
||||||
|
SetBoss boss = (SetBoss) o;
|
||||||
|
|
||||||
|
if (department != null ? !department.equals(boss.department) : boss.department != null) return false;
|
||||||
|
if (first_name != null ? !first_name.equals(boss.first_name) : boss.first_name != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = super.hashCode();
|
||||||
|
result = 31 * result + (department != null ? department.hashCode() : 0);
|
||||||
|
result = 31 * result + (first_name != null ? first_name.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.getClass().getSimpleName()+"{" +
|
||||||
|
"department='" + department + '\'' +
|
||||||
|
", first_name='" + first_name + '\'' +
|
||||||
|
"} " + super.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDepartment(String department) {
|
||||||
|
this.department = department;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirst_name(String first_name) {
|
||||||
|
this.first_name = first_name;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package com.moparisthebest.jdbc.dto;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mopar on 6/10/14.
|
||||||
|
*/
|
||||||
|
public class SetPerson extends FieldPerson {
|
||||||
|
protected SetPerson() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public SetPerson(long personNo, Date birthDate, String firstName, String lastName) {
|
||||||
|
super(personNo, birthDate, firstName, lastName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SetPerson(Person person) {
|
||||||
|
super(person);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPersonNo(long personNo) {
|
||||||
|
this.personNo = personNo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBirthDate(Date birthDate) {
|
||||||
|
this.birthDate = birthDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFirstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6
pom.xml
6
pom.xml
@ -109,6 +109,12 @@
|
|||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.derby</groupId>
|
||||||
|
<artifactId>derby</artifactId>
|
||||||
|
<version>10.10.2.0</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.ant</groupId>
|
<groupId>org.apache.ant</groupId>
|
||||||
<artifactId>ant</artifactId>
|
<artifactId>ant</artifactId>
|
||||||
|
Loading…
Reference in New Issue
Block a user