My General Question is: Is it inefficient/bad practice to call preparedStatement.executeBatch() if there's only one query in the batch?
I'm writing a generic method for the Java Helper Library to execute a query. There's a javabean called HelperQuery which holds a list of arrays another javabean called QueryParameter which holds a type (like STRING, BLOB, INT, etc.) and a value. The QueryParameter is used to fill the HelperQuery's PreparedStatement. In many cases, there will be only one array of QueryParameters.
My Specific Question is: Should I handle things differently if there's only one array of QueryParameters or would it be ok to handle things exactly the same regardless of how many QueryParameters there are?
executeBatch is a "super" method from the PreparedStatement's parent Statement which returns an int[] which indicates the success/failure of the executed queries and executeQuery returns a ResultSet. Therefore, it would be a good idea to have the two be totally different method calls so the developer can handle them differently. I would recommend:
An executeQuery(HelperQuery helperQuery) method which will return the associated ResultSet and will only get the first QueryParameters from the HelperQuery (for convenience) and another method which the developer can specify which QueryParameter set to use (either have them specify a number of the QueryParameter list or just pass in the QueryParameters explicitly (I recommend the second of the two)).
An executeBatch(HelperQuery helperQuery method which will return the int[] and the developer can handle that as they wish.
It's always good to give the user (developer in this case) power to do what they want (but also provide for a simple solution for them to perform common tasks).
Related
According to sequence diagram I should create firstly method "regisreItem(Item item)" with argument "item" as an object. I see my problem that the constructor for "items" is called after the method "regisreItem(Item item)" so that I have nothing to insert into "regisreItem(Item item)" method according sequence diagramm. Or not ?
Sequence diagram
Class diagram
Here is a part of sequence diagram i am interested in
https://drive.google.com/open?id=1eJolWNoN32IubP3iaaXPc_cLM5Es08hK
Here is all my sort of code.
Please provide me some sort of code ho is it possible to implement.
And clarify the beginning of sequence diagram.
Since the operation registerItem expects an item as parameter, the Auctioneer object needs to create it, before calling the operation. That means the Auctioneer has to send a create message, not the Auction (using new Item() as a parameter is not possible in a sequence diagram - and it doesn’t change the creator anyway). i1 and i2 are attributes of the interaction. They can be used as parameters of registerItem.
addBid also expects a bidder. Again the attributes Max and Moritzof the interaction should be used here.
In a real program these interaction attributes would be temporary variables of the Auction::addBid operation or of the Auctioneer. The Auctioneer is probably not supposed to have variables, therefore the registerItem Operation should probably only have generic data types such as stringas parameters.
The Auction is supposed to send messages to i1 and i2, however, since these are attributes of the interaction, the Auction object does not know them. It’s Ok to omit this detail, but it would be better to show how the Auction finds the relevant Item, for example with a findItemByName Operation called on itself.
A better alternative is, to let the Auction send the messages to its own attribute allItems. Then two lifelines would represent the same attribute, but with different objects. A selector could be used to distinguish between the two objects in the slot defined by this attribute (allItems[0], allItems[1], this is optional). The same is applicable to allBids instead of b300EUR and the like.
You can get around the issue of the Item constructor being called after registerItem by using:
registerItem(new Item(...));
and passing in the attributes of Item i1 and i2. That will create the new Item and then it can be added to the auction Item list.
I'm assuming the start of the sequence diagram is the auctioneer creating or opening an already created auction and then adding a list of items that will be used in the auction by repeatedly calling registerItem(new Item(...)); which can then have bids added to them by Max and Moritz via the Auction object
I am currently working on a Rest API, in a get method which suppose to return an Array of objects in json format I now have the requirement to sort the result by a field passed as a parameter to the method. Consider for example the object to be
public class ExampleType {
int firstField ;
String secondField ;
}
Now according to the requirements the Rest API user should be able to pass as a parameter among other things either "firstField" or "secondField" and I should be sorting the array containing the result objects using this field.
Apparently my model is not so simplistic as the example, I do have more than 15 fields which could potentially be the one that I need to sort by, so an else if statement is not a choice at this point. My question is does anybody had a similar requirement for a rest api and if so how did you tackle it ? Or any recommendation on what could potentially by an elegant solution to my problem would be greatly appreciated.
You should create a Comparator and then use this to sort your data.
The comparators could be stored in a static map to avoid a switch/case if/else:
map.put("fieldName", Comparator.comparing(ExampleType::getFirstField));
You can combine two or more comparators using the thenComparing method.
The only other option is to create the appropriate comparators using reflection.
Note: requirements of API consumers often are not requirements that should be implemented in the API itself. You may also consider that sorting output is in fact a display problem and not something that an API needs to be concerned with.
It depends on the situation though, if data needs to be paginated then you may have no option other than to sort at the API level.
I've got loads of the following to implement.
validateParameter(field_name, field_type, field_validationMessage, visibleBoolean);
Instead of having 50-60 of these in a row, is there some form of nested hashmap/4d array I can use to build it up and loop through them?
Whats the best approach for doing something like that?
Thanks!
EDIT: Was 4 items.
What you could do is create a new Class that holds three values. (The type, the boolean, and name, or the fourth value (you didn't list it)). Then, when creating the HashMap, all you have to do is call the method to get your three values. It may seem like more work, but all you would have to do is create a simple loop to go through all of the values you need. Since I don't know exactly what it is that you're trying to do, all I can do is provide an example of what I'm trying to do. Hope it applies to your problem.
Anyways, creating the Class to hold the three(or four) values you need.
For example,
Class Fields{
String field_name;
Integer field_type;
Boolean validationMessageVisible;
Fields(String name, Integer type, Boolean mv) {
// this.field_name = name;
this.field_type = type;
this.validationMessageVisible = mv;
}
Then put them in a HashMap somewhat like this:
HashMap map = new HashMap<String, Triple>();
map.put(LOCAL STRING FOR NAME OF FIELD, new Field(new Integer(YOUR INTEGER),new Boolean(YOUR BOOLEAN)));
NOTE: This is only going to work as long as these three or four values can all be stored together. For example if you need all of the values to be stored separately for whatever reason it may be, then this won't work. Only if they can be grouped together without it affecting the function of the program, that this will work.
This was a quick brainstorm. Not sure if it will work, but think along these lines and I believe it should work out for you.
You may have to make a few edits, but this should get you in the right direction
P.S. Sorry for it being so wordy, just tried to get as many details out as possible.
The other answer is close but you don't need a key in this case.
Just define a class to contain your three fields. Create a List or array of that class. Loop over the list or array calling the method for each combination.
The approach I'd use is to create a POJO (or some POJOs) to store the values as attributes and validate attribute by attribute.
Since many times you're going to have the same validation per attribute type (e.g. dates and numbers can be validated by range, strings can be validated to ensure they´re not null or empty, etc), you could just iterate on these attributes using reflection (or even better, using annotations).
If you need to validate on the POJO level, you can still reuse these attribute-level validators via composition, while you add more specific validations are you´re going up in the abstraction level (going up means basic attributes -> pojos -> pojos that contain other pojos -> etc).
Passing several basic types as parameters of the same method is not good because the parameters themselves don't tell much and you can easily exchange two parameters of the same type by accident in the method call.
There are often times when I have need for a RowCallbackHandler, because in processing the result set I don't map each row to a single type, nor each result set to a single data structure. Instead, I may map the majority rows to a specific Java bean, and add the remainder to a list for post-processing.
In these cases, I need a callback with return type void, and the only callback which satisfies this is RowCallbackHandler.
But I don't come across many examples of this, and I have to admit, it's aesthetically nicer to use JDBC and loop through a ResultSet, than to use the clunky Spring callbacks. Is RowCallbackHandler more common than I think? I'm curious what people have to say...
Edit: Some people have asked for my data model. Okay, there's a nodes table and an edges table. If there's an edge between nodes A and B, that edge can signify two things:
A and B are disjoint nodes that interact
A is a member of B, or vice versa
In the second case, I need to add these group nodes to a list. They can't be mapped to a Java bean yet, because they don't signify interactions between disjoint nodes.
Perhaps what I should be doing, instead, is to have 2 queries, one that retrieves case (1), another that retrieves case (2). Case (1) could be mapped to a Java bean, case (2) to a List.
If this is indeed better, then maybe RowCallbackHandler is a bad code smell?
If what you want is to process the whole result set, without returning anything, simply use a ResultSetExtractor<Void> (and one of the JdbcTemplate methods taking it as argument).
You can create a new class that's composed of your bean objects(s), plus the list. Then fill it in a ResultSetExtractor or RowCallbackHandler. Then your return type can change from void to the new class' type.
I would like to have an option to call 'rawQuery' with a list of Integers passed into it, but it looks I can't: all 'rawQuery' methods require array of Strings...
Why? I can call 'toString' for each passed int object, but I don't see any logic here. Why Google don't provide rawQuery that accept list of Objects?
Are there any limitation or constrains for that?
Probably I miss something?
Thank you.
Probably because rawQuery isn't the prefered method of querying. And since sqlite columns basically don't have types, they probably don't want to assume calling toString on whatever it is you're passing.
SQLite supports the concept of "type affinity" on columns. The type
affinity of a column is the recommended type for data stored in that
column. The important idea here is that the type is recommended, not
required. Any column can still store any type of data. It is just that
some columns, given the choice, will prefer to use one storage class
over another. The preferred storage class for a column is called its
"affinity".
Is there a reason you want to use rawQuery instead of execSQL?
No complex objects are accepted in the list of parameters, as stated on the documentation for the parameter bindArgs:
Parameters
sql the SQL statement to be executed. Multiple statements separated by semicolons are not supported.
bindArgs only byte[], String, Long and Double are supported in bindArgs.
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#execSQL(java.lang.String, java.lang.Object[]).