Mapping Java-Objects to a database using Reflection and Generics (Part 2)
May 2nd, 2009
This post is the second part of the series ‘Mapping Java-Objects to a database using Reflection and Generics’. In part one we covered the process of selecting entries from a database-table and instantiating Java-Objects with these entries using Reflection and Generics. Now we’ll have a look at the other side and insert some entries into the database. If you’ve understood the code-examples of the last post you won’t have any problems with the following snippets either.
You’ve probably noticed that Prepared Statement are used for the inserts. The proper use and the advantages/disadvanteges of Prepared Statements are covered in a post I published a while ago.
The non-trivial part of the insertObjects()-method should be familiar to you. All the Reflection- and Generics-stuff has already been discussed in part one. Instead of the PropertyDescriptor that provides the set()-method of the bean-class we use the get()-method to retrieve the value of the object here.
Below is a small main-method that demonstrates how the presented code can be used.
The output should look like this:
So, that’s it! In the upcoming posts we’ll leave the JDBC-area and look at some other interesting Java-functionality.
Happy Coding,
Tino
| Java | | copy code | | ? |
| 01 | import java.beans.IntrospectionException; |
| 02 | import java.beans.PropertyDescriptor; |
| 03 | import java.lang.reflect.Field; |
| 04 | import java.lang.reflect.InvocationTargetException; |
| 05 | import java.lang.reflect.Method; |
| 06 | import java.sql.Connection; |
| 07 | import java.sql.PreparedStatement; |
| 08 | import java.sql.SQLException; |
| 09 | import java.util.List; |
| 10 | |
| 11 | /** |
| 12 | * |
| 13 | * Class that inserts a list of <T>s into the corresponding database-table. |
| 14 | * |
| 15 | * @author Tino for http://www.java-blog.com |
| 16 | * |
| 17 | * @param <T> |
| 18 | */ |
| 19 | public class DatabaseInserter<T> extends AbstractDatabaseHandler<T> { |
| 20 | |
| 21 | public DatabaseInserter(Class<T> type, |
| 22 | DatabaseConnecter databaseConnecter) { |
| 23 | super(type, databaseConnecter); |
| 24 | } |
| 25 | |
| 26 | @Override |
| 27 | protected String createQuery() { |
| 28 | |
| 29 | StringBuilder sb = new StringBuilder(); |
| 30 | |
| 31 | sb.append("INSERT INTO "); |
| 32 | sb.append(type.getSimpleName()); |
| 33 | sb.append("("); |
| 34 | sb.append(super.getColumns(false)); |
| 35 | sb.append(")"); |
| 36 | sb.append(" VALUES ("); |
| 37 | sb.append(super.getColumns(true)); |
| 38 | sb.append(")"); |
| 39 | |
| 40 | return sb.toString(); |
| 41 | } |
| 42 | |
| 43 | /** |
| 44 | * Inserts a list of <T>s into the corresponding database-table |
| 45 | * |
| 46 | * @param list |
| 47 | * List of <T>s that should be inserted into the corresponding |
| 48 | * database-table |
| 49 | * |
| 50 | * @throws SQLException |
| 51 | * @throws SecurityException |
| 52 | * @throws IllegalArgumentException |
| 53 | * @throws InstantiationException |
| 54 | * @throws IllegalAccessException |
| 55 | * @throws IntrospectionException |
| 56 | * @throws InvocationTargetException |
| 57 | */ |
| 58 | public void insertObjects(List<T> list) throws SQLException, |
| 59 | SecurityException, IllegalArgumentException, |
| 60 | InstantiationException, IllegalAccessException, |
| 61 | IntrospectionException, InvocationTargetException { |
| 62 | |
| 63 | Connection connection = null; |
| 64 | PreparedStatement preparedStatement = null; |
| 65 | |
| 66 | try { |
| 67 | connection = databaseConnecter.createConnection(); |
| 68 | preparedStatement = connection.prepareStatement(query); |
| 69 | |
| 70 | for (T instance : list) { |
| 71 | int i = 0; |
| 72 | |
| 73 | for (Field field : type.getDeclaredFields()) { |
| 74 | PropertyDescriptor propertyDescriptor = new PropertyDescriptor( |
| 75 | field.getName(), type); |
| 76 | |
| 77 | Method method = propertyDescriptor |
| 78 | .getReadMethod(); |
| 79 | |
| 80 | Object value = method.invoke(instance); |
| 81 | |
| 82 | preparedStatement.setObject(++i, value); |
| 83 | } |
| 84 | |
| 85 | preparedStatement.addBatch(); |
| 86 | } |
| 87 | preparedStatement.executeBatch(); |
| 88 | |
| 89 | } finally { |
| 90 | DatabaseResourceCloser.close(preparedStatement, |
| 91 | connection); |
| 92 | } |
| 93 | } |
| 94 | } |
You’ve probably noticed that Prepared Statement are used for the inserts. The proper use and the advantages/disadvanteges of Prepared Statements are covered in a post I published a while ago.
The non-trivial part of the insertObjects()-method should be familiar to you. All the Reflection- and Generics-stuff has already been discussed in part one. Instead of the PropertyDescriptor that provides the set()-method of the bean-class we use the get()-method to retrieve the value of the object here.
Putting it all together and test it
Below is a small main-method that demonstrates how the presented code can be used.
| Java | | copy code | | ? |
| 01 | import java.util.ArrayList; |
| 02 | import java.util.List; |
| 03 | |
| 04 | public class Main { |
| 05 | |
| 06 | /** For testing purposes */ |
| 07 | public static void main(String[] args) { |
| 08 | |
| 09 | try { |
| 10 | |
| 11 | DatabaseConnecter connecter = new MySqlDatabaseConnecter( |
| 12 | new DatabaseConnectionSettingsImpl( |
| 13 | "127.0.0.1", 3306, "exampleDatabase", |
| 14 | "user", "pass")); |
| 15 | |
| 16 | List<Test> list = new ArrayList<Test>(); |
| 17 | list.add(new Test(1, "one")); |
| 18 | list.add(new Test(2, "two")); |
| 19 | |
| 20 | DatabaseInserter<Test> inserter = new DatabaseInserter<Test>( |
| 21 | Test.class, connecter); |
| 22 | |
| 23 | inserter.insertObjects(list); |
| 24 | |
| 25 | DatabaseSelecter<Test> selecter = new DatabaseSelecter<Test>( |
| 26 | Test.class, connecter); |
| 27 | |
| 28 | list = selecter.selectObjects(); |
| 29 | |
| 30 | for (Test test : list) |
| 31 | System.out.println(test); |
| 32 | |
| 33 | } catch (Exception e) { |
| 34 | e.printStackTrace(); |
| 35 | } |
| 36 | } |
| 37 | } |
The output should look like this:
Test (
Test@19821f
id = 1
name = one
)
Test (
Test@addbf1
id = 2
name = two
)So, that’s it! In the upcoming posts we’ll leave the JDBC-area and look at some other interesting Java-functionality.
Happy Coding,
Tino