feat: 在 insert 时,若 entity 有主键,则直接使用 entity 的主键,不再通过主键生成器来生成; close #I88TX1

This commit is contained in:
开源海哥 2023-10-17 19:51:57 +08:00
parent 90d6bc1051
commit 9c204fbcb0
7 changed files with 144 additions and 14 deletions

View File

@ -69,10 +69,15 @@ public class CustomKeyGenerator implements KeyGenerator {
@Override
public void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
Object entity = ((Map) parameter).get(FlexConsts.ENTITY);
Configuration configuration = ms.getConfiguration();
MetaObject metaParam = configuration.newMetaObject(parameter);
Object generateId = keyGenerator.generate(entity, idInfo.getColumn());
try {
Object existId = tableInfo.getValue(entity, idInfo.getProperty());
// 若用户主动设置了主键则使用用户自己设置的主键不再生成主键
if (existId != null){
return;
}
Configuration configuration = ms.getConfiguration();
MetaObject metaParam = configuration.newMetaObject(parameter);
Object generateId = keyGenerator.generate(entity, idInfo.getColumn());
MetaObject metaObjectForProperty = metaParam.metaObjectForProperty(FlexConsts.ENTITY);
Invoker setInvoker = tableInfo.getReflector().getSetInvoker(idInfo.getProperty());
Object id = ConvertUtil.convert(generateId, setInvoker.getType());

View File

@ -55,8 +55,13 @@ public class RowCustomKeyGenerator implements KeyGenerator {
@Override
public void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
Row row = (Row) ((Map) parameter).get(FlexConsts.ROW);
Object generateId = keyGenerator.generate(row, rowKey.getKeyColumn());
try {
Object existId = row.get(rowKey.getKeyColumn());
// 若用户主动设置了主键则使用用户自己设置的主键不再生成主键
if (existId != null) {
return;
}
Object generateId = keyGenerator.generate(row, rowKey.getKeyColumn());
row.put(rowKey.getKeyColumn(), generateId);
} catch (Exception e) {
throw FlexExceptions.wrap(e);

View File

@ -35,7 +35,7 @@ public class ColumnInfo {
protected String[] alias;
/**
* java entity 定义的属性名称
* java entity 定义的属性名称field name
*/
protected String property;

View File

@ -718,6 +718,10 @@ public class TableInfo {
return values;
}
public Object getValue(Object entity, String property) {
FieldWrapper fieldWrapper = FieldWrapper.of(entityClass, property);
return fieldWrapper.get(entity);
}
/**
* 获取主键值
@ -1119,7 +1123,6 @@ public class TableInfo {
private Object buildColumnSqlArg(MetaObject metaObject, String column) {
ColumnInfo columnInfo = columnInfoMapping.get(column);
Object value = getPropertyValue(metaObject, columnInfo.property);
if (value != null) {
TypeHandler typeHandler = columnInfo.buildTypeHandler(null);
if (typeHandler != null) {
@ -1137,7 +1140,7 @@ public class TableInfo {
}
private Object getPropertyValue(MetaObject metaObject, String property) {
public Object getPropertyValue(MetaObject metaObject, String property) {
if (property != null && metaObject.hasGetter(property)) {
return metaObject.getValue(property);
}

View File

@ -0,0 +1,77 @@
/*
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.test;
import com.mybatisflex.annotation.ColumnMask;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import com.mybatisflex.core.mask.Masks;
import java.io.Serializable;
@Table(value = "tb_account")
public class Account7 extends BaseEntity implements Serializable, AgeAware {
private static final long serialVersionUID = 1L;
@Id(keyType = KeyType.Generator, value = "test")
private Long id;
@ColumnMask(Masks.CHINESE_NAME)
private String userName;
private int age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Override
public int getAge() {
return age;
}
@Override
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", userName='" + userName + '\'' +
", age=" + age +
'}';
}
}

View File

@ -20,6 +20,7 @@ import com.mybatisflex.core.MybatisFlexBootstrap;
import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.audit.ConsoleMessageCollector;
import com.mybatisflex.core.audit.MessageCollector;
import com.mybatisflex.core.keygen.KeyGeneratorFactory;
import com.mybatisflex.core.mybatis.Mappers;
import com.mybatisflex.core.query.If;
import com.mybatisflex.core.query.QueryWrapper;
@ -28,6 +29,7 @@ import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.core.update.UpdateWrapper;
import com.mybatisflex.core.util.UpdateEntity;
import com.mybatisflex.mapper.Account6Mapper;
import com.mybatisflex.mapper.Account7Mapper;
import com.mybatisflex.mapper.ArticleMapper;
import org.apache.ibatis.logging.stdout.StdOutImpl;
import org.junit.Assert;
@ -59,11 +61,14 @@ public class AccountTester {
FlexGlobalConfig.getDefaultConfig()
.setLogicDeleteColumn("is_delete");
KeyGeneratorFactory.register("test", new TestKeyGenerator());
MybatisFlexBootstrap bootstrap = MybatisFlexBootstrap.getInstance()
.setDataSource(dataSource)
.setLogImpl(StdOutImpl.class)
.addMapper(AccountMapper.class)
.addMapper(Account6Mapper.class)
.addMapper(Account7Mapper.class)
.addMapper(ArticleMapper.class)
.start();
@ -151,7 +156,7 @@ public class AccountTester {
public void testLeftJoinSelectWithIgnoreColumn() {
QueryWrapper queryWrapper = QueryWrapper.create();
queryWrapper
.select(ACCOUNT.ID,ACCOUNT.AGE,ARTICLE.TITLE)
.select(ACCOUNT.ID, ACCOUNT.AGE, ARTICLE.TITLE)
.from(ACCOUNT)
.leftJoin(ARTICLE).on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID))
.where(ACCOUNT.ID.ge(1));
@ -168,7 +173,7 @@ public class AccountTester {
Account account = new Account();
account.setId(1L);
account = UpdateWrapper.of(account)
.set(Account::getId,1)
.set(Account::getId, 1)
.set(Account::getAge, 20)
//设置 Ignore 字段会被自动忽略
.setRaw(Account::getTitle, "xxxx")
@ -177,13 +182,11 @@ public class AccountTester {
}
@Test
public void testSelectAsToDTO() {
QueryWrapper queryWrapper = QueryWrapper.create();
// queryWrapper.select(ACCOUNT.ALL_COLUMNS,ARTICLE.TITLE.as(AccountDTO::getPermissions))
queryWrapper.select(ACCOUNT.ALL_COLUMNS,ACCOUNT.USER_NAME.as(AccountDTO::getTestOtherField))
queryWrapper.select(ACCOUNT.ALL_COLUMNS, ACCOUNT.USER_NAME.as(AccountDTO::getTestOtherField))
// queryWrapper.select(ACCOUNT.ALL_COLUMNS)
.from(ACCOUNT).leftJoin(ARTICLE).on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID));
List<AccountDTO> accountDTOS = accountMapper.selectListByQueryAs(queryWrapper, AccountDTO.class);
@ -277,7 +280,7 @@ public class AccountTester {
account1.setUserName("michael");
account1.setAge(5);
Assert.assertEquals(mapper.insertSelective(account1),1);
Assert.assertEquals(mapper.insertSelective(account1), 1);
Account6 account2 = new Account6();
@ -285,7 +288,34 @@ public class AccountTester {
account2.setUserName("michael");
account2.setAge(5);
Assert.assertEquals(mapper.insertSelective(account2),1);
Assert.assertEquals(mapper.insertSelective(account2), 1);
}
/**
* issues https://gitee.com/mybatis-flex/mybatis-flex/issues/I88TX1
*/
@Test
public void testInsertWithEntityId() {
Account7Mapper mapper = MybatisFlexBootstrap.getInstance()
.getMapper(Account7Mapper.class);
Account7 account1 = new Account7();
account1.setId(1L);
account1.setUserName("michael");
account1.setAge(5);
int result1 = mapper.insert(account1);
Assert.assertEquals(result1, 1);
Account7 account2 = new Account7();
// account2.setId(1L); 不设置主键自动生成主键
account2.setUserName("michael");
account2.setAge(5);
int result2 = mapper.insert(account2);
Assert.assertEquals(result2, 1);
}

View File

@ -0,0 +1,10 @@
package com.mybatisflex.test;
import com.mybatisflex.core.keygen.IKeyGenerator;
public class TestKeyGenerator implements IKeyGenerator {
@Override
public Object generate(Object entity, String keyColumn) {
return System.currentTimeMillis() / 1000;
}
}