Liquibase : build where clause with java - java

I want to execute an update on a row using Liquibase but how can I set where param ? i can find the setter but I don't know what to put in it ? where id=value
UpdateDataChange updateDataChange=new UpdateDataChange();
columnConfig = new LoadDataColumnConfig();
columnConfig.setName(targetFieldKey);
columnConfig.setType("String");
columnConfig.setValue(value);
updateDataChange.addColumn(columnConfig);

Usually you put a condition in the where clause which makes the row(s) you want to update unique.
If you want to update one row, the most obvious choice would be to use the identifier of the table. Updating multiple rows could involve a condition with a LIKE.
For example: WHERE name LIKE "%test%", would update all the rows where the name contain test.
It always depends on the use-case.

Related

Making changes to my program after updating my database?

Sorry if my question is not specific or if it has been answered before. I tried looking for it and for a better way to ask but this is the most accurate way.
I have developed a program in Java in which I insert a new row into my database in the following way:
INSERT INTO table_name VALUES (?,?,?)
The thing is that I have this query in many parts of the program, and now I decided to add a fourth column to my table. Do I have to update EVERY SINGLE query with a new question mark in the program? If I dont, it crashes.
What is the best way to proceed in these cases?
YES.
you need to add extra ? (parameter placeholder) because you are using implicit INSERT statement. That means that you didn't specify the column names of the table to which the values will be inserted.
INSERT INTO table_name VALUES (?,?,?)
// the server assumes that you are inserting values for all
// columns in your table
// if you fail to add value on one column. an exception will be thrown
The next time you create an INSERT statement, make sure that you specify the column names on it so when you alter the table by adding extra column, you won't update all your place holders.
INSERT INTO table_name (Col1, col2, col3) VALUES (?,?,?)
// the server knows that you are inserting values for a specific column
Do I have to update EVERY SINGLE query with a new question mark in the program?
Probably. What you should do, while you're updating every single one of those queries, is to encapsulate them into an object, probably using a Data Source pattern such as a Table Data Gateway or a Row Data Gateway. That way you Don't Repeat Yourself and the next time you update the table, you only have one place to update the query.
Because of the syntax you've used, you might run some issues. I've referring to the lack of column names. Your INSERT queries will start failing as soon as you change your table structure.
If you had used the following syntax:
INSERT INTO table_name (C1, C2, C3) VALUES (?,?,?)
assuming your new column has a proper default value, then it would've work fine.

Java JDBC UPDATE Add Number?

So let's say I have an int column in MySQL. I want to update that column by adding to it, without running a SELECT query to get the number and add it. Is this possible?
update tablename set field = field + 1 where condition
This is a direct MySql update command to do so. You didn't mention if you were using a specific ORM like Hibernate or anything, but this same concept can be applied in HQL etc.

Possible to avoid code changes during schema changes when using Jdbctemplate?

When using spring's JdbcTemplate, I am using the row mapper to map results coming back.
The benefit with this is that there are less places where I have to change my code if I change my mysql schema etc.
Are there any other tips on how to minimize changes in code when adding/removing columns in mysql?
If you are retrieving columns by name (SELECT col1, col2, col3) you will be immune to adding and rearranging of columns. Never use SELECT *.
However if you are removing columns, you have no choice. In fact, how was this suppose to work? Previously you fetched e.g. price column and used it in your business layer. Now the column does not exist - how to handle this?
But adding columns is safe, unless new columns are non-nullable. In this case you will have a problem when adding new records, since VALUES statement won't include new columns. Optional columns are fine.
One tip is to not do SELECT *, select on specific columns so in case you add stuff you don't break your code :)

Control order of updates in hibernate

