Reputation: 1510
Starting point:
The program need to connect to a database. The data structure is unknown. The access data is provided in a seperate file.
The data needs to be analyzised and later updated.
Connection is made by using jdbc
and the use of Statement
, ResultSet
and ResultSetMetaData
.
For further manipulation of data, it is necessary to store them all in one
object, a LinkedHashMap
, key is the column index, value the column entries.
public class TableRepresentation {
private final LinkedHashMap<Integer, DataType> tableData;
Because the data types differ, a new interface
DataType
is used.
public interface DataType {
public void putDataToObject(int key, int value);
public void putDataToObject(int key, String value);
public void putDataToObject(int key, Date value);}
The idea is to use the factory pattern to create the Datatype objects at runtime. Next step is to add the data to each DataType
object. There lies the problem.
By doing it this way, I of course have to implement each method in each class:
public class IntegerObject implements DataType{
private final Map<Integer, Integer> attributeData;
public IntegerObject(){
attributeData = new LinkedHashMap<>();
}
/**
* @return the attributeData
*/
public Map<Integer, Integer> getAttributeData() {
return attributeData;
}
@Override
public void putDataToObject(int key, int value){
attributeData.put(key, value);
}
@Override
public void putDataToObject(int key, String value) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void putDataToObject(int key, Date value) {
throw new UnsupportedOperationException("Not supported yet.");
}
which is a lot of unused and for sure dangerous code.
Question 1: Is there a way to overload methods, which are implemented from an interface?
Question 2: Is there a better way to achive the goal?
Upvotes: 3
Views: 1806
Reputation: 42966
Question 1: Is there a way to overload methods, which are implemented from an interface?
All of those method signatures are a bit redundant, you could generalize by making an interface with a single method:
public interface DataType {
public void putDataToObject(int key, Object value);
}
Then you can override it in any way you want:
public class IntegerObject implements DataType{
private final Map<Integer, Object> attributeData = new LinkedHashMap<>();
public Map<Integer, Integer> getAttributeData() {
return attributeData;
}
@Override
public void putDataToObject(int key, Object value){
attributeData.put(key, value);
}
}
Now, this assumes you only want 1 implementation of putDataToObject
per class. If you need multiple implementations, it wouldn't be hard to branch out different behavior using the instanceof
keyword in Java.
Question 2: Is there a better way to achive the goal?
Yes, there is a standard way to do this in JDBC with the SQLData interface.
Example:
public class MyUser implements SQLData, Serializable
{
private static final long serialVersionUID = -4235126659654360181L;
public String name;
public String address;
public String phone;
private String sql_type;
public MyUser(String name, String address, String phone) {
this.name = name;
this.address = address;
this.phone = phone;
}
@Override
public String getSQLTypeName() throws SQLException {
return sql_type;
}
@Override
public void readSQL(SQLInput stream, String typeName) throws SQLException {
sql_type = typeName;
name = stream.readString();
address = stream.readString();
phone = stream.readString();
}
@Override
public void writeSQL(SQLOutput stream) throws SQLException {
stream.writeString(name);
stream.writeString(address);
stream.writeString(phone);
}
}
Then, it's very easy to read and write these classed to a database:
// Writing an object to a database
PreparedStatement pstmt = conn.prepareStatement("insert into MY_USER_TABLE values(?,?)");
pstmt.setInt(1, 1);
pstmt.setObject(2, new MyUser("Alice", "aAddress", "111-1111"));
pstmt.addBatch();
pstmt.executeBatch(); // Insert the users
pstmt.close();
// Reading an object from a database
Statement stmt = conn.createStatement();
stmt.execute("select * from MY_USER_TABLE");
ResultSet rs = stmt.getResultSet();
rs.next();
MyUser userFromDB = rs.getObject(2, MyUser.class);
rs.close();
stmt.close();
Upvotes: 1