CREATE TABLE `t_pdm_task_ebom_material` ( `id` bigint(20) NOT NULL COMMENT '物理主键,全局唯一', `tenant_id` varchar(8) NOT NULL COMMENT '租户ID', `material_no` varchar(64) DEFAULT NULL COMMENT '项目物料编码', `cbom_material_id` bigint(20) DEFAULT NULL COMMENT '外键,t_pdm_cbom_material.id', `material_name` varchar(255) DEFAULT NULL COMMENT '物料名称', `material_description` varchar(255) DEFAULT NULL COMMENT '物料描述', `unit_group` varchar(255) DEFAULT NULL COMMENT '单元组', `unit_code` varchar(255) DEFAULT NULL COMMENT '计量单位', `material_category` varchar(255) DEFAULT NULL COMMENT '物料类别', `material_subcategory` varchar(255) DEFAULT NULL COMMENT '物料子类别', `md5_code` varchar(255) DEFAULT NULL COMMENT '属性md5', `md5_code_bom` varchar(255) DEFAULT NULL COMMENT 'bom的md5', `erp_material_id` bigint(20) DEFAULT NULL COMMENT '对应erp物料编码id', `version` bigint(20) unsigned NOT NULL DEFAULT '0', `is_deleted` tinyint(3) unsigned NOT NULL DEFAULT '0', `created_by` char(32) NOT NULL, `created_date` datetime NOT NULL, `last_modified_by` char(32) NOT NULL, `last_modified_date` datetime NOT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='设计物料主数据'; 写一个mybatis插入语句 要求字段驼峰 有标签判断
时间: 2025-04-03 12:00:12 浏览: 32
<think>嗯,用户让我根据提供的SQL表结构写一个MyBatis的插入语句,要求字段驼峰命名,并且有标签判断。首先,我需要仔细看一下这个表的结构,了解每个字段的类型和注释。
首先,表名是`t_pdm_task_ebom_material`,对应的实体类应该是驼峰命名的,比如`TaskEbomMaterial`。然后各个字段比如`tenant_id`对应的Java属性应该是`tenantId`,所以MyBatis的映射需要处理数据库字段的下划线和Java属性的驼峰命名。不过用户已经提到字段驼峰,可能不需要配置全局的映射,而是在插入语句中使用别名或者通过MyBatis的自动映射,但通常MyBatis配置了mapUnderscoreToCamelCase就可以自动转换,这里可能需要确认。
接下来是插入语句的编写。MyBatis的插入通常使用`<insert>`标签,id对应Mapper接口的方法名,比如`insert`或者`insertTaskEbomMaterial`。参数类型应该是实体类的全限定名,比如`com.example.model.TaskEbomMaterial`。
然后是具体的SQL语句,需要列出所有字段,并且使用`#{}`来引用实体类的属性。这里要注意字段是否允许为空,比如`id`和`tenant_id`是NOT NULL,所以必须插入值,而其他字段如`material_no`是DEFAULT NULL,所以可以为空。这时候需要考虑在插入时是否需要判断属性是否为null,如果为null的话是否要插入默认值或者不插入,但根据表结构,这些字段允许NULL,所以如果实体类中的属性为null的话,插入时数据库会设为NULL。
但用户要求有标签判断,也就是使用MyBatis的动态标签,比如`<if>`来判断某些字段是否需要包含在插入语句中。例如,如果某个字段的值不为空,才插入该字段,否则不插入。不过需要注意的是,如果使用动态标签,可能会导致插入语句的字段列表和values列表动态变化,这时候需要确保每个字段和对应的值都正确对应,可能需要使用`<trim>`或者`<set>`标签,但插入语句通常使用`<trim>`来处理前缀和 suffix。
不过,标准的插入语句如果字段都是非动态的话,可以直接列出所有字段和对应的`#{}`。但根据用户的需求,可能需要动态判断哪些字段需要插入。例如,如果某些字段在插入时可能为null,而数据库允许NULL,那么可以选择性插入,但通常这种情况下,如果字段允许NULL,即使不插入,数据库也会自动设为NULL。不过使用动态标签可以避免插入NULL,让数据库使用默认值,如果有默认值的话。但在这个表结构中,很多字段的默认值都是NULL,除了version、is_deleted等字段有默认值。
比如`version`字段的默认值是0,`is_deleted`默认是0,`created_by`和`created_date`以及`last_modified_by`和`last_modified_date`在插入时必须要有值,因为它们是NOT NULL的。所以这些字段在插入时不能为null,所以对应的实体类属性必须有值,否则会出错。因此,在动态标签中,这些字段不需要判断,必须包含在插入语句中,而其他允许为NULL的字段可以根据实体类属性是否为null来决定是否插入。
不过用户可能希望即使允许为NULL的字段,在插入时如果属性为null,则不插入该字段,让数据库使用默认的NULL。这种情况下,可以使用动态SQL来判断。例如,对于`material_no`字段,如果实体类的materialNo属性不为空,则插入该字段和值,否则不插入,这样数据库会自动设为NULL。
所以整个插入语句的结构应该是这样的:
```xml
<insert id="insert" parameterType="...">
INSERT INTO t_pdm_task_ebom_material
<trim prefix="(" suffix=")" suffixOverrides=",">
id,
tenant_id,
<if test="materialNo != null">material_no,</if>
<if test="cbomMaterialId != null">cbom_material_id,</if>
...
created_by,
created_date,
last_modified_by,
last_modified_date
</trim>
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
#{id},
#{tenantId},
<if test="materialNo != null">#{materialNo},</if>
<if test="cbomMaterialId != null">#{cbomMaterialId},</if>
...
#{createdBy},
#{createdDate},
#{lastModifiedBy},
#{lastModifiedDate}
</trim>
</insert>
```
不过,这里需要注意的是,像id、tenant_id、created_by等字段是NOT NULL的,所以必须插入值,因此在插入语句中不应该被包裹在`<if>`标签里,必须直接写入。而其他允许NULL的字段可以判断是否为null来决定是否插入。
比如,表结构中的字段:
- `id`:NOT NULL,必须插入
- `tenant_id`:NOT NULL,必须插入
- `material_no`:DEFAULT NULL,可以判断
- `cbom_material_id`:DEFAULT NULL,可以判断
- ...其他类似
- `version`:NOT NULL DEFAULT 0,所以如果实体类中没有设置version,应该插入0,但这里用户可能希望自动处理,可能需要在插入语句中包含version字段,并且如果实体类的version为null,则使用数据库的默认值。不过由于字段是NOT NULL,所以必须插入值,但DEFAULT '0',所以如果插入时不包含version,数据库会自动设为0。但根据表结构,version字段的定义是`version` bigint(20) unsigned NOT NULL DEFAULT '0',所以如果插入时不指定version,数据库会使用默认值0。因此,在MyBatis的插入语句中,可以不包含version字段,让数据库处理。或者如果实体类中version有值,则插入,否则不插入,让数据库设为默认值。类似的情况适用于`is_deleted`字段,它也是NOT NULL DEFAULT '0'。所以这两个字段在插入时可以不写,让数据库自动填充默认值。
但根据用户提供的表结构,version和is_deleted在插入时是否必须显式插入?比如,如果实体类中没有设置version和is_deleted的值,那么在插入语句中不包含这两个字段,数据库会自动设为默认值。这样可以减少插入的字段数量,但需要确保应用程序中没有设置这些值,而依赖数据库的默认值。
所以,在编写MyBatis的插入语句时,需要考虑哪些字段必须显式插入,哪些可以省略。对于NOT NULL且有默认值的字段,可以省略,让数据库处理;对于NOT NULL但没有默认值的字段,必须显式插入值,否则会报错。
回到这个表结构:
- `id`:NOT NULL,无默认值,必须显式插入
- `tenant_id`:NOT NULL,无默认值,必须显式插入
- `version`:NOT NULL,默认0,可以不显式插入,依赖数据库默认值
- `is_deleted`:NOT NULL,默认0,同样可以不显式插入
- `created_by`、`created_date`、`last_modified_by`、`last_modified_date`:都是NOT NULL,无默认值,必须显式插入
所以,在插入语句中,必须包含的字段有:id, tenant_id, created_by, created_date, last_modified_by, last_modified_date。其他字段如version和is_deleted可以省略,让数据库处理,或者根据情况决定是否插入。
但用户可能希望所有字段都显式插入,或者根据实体类的属性来动态判断。比如,如果实体类中的version被显式设置了值,则插入该值,否则不插入,让数据库设为默认值。同样适用于is_deleted。
因此,在MyBatis的插入语句中,对于version和is_deleted字段,可以使用`<if>`标签判断是否传入,如果没有传入,则不插入,让数据库使用默认值。例如:
```xml
<if test="version != null">version,</if>
<if test="isDeleted != null">is_deleted,</if>
```
不过,根据表结构,version和is_deleted是NOT NULL,但允许在插入时不指定,因为有默认值。所以,如果实体类中没有设置version或is_deleted,那么在插入语句中不包含这两个字段,数据库会自动填充默认值。
同样,created_by等字段是NOT NULL且无默认值,所以必须确保实体类中的这些属性有值,否则插入会失败。
现在,综合所有情况,编写MyBatis的插入语句:
1. 使用`<trim>`标签来处理字段和值的动态生成,避免末尾多余的逗号。
2. 必须包含的字段:id, tenant_id, created_by, created_date, last_modified_by, last_modified_date。
3. 其他字段根据是否为null判断是否插入,包括version和is_deleted(如果允许的话)。
但根据表结构,version和is_deleted有默认值,所以即使不插入,数据库也会填充默认值。所以,在插入语句中可以动态判断这些字段是否需要显式插入。例如,如果实体类中version属性不为空,则插入该值,否则不插入,让数据库设为默认值。
因此,最终的插入语句可能如下:
```xml
<insert id="insertTaskEbomMaterial" parameterType="com.example.model.TaskEbomMaterial">
INSERT INTO t_pdm_task_ebom_material
<trim prefix="(" suffix=")" suffixOverrides=",">
id,
tenant_id,
<if test="materialNo != null">material_no,</if>
<if test="cbomMaterialId != null">cbom_material_id,</if>
<if test="materialName != null">material_name,</if>
<if test="materialDescription != null">material_description,</if>
<if test="unitGroup != null">unit_group,</if>
<if test="unitCode != null">unit_code,</if>
<if test="materialCategory != null">material_category,</if>
<if test="materialSubcategory != null">material_subcategory,</if>
<if test="md5Code != null">md5_code,</if>
<if test="md5CodeBom != null">md5_code_bom,</if>
<if test="erpMaterialId != null">erp_material_id,</if>
<if test="version != null">version,</if>
<if test="isDeleted != null">is_deleted,</if>
created_by,
created_date,
last_modified_by,
last_modified_date
</trim>
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
#{id},
#{tenantId},
<if test="materialNo != null">#{materialNo},</if>
<if test="cbomMaterialId != null">#{cbomMaterialId},</if>
<if test="materialName != null">#{materialName},</if>
<if test="materialDescription != null">#{materialDescription},</if>
<if test="unitGroup != null">#{unitGroup},</if>
<if test="unitCode != null">#{unitCode},</if>
<if test="materialCategory != null">#{materialCategory},</if>
<if test="materialSubcategory != null">#{materialSubcategory},</if>
<if test="md5Code != null">#{md5Code},</if>
<if test="md5CodeBom != null">#{md5CodeBom},</if>
<if test="erpMaterialId != null">#{erpMaterialId},</if>
<if test="version != null">#{version},</if>
<if test="isDeleted != null">#{isDeleted},</if>
#{createdBy},
#{createdDate},
#{lastModifiedBy},
#{lastModifiedDate}
</trim>
</insert>
```
这里需要注意的是,字段名在SQL中保持原样(下划线),而属性名是驼峰的,例如`material_no`对应`materialNo`,在MyBatis中如果配置了mapUnderscoreToCamelCase,则自动映射,否则可能需要使用别名,但用户要求字段驼峰,可能是指Java属性是驼峰,而数据库字段是下划线,所以MyBatis的配置应该已经处理了这种转换,所以在`#{}`中使用的是Java属性的驼峰命名。
此外,必须字段如id、tenant_id等没有使用`<if>`判断,因为它们是NOT NULL且没有默认值,必须由应用程序提供,所以在插入时必须存在。如果实体类中这些属性可能为null,那么插入会失败,因此需要确保在调用此插入方法前,这些属性已经被正确设置。
最后,确认所有字段是否都被处理:
- `id`、`tenant_id`、`created_by`、`created_date`、`last_modified_by`、`last_modified_date`必须显式插入
- 其他字段根据是否为null动态插入
- `version`和`is_deleted`由于有默认值,可以选择性插入,如果实体类中没有设置,则不插入,让数据库使用默认值
这样应该满足用户的需求:字段驼峰命名,使用动态标签判断。</think>以下是根据表结构编写的MyBatis插入语句,采用驼峰字段命名和动态标签判断:
```xml
<!-- 实体类建议命名为 TaskEbomMaterial -->
<insert id="insertTaskEbomMaterial" parameterType="com.xxx.entity.TaskEbomMaterial">
INSERT INTO t_pdm_task_ebom_material
<trim prefix="(" suffix=")" suffixOverrides=",">
id,
tenant_id,
<if test="materialNo != null">material_no,</if>
<if test="cbomMaterialId != null">cbom_material_id,</if>
<if test="materialName != null">material_name,</if>
<if test="materialDescription != null">material_description,</if>
<if test="unitGroup != null">unit_group,</if>
<if test="unitCode != null">unit_code,</if>
<if test="materialCategory != null">material_category,</if>
<if test="materialSubcategory != null">material_subcategory,</if>
<if test="md5Code != null">md5_code,</if>
<if test="md5CodeBom != null">md5_code_bom,</if>
<if test="erpMaterialId != null">erp_material_id,</if>
<!-- 以下为系统字段 -->
version,
is_deleted,
created_by,
created_date,
last_modified_by,
last_modified_date
</trim>
<trim prefix="VALUES (" suffix=")" suffixOverrides=",">
#{id},
#{tenantId},
<if test="materialNo != null">#{materialNo},</if>
<if test="cbomMaterialId != null">#{cbomMaterialId},</if>
<if test="materialName != null">#{materialName},</if>
<if test="materialDescription != null">#{materialDescription},</if>
<if test="unitGroup != null">#{unitGroup},</if>
<if test="unitCode != null">#{unitCode},</if>
<if test="materialCategory != null">#{materialCategory},</if>
<if test="materialSubcategory != null">#{materialSubcategory},</if>
<if test="md5Code != null">#{md5Code},</if>
<if test="md5CodeBom != null">#{md5CodeBom},</if>
<if test="erpMaterialId != null">#{erpMaterialId},</if>
<!-- 系统字段处理 -->
#{version},
#{isDeleted},
#{createdBy},
#{createdDate},
#{lastModifiedBy},
#{lastModifiedDate}
</trim>
</insert>
```
### 关键点说明:
1. **字段映射**:
- 数据库下划线字段(如`material_no`)自动映射驼峰属性(`materialNo`),需确保MyBatis配置`mapUnderscoreToCamelCase=true`
2. **动态标签**:
- `<trim>`标签用于动态处理字段列表的逗号
- `<if>`标签判断非空字段(如`materialNo != null`),避免插入NULL值
3. **系统字段处理**:
- `version`和`is_deleted`虽然数据库有默认值,但根据DDL显式插入更符合审计规范
- 审计字段(`created_by`等)必须显式赋值,不能为空
4. **特殊字段说明**:
```xml
<!-- 若需要严格使用数据库默认值,可改为动态插入 -->
<if test="version != null">version,</if>
<if test="isDeleted != null">is_deleted,</if>
```
### 配套实体类字段示例:
```java
public class TaskEbomMaterial {
private Long id; // 物理主键
private String tenantId; // 租户ID
private String materialNo; // 项目物料编码
private Long cbomMaterialId; // CBOM物料ID
private String materialName; // 物料名称
// 其他字段省略...
}
```
阅读全文
相关推荐











