请详细描述需要增加的功能
依赖版本:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
uuid handler
@MappedTypes({UUID.class})
public class UuidTypeHandler implements TypeHandler<UUID> {
private static final Logger LOG = LoggerFactory.getLogger(UuidTypeHandler.class);
@Override
public void setParameter(PreparedStatement ps, int i, UUID parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
ps.setObject(i, null, Types.OTHER);
} else {
ps.setObject(i, parameter.toString(), Types.OTHER);
}
}
@Override
public UUID getResult(ResultSet rs, String columnName) throws SQLException {
return toUUID(rs.getString(columnName));
}
@Override
public UUID getResult(ResultSet rs, int columnIndex) throws SQLException {
return toUUID(rs.getString(columnIndex));
}
@Override
public UUID getResult(CallableStatement cs, int columnIndex) throws SQLException {
return toUUID(cs.getString(columnIndex));
}
private static UUID toUUID(String val) {
if (StringUtils.isNotBlank(val)) {
try {
return UUID.fromString(val);
} catch (IllegalArgumentException e) {
LOG.warn("Bad UUID found: {}", val);
}
}
return null;
}
}
自定义生成主键ID
@Component
@Slf4j
public class CustomIdGenerator implements IdentifierGenerator {
private final Sequence sequence = new Sequence(InetAddress.getLoopbackAddress());
@Override
public Long nextId(Object entity) {
//可以将当前传入的class全类名来作为bizKey,或者提取参数来生成bizKey进行分布式Id调用生成.
String bizKey = entity.getClass().getName();
log.info("bizKey:{}", bizKey);
MetaObject metaObject = SystemMetaObject.forObject(entity);
String name = (String) metaObject.getValue("name");
final long id = sequence.nextId();
log.info("为{}生成主键值->:{}", name, id);
// 返回生成的ID值
return id;
}
@Override
public String nextUUID(Object entity) {
return UUID.randomUUID().toString();
}
}
### 实体类
@Getter
@Setter
public class Actor implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private UUID id;
private String name;
private JSON configuration;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
mbatis-plus 生成主键,赋值
由于实体类的主键类型是UUID, 这里赋值一个字符串会报错 Caused by: org.apache.ibatis.reflection.ReflectionException: Could not set property 'id' of 'class com.echoai.entity.Actor' with value '035260f6-5026-4bd2-b364-ee3311fd4fbc' Cause: java.lang.IllegalArgumentException: argument type mismatch at org.apache.ibatis.reflection.wrapper.BeanWrapper.setBeanProperty(BeanWrapper.java:181) at org.apache.ibatis.reflection.wrapper.BeanWrapper.set(BeanWrapper.java:61) at org.apache.ibatis.reflection.MetaObject.setValue(MetaObject.java:119)
请问,这里的nextuuid() 是不是支持范型比较好呢?
Comment From: miemieYaho
请使用string,不打算支持泛型
Comment From: allendata0706
调通成功,完整示例如下
依赖版本:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.7</version>
</dependency>
jdbc连接参数
数据库配置加上 stringtype=unspecified 官方对stringtype参数的解释是: stringtype : String Specify the type to use when binding PreparedStatement parameters set via setString(). If stringtype is set to VARCHAR (the default), such parameters will be sent to the server as varchar parameters. If stringtype is set to unspecified, parameters will be sent to the server as untyped values, and the server will attempt to infer an appropriate type. This is useful if you have an existing application that uses setString() to set parameters that are actually some other type, such as integers, and you are unable to change the application to use an appropriate method such as setInt().
spring:
datasource:
url: jdbc:postgresql://${spring.datasource.host}:${spring.datasource.port}/${spring.datasource.database}?stringtype=unspecified
uuid handler
@MappedTypes({UUID.class})
public class UuidTypeHandler implements TypeHandler<UUID> {
private static final Logger LOG = LoggerFactory.getLogger(UuidTypeHandler.class);
@Override
public void setParameter(PreparedStatement ps, int i, UUID parameter, JdbcType jdbcType) throws SQLException {
if (parameter == null) {
ps.setObject(i, null, Types.OTHER);
} else {
ps.setObject(i, parameter.toString(), Types.OTHER);
}
}
@Override
public UUID getResult(ResultSet rs, String columnName) throws SQLException {
return toUUID(rs.getString(columnName));
}
@Override
public UUID getResult(ResultSet rs, int columnIndex) throws SQLException {
return toUUID(rs.getString(columnIndex));
}
@Override
public UUID getResult(CallableStatement cs, int columnIndex) throws SQLException {
return toUUID(cs.getString(columnIndex));
}
private static UUID toUUID(String val) {
if (StringUtils.isNotBlank(val)) {
try {
return UUID.fromString(val);
} catch (IllegalArgumentException e) {
LOG.warn("Bad UUID found: {}", val);
}
}
return null;
}
}
实体类
@Getter
@Setter
public class Actor implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.ASSIGN_UUID)
private String id;
private String name;
private JSON configuration;
private LocalDateTime createdAt;
private LocalDateTime updatedAt;
}
生成代码
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import org.junit.jupiter.api.Test;
import java.nio.file.Paths;
import java.sql.Types;
import java.util.Map;
import static com.baomidou.mybatisplus.generator.config.OutputFile.xml;
public class CodeGeneratorTest {
@Test
public void generator() {
FastAutoGenerator.create("jdbc:postgresql://127.0.0.1:5432/echo-ai", "postgres", "echo@1234567")
.globalConfig(builder -> builder
.author("admin")
.disableOpenDir()
.outputDir(Paths.get(System.getProperty("user.dir")) + "/src/main/java")
// .enableSwagger() // 开启 swagger 模式
.commentDate("yyyy-MM-dd")
)
.dataSourceConfig(builder ->
builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
System.out.println("metaInfo.getTypeName : " + metaInfo.getTypeName());
// uuid
if (metaInfo.getTypeName().equals("uuid")) {
return new UUIDColumnType();
}
// jsonb
if (metaInfo.getTypeName().equals("jsonb")) {
return new JSONColumnType();
}
int typeCode = metaInfo.getJdbcType().TYPE_CODE;
if (typeCode == Types.SMALLINT) {
// 自定义类型转换
return DbColumnType.INTEGER;
}
return typeRegistry.getColumnType(metaInfo);
})
)
.packageConfig(builder -> builder
.parent("com.echo.ai.repository")
.entity("entity")
.mapper("mapper")
.service("service")
.serviceImpl("service.impl")
.xml("mapper.xml")
.pathInfo(Map.of(xml, Paths.get(System.getProperty("user.dir")) + "/src/main/resources/mapper"
))
)
.strategyConfig(builder -> {
builder.entityBuilder().enableFileOverride().enableLombok().idType(IdType.ASSIGN_UUID);
builder.mapperBuilder().enableFileOverride();
builder.controllerBuilder().disable();
builder.serviceBuilder().disableService();
builder.serviceBuilder().disable();
builder.addInclude("actor");
}
)
.templateEngine(new FreemarkerTemplateEngine())
.execute();
}
static class UUIDColumnType implements IColumnType {
@Override
public String getType() {
return "String";
}
@Override
public String getPkg() {
return java.lang.String.class.getName();
}
}
static class JSONColumnType implements IColumnType {
@Override
public String getType() {
return "JSON";
}
@Override
public String getPkg() {
return JSON.class.getName();
}
}
// timestampz 类型支持
}
Comment From: nieqiurong
目前版本内置策略不支持,你可以改完input手动赋值.
Comment From: allendata0706
目前版本内置策略不支持,你可以改完input手动赋值.
java 属性是UUID,主动设置值是OK的
Comment From: nieqiurong
用input,后面版本不会报错,但会打印警告日志.
Comment From: nieqiurong
已发布 3.5.8-SNAPSHOT