I have a table with a unique column, "token", enforced by a unique constraint in the database. In a certain case, I need to change an existing row to have the same token as another existing row, changing the 2nd row to have a new value.
So, say I have:
id;token
0;'aaa'
1;'bbb'
I want id 0 ('aaa') to instead have the token 'bbb'. So I need to change 'bbb' to be 'jfeisefjse', and then I can change 'aaa' to be 'bbb'. This can be done in postgres in a single tranasction.
I've tried to do the same thing in code: In one transaction I get the token from the existing row (row 1), I set it to be a random value, I update the other row (row 0) to have row 1's token, then I commit. However hibernate doesn't respect the order I've done the commits in. It seems to always run the update statement for row 0 first, and postgres complains that it's violating a foreign key constraint.
How can I make hibernate do this? Either force a certain order of update statements, or some other way to do this?
Note: Doing this in two transactions (one for scrambling row 1, then another transaction to update row 0) is not an option.
Session.flush() will force hibernate to write any pending SQL without committing the transaction. It's a bit clunky but sometimes you do need to get a little less 'ORM' and make things just work :)

Insert fail then update OR Load and then decide if insert or update

I have a webservice in java that receives a list of information to be inserted or updated in a database. I don't know which one is to insert or update.
Which one is the best approach to abtain better performance results:
Iterate over the list(a object list, with the table pk on it), try to insert the entry on Database. If the insert failed, run a update
Try to load the entry from database. if the results retrieved update, if not insert the entry.
another option? tell me about it :)
In first calls, i believe that most of the entries will be new bd entries, but there will be a saturation point that most of the entries will be to update.
I'm talking about a DB table that could reach over 100 million entries in a mature form.
What will be your approach? Performance is my most important goal.
If your database supports MERGE, I would have thought that was most efficient (and treats all the data as a single set).
See:
http://www.oracle.com/technology/products/oracle9i/daily/Aug24.html
https://web.archive.org/web/1/http://blogs.techrepublic%2ecom%2ecom/datacenter/?p=194
If performance is your goal then first get rid of the word iterate from your vocabulary! learn to do things in sets.
If you need to update or insert, always do the update first. Otherwise it is easy to find yourself updating the record you just inserted by accident. If you are doing this it helps to have an identifier you can look at to see if the record exists. If the identifier exists, then do the update otherwise do the insert.
The important thing is to understand the balance or ratio between the number of inserts versus the number of updates on the list you receive. IMHO you should implement an abstract strategy that says "persists this on database". Then create concrete strategies that (for example):
checks for primary key, if zero records are found does the insert, else updates
Does the update and, if fails, does the insert.
others
And then pull the strategy to use (the class fully qualified name for example) from a configuration file. This way you can switch from one strategy to another easily. If it is feasible, could be depending on your domain, you can put an heuristic that selects the best strategy based on the input entities on the set.
MySQL supports this:
INSERT INTO foo
SET bar='baz', howmanybars=1
ON DUPLICATE KEY UPDATE howmanybars=howmanybars+1
Option 2 is not going to be the most efficient. The database will already be making this check for you when you do the actual insert or update in order to enforce the primary key. By making this check yourself you are incurring the overhead of a table lookup twice as well as an extra round trip from your Java code. Choose which case is the most likely and code optimistically.
Expanding on option 1, you can use a stored procedure to handle the insert/update. This example with PostgreSQL syntax assumes the insert is the normal case.
CREATE FUNCTION insert_or_update(_id INTEGER, _col1 INTEGER) RETURNS void
AS $$
BEGIN
INSERT INTO
my_table (id, col1)
SELECT
_id, _col1;
EXCEPTION WHEN unique_violation THEN
UPDATE
my_table
SET
col1 = _col1
WHERE
id = _id;
END;
END;
$$
LANGUAGE plpgsql;
You could also make the update the normal case and then check the number of rows affected by the update statement to determine if the row is actually new and you need to do an insert.
As alluded to in some other answers, the most efficient way to handle this operation is in one batch:
Take all of the rows passed to the web service and bulk insert them into a temporary table
Update rows in the mater table from the temp table
Insert new rows in the master table from the temp table
Dispose of the temp table
The type of temporary table to use and most efficient way to manage it will depend on the database you are using.

Categories