问题
In spring I am using jdbcTemplate, but having a problem that it is returning a Linkedcaseinsensitivemap when querying for a List, when doing the following I still get the spring linkedcaseinsensitivemap, even if I cast it to java util List and define the left-side of the assignment as a java.util.List.
Firstly how is that even possible?
final java.util.List<Map<String, Object>> list = (java.util.List<Map<String, Object>>) jdbc
.queryForList("SELECT * FROM customer");
so, how would one achive doing this type of upcaste? without needing to declare a second list allocate memory for it and then put the objects manually into the java.util.List?
Since the LinkedCaseInsensitive is subclassing the java object, Im having a hard time figuring out how to cast to the super object which is the java List. How to achieve this is a mystery at the moment.
since there is no way currently to know which brokers will use our AMQ, the goal is too strictly keep to jms objects, So I can't start sending spring objects, since jms should be our standard, also please note I do not have the option to implement the AMQProtocol, I need to send basic java objects,
Since serialising to JSON has been suggested I will explain why it does not work in this case, why I'll need to send the Objects "as-are" to the receiver since they will put it into a Notes document.
for (int i = 1; i <= metadata.getColumnCount(); i++) {
String columnName = metadata.getColumnName(i);
Object values = sqlConnection.getRset().getObject(i);
doc.replaceItemValue(columnName, values);
}
So SO'ers, how does one achieve doing this more beautifully?
please help
thanks in advance!
回答1:
A SQL select can return multiple rows, and each row has multiple selected columns. The queryForList method you are calling returns a List with for each selected row a Map mapping column name to column value.
Map and List are interfaces, so Spring is free to pick whatever implementation it likes. It chooses the LinkedCaseInsensitiveHashMap for the Map because that map will list the keys in the order of insertion. So the order in which the columns were selected does not get lost.
If you wish to send the result list to a receiver that you know little about, you can probably best serialize it to JSON and send it as a text message.
You can serialize to JSON using a library like Gson or Jackson2. You create a serializer and feed it the object you wish to convert to a String. So for example in Gson, where the serializer class is called Gson:
TextMessage message;
// initialize message and headers however you like
// then serialize it to String:
Gson gson = new Gson();
String json = gson.toJson(list);
// and set it in the message:
message.setText(json);
(You can also let Spring JmsTemplate do this for you using a MessageConverter that converts to JSON but I'd estimate that that's a bit harder to get working.)
Alternatively, if you wish to customize the Map that you send as an ObjectMessage, you can use a different query method that allows you to specify a custom RowMapper that creates a java.util.Map implementation of your liking. Note that if you use a TreeMap, it'll sort the columns alphabetically and if you use a HashMap, it'll put them in random order.
The receiver then can unpack the JSON back into Java objects. gson.fromGson(json) will return a List of Maps.
回答2:
This is the only way I've figured out how to have a child object to become it's parent class without breaking out into methods - in my described scenario doing the following:
final java.util.ArrayList<java.util.Map<String, Object>> javaList = new java.util.ArrayList<java.util.Map<String, Object>>();
final java.util.List<java.util.Map<String, Object>> list = jdbc
.queryForList("SELECT * FROM customer");
javaList.addAll(list);
But doesn't look good to me, how would one achive this in a more right way?
来源:https://stackoverflow.com/questions/30378061/explicit-type-conversion-between-child-spring-object-and-its-super-java-util-o