如何在我的 @Transactional 方法中只更新已更改的字段?

huangapple go评论82阅读模式
英文:

How can I update only changed fields in my @Transactional method in Java?

问题

亲爱的开发者们,大家好!我需要解决一些与我的方法相关的问题。
我需要创建一个编辑/更新方法,允许我更改我的对象。

其中一个条件是,只有用户更改的字段才应该在数据库中更改。不应覆盖所有字段。
例如:旧值为名字 - > "Jack",新值为名字 - > "Bob",应该更改。
但是,如果旧值是名字 - > "Jack",新值也是名字 - > "Jack",则字段不应该被覆盖,因为值相同。

我需要我的方法来检查并仅更改已更改的字段,并将更改插入数据库。

我尝试使用SQL完成任务,但不幸的是,我不知道如何设置值(如果新值与数据库中的值相同,则不执行任何更新的想法):

也许我需要先执行SELECT,或者使用equals比较每个字段?请至少在一个值的示例上告诉我如何正确实现我的任务。

P.S 我希望仅在新值不等于旧值时更新我的值,但如果旧值和新值相等,什么都不应该发生。

感谢您的帮助!

英文:

Good day Dear developers! I need to solve a couple of problems related to my method.
I need to create an edit / update method that would allow me to change my object.

One of the conditions is that only the fields that the user changes should change in the database. All fields should not be overwritten.
Example: the old value name - > "Jack", the new value name - > "Bob", should change .
HOWEVER, if the old value is name - > " Jack "and the new value is name - > "Jack", then the field should not be overwritten, since the values are equals.

I need my method to check and change only the fields that were changed and insert changes on the database.

I tried to do the task using sql, but unfortunately I don't know how to set the values
(The idea is do not perform any update if a new value is the same as in DB right now)
:


	@Transactional(transactionManager = TransactionManagerConfig.TX_MANAGER_MAIN)
	public void editUserContacts(User user) {

		Connection connection = DataSourceUtils.getConnection(mainDataSource);

		String sql = "UPDATE `" + userSchema + "`.l_user " +
				" SET user_phone_number = @phoneNumber," +
				"firstname = @fullName," +
				"user_country = @userCountry," +
				"house_phone_number = @phoneAlternative," +
				" WHERE l_user_id=? , " +
				"user_phone_number != @phoneNumber OR IS NULL," +
				"firstName != @fullName OR IS NULL," +
				"user_country != @userCountry OR IS NULL," +
				"house_phone_number != @phoneAlternative OR IS NULL,;

		try (
				PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)
		) {
			statement.executeUpdate();
			statement.getUpdateCount();

		} catch (SQLException e) {
			throw new DAOException(e);

		}
	}

Maybe I need to do SELECT first, or compare each field using equals ? Please tell me on the EXAMPLE of at least one value, how can I implement my task correctly?

P.S I want to update my value if the new value is not equals the old value. but if old and new values is equals , that nothing should happen

I will be very grateful for your help!

答案1

得分: 2

> 示例:旧值为名字 -> "Jack",新值为名字 -> "Bob",应进行更改。然而,如果旧值为名字 -> "Jack",新值为名字 -> "Jack",则不应覆盖该字段,因为这些值相等。

不必担心。MySQL足够智能,只有在其值真正更改时才会更新列。

示例:

如何在我的 @Transactional 方法中只更新已更改的字段?

看 - 这里有2行,只有一行中的值更改了。MySQL报告:

> 影响了1行

> 匹配的行数:2 已更改:1

也就是说,未更改值的行实际上未被修改。

英文:

> Example: the old value name - > "Jack", the new value name - > "Bob", should change . HOWEVER, if the old value is name - > " Jack "and the new value is name - > "Jack", then the field should not be overwritten, since the values are equals.

Don't care about it. MySQL is smart enough, it will renew the column only when its value is really changed.

Example:

如何在我的 @Transactional 方法中只更新已更改的字段?

Look - there is 2 rows, and only in one row the value is changed. And MySQL reports

> 1 row affected

and

> Rows matched: 2 Changed: 1

I.e. the row which' value was not altered by fact was not changed.

答案2

得分: 0

如果我理解正确,您希望仅在新值不为 NULL 时更新表中的值。然而,只有某些列可能会受到影响。为此,可以使用 COALESCE() 函数:

UPDATE " + userSchema + ".l_user 
    SET user_phone_number = COALESCE(@phoneNumber, user_phone_number),
        firstname = COALESCE(@fullName, firstname),
        user_country = COALESCE(@userCountry, user_country),
        house_phone_number = COALESCE(@phoneAlternative, house_phone_number)
    WHERE l_user_id = ? AND
          not (user_phone_number <=> @phoneNumber and
               firstName <=> @fullName and
               user_country <=> @userCountry and
               house_phone_number <=> @phoneAlternative
              );

这将仅在四个值中的一个发生更改时尝试更新行。<=>NULL 安全比较运算符。

您的查询尝试存在多个错误。

  • WHERE 子句不识别 ,。这只是语法错误。
  • OR IS NULL 不是有效的 SQL。这是语法错误。
  • 您还在 WHERE 子句之前有一个逗号,这是另一个语法错误。
英文:

If I understand correctly, you ant to update the values in the table only when the new value is not NULL. However, only some of the columns might be affected. For this, use COALESCE():

UPDATE &quot; + userSchema + &quot;.l_user 
    SET user_phone_number = COALESCE(@phoneNumber, user_phone_number),
        firstname = COALESCE(@fullName, firstname),
        user_country = COALESCE(@userCountry, user_country),
        house_phone_number = COALESCE(@phoneAlternative, house_phone_number),
    WHERE l_user_id = ? AND
          not (user_phone_number &lt;=&gt; @phoneNumber and
               firstName &lt;=&gt; @fullName and
               user_country &lt;=&gt; @userCountry and
               house_phone_number &lt;=&gt; @phoneAlternative
              );

This will attempt to update rows only where one of the four values has changed. The &lt;=&gt; is the NULL-safe comparison operator.

Your query attempt has multiple errors.

  • The WHERE clause does not recognize ,. That is just a syntax error
  • OR IS NULL is not valid SQL. That is a syntax error.
  • You also have a comma before the WHERE clause, which is another syntax error.

huangapple
  • 本文由 发表于 2020年9月1日 17:57:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/63685435.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定