diff --git a/docs/zh/base/add-delete-update.md b/docs/zh/base/add-delete-update.md
index f4d0e278..597ae9e6 100644
--- a/docs/zh/base/add-delete-update.md
+++ b/docs/zh/base/add-delete-update.md
@@ -10,6 +10,59 @@ MyBatis-Flex 内置了一个名为 `BaseMapper` 的接口,它实现了基本
+**用 UpdateWrapper 新增数据**
+
+在某些场景下,我们希望在新增数据时,新增数据字段内容是数据库的某个 `函数` 或者 `SQL片段` 生成的内容,而非我们手动设置的内容。
+例如,我们希望执行的 SQL 如下:
+
+```sql
+INSERT INTO `tb_account`(`user_name`, `birthday`)
+VALUES (?, now())
+```
+
+> 以上 SQL 中,`birthday` 是由 `now()` 函数生成的内容。
+
+那么,java 代码如下:
+
+```java 9
+@Test
+public void testInsertWithRaw() {
+ Account account = new Account();
+ account.setUserName("michael");
+
+ Account newAccount = UpdateWrapper.of(account)
+// .setRaw("birthday", "now()")
+// .setRaw(ACCOUNT.BIRTHDAY, "now()")
+ .setRaw(Account::getBirthday, "now()")
+ .toEntity();
+
+ accountMapper.insert(newAccount);
+}
+```
+
+或者复杂一点的:
+
+```java 7
+@Test
+public void testInsertWithRaw() {
+ Account account = new Account();
+ account.setUserName("michael");
+
+ Account newAccount = UpdateWrapper.of(account)
+ .setRaw(Account::getBirthday, "(select xxx from ...)")
+ .toEntity();
+
+ accountMapper.insert(newAccount);
+}
+```
+其生成的 SQL 如下:
+
+```sql
+INSERT INTO `tb_account`(`user_name`, `birthday`)
+VALUES (?, (select xxx from ...))
+```
+
+> 注意,通过 `UpdateWrapper.setRaw()` 的设置,会覆盖注解 `@Column.onUpdateValue` 配置的内容。
diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java
index 35b9296f..5b71bc86 100644
--- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java
+++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/dialect/impl/CommonsDialectImpl.java
@@ -523,12 +523,16 @@ public class CommonsDialectImpl implements IDialect {
String[] insertColumns = tableInfo.obtainInsertColumns(entity, ignoreNulls);
Map onInsertColumns = tableInfo.getOnInsertColumns();
+ Map rawValueMap = tableInfo.obtainUpdateRawValueMap(entity);
+
StringJoiner sqlFields = new StringJoiner(DELIMITER);
StringJoiner sqlValues = new StringJoiner(DELIMITER);
for (String insertColumn : insertColumns) {
sqlFields.add(wrap(insertColumn));
- if (onInsertColumns != null && onInsertColumns.containsKey(insertColumn)) {
+ if (rawValueMap.containsKey(insertColumn)) {
+ sqlValues.add(rawValueMap.get(insertColumn).toSql(this));
+ } else if (onInsertColumns != null && onInsertColumns.containsKey(insertColumn)) {
sqlValues.add(onInsertColumns.get(insertColumn));
} else {
sqlValues.add(PLACEHOLDER);
diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Row.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Row.java
index 2bbaab76..e76ff077 100644
--- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Row.java
+++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/row/Row.java
@@ -32,7 +32,7 @@ import java.util.*;
import java.util.function.BooleanSupplier;
import java.util.function.Predicate;
-public class Row extends LinkedHashMap implements UpdateWrapper {
+public class Row extends LinkedHashMap implements UpdateWrapper {
//主键,多个主键用英文逗号隔开
private Set primaryKeys;
diff --git a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java
index 18d351be..4e424462 100644
--- a/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java
+++ b/mybatis-flex-core/src/main/java/com/mybatisflex/core/table/TableInfo.java
@@ -414,9 +414,14 @@ public class TableInfo {
MetaObject metaObject = EntityMetaObject.forObject(entity, reflectorFactory);
String[] insertColumns = obtainInsertColumns(entity, ignoreNulls);
+ Map rawValueMap = obtainUpdateRawValueMap(entity);
+
List