mybatis中对Oracle特殊字段做处理

本文介绍了在Oracle数据库中处理BLOB和DATE类型的正确方法。包括插入或更新时使用rawtohex及to_date函数,以及查询时如何利用UTL_RAW.CAST_TO_VARCHAR2和to_char函数。

1.插入或更新数据库时

   BLOB:rawtohex(#{字段名})   否则,会报错:ORA-01465: 无效的十六进制数字

   DATE:to_date(#{字段名},'yyyy-mm-dd hh24:mi:ss')  

 2.查询

  BLOB:UTL_RAW.CAST_TO_VARCHAR2(字段)

  Date:to_char(字段名,'yyyy-mm-dd hh24:mi:ss')

 

 

 

 

在使用 **MyBatis-Plus** 操作 Oracle 数据库时,如果表有 **多个字段组成的联合主键(复合主键)**,而你又想使用 MyBatis-Plus 的 `@TableId` 注解来标识主键字段,需要注意:**MyBatis-Plus 本身并不直接支持复合主键的完整 ORM 映射操作**。 也就是说,MyBatis-Plus 要求实体类中必须有一个字段标记为 `@TableId` 作为主键,但它不支持将多个字段同时作为“逻辑上的联合主键”进行 CRUD 自动处理(比如 `selectById`, `updateById` 等方法无法直接用于多字段主键场景)。 --- ### ✅ 解决方案 #### 方案一:使用 `@TableId` + 复合主键逻辑封装(推荐法) 虽然不能直接用两个 `@TableId`,但你可以: 1. 在实体类中标记其中一个字段为 `@TableId`(通常选业务无关的自增/序列字段,若没有则选一个代表性的); 2. 其他主键字段仅使用 `@TableField`; 3. 手动实现基于多字段的查询和更新(通过 `QueryWrapper` 或 XML 自定义 SQL); > ⚠️ 注意:Oracle 中一般没有自增主键,常用 `SEQUENCE + TRIGGER` 或手动赋值。 --- ### 示例代码(Oracle字段主键:order_id + item_id) ```java import com.baomidou.mybatisplus.annotation.*; import lombok.Data; @Data @TableName("t_order_item") // 对应 Oracle 表名(注意大小写) public class OrderItem { @TableId(value = "ORDER_ID", type = IdType.NONE) private String orderId; @TableId(value = "ITEM_ID", type = IdType.NONE) // ❌ 错误!不能有两个 @TableId private String itemId; } ``` 上面的写法是 **非法的** —— MyBatis-Plus 不允许两个字段都加 `@TableId`。 --- ### ✅ 正确法 只保留一个 `@TableId` 是不行的。所以正确法是: > **放弃使用 `@TableId` 标识所有主键字段,转而全部使用 `@TableField`,并通过自定义条件构造器完成操作。** --- ### ✅ 推荐法:使用 `@TableField` + 自定义查询 ```java import com.baomidou.mybatisplus.annotation.*; import lombok.Data; @Data @TableName("T_ORDER_ITEM") public class OrderItem { @TableField("ORDER_ID") private String orderId; @TableField("ITEM_ID") private String itemId; @TableField("PRODUCT_NAME") private String productName; @TableField("QUANTITY") private Integer quantity; } ``` 然后使用 `QueryWrapper` 构造复合主键查询: ```java // 查询某条记录(根据两个字段) QueryWrapper<OrderItem> wrapper = new QueryWrapper<>(); wrapper.eq("ORDER_ID", "ORD001") .eq("ITEM_ID", "ITM001"); OrderItem item = orderItemMapper.selectOne(wrapper); ``` 插入时也需手动赋值主键(或使用 Oracle Sequence): ```java OrderItem item = new OrderItem(); item.setOrderId("ORD001"); item.setItemId("ITM001"); item.setProductName("iPhone"); item.setQuantity(2); orderItemMapper.insert(item); ``` --- ### ✅ 高级方案:使用复合主键包装类(DTO)+ XML 自定义 SQL 创建一个专门用于主键查询的 DTO 或参数对象,并在 Mapper 中编写 XML SQL: #### Mapper 接口: ```java public interface OrderItemMapper extends BaseMapper<OrderItem> { OrderItem selectByCompositeKey(@Param("orderId") String orderId, @Param("itemId") String itemId); } ``` #### XML 文件(resources/mapper/OrderItemMapper.xml): ```xml <select id="selectByCompositeKey" resultType="com.example.entity.OrderItem"> SELECT ORDER_ID, ITEM_ID, PRODUCT_NAME, QUANTITY FROM T_ORDER_ITEM WHERE ORDER_ID = #{orderId} AND ITEM_ID = #{itemId} </select> ``` 调用方式: ```java OrderItem item = orderItemMapper.selectByCompositeKey("ORD001", "ITM001"); ``` --- ### ✅ 补充:Oracle 主键生成策略(如需自动分配) 如果你希望某个字段Oracle 序列生成,可以这样设置: ```java @TableId(value = "ID", type = IdType.INPUT) private Long id; ``` 并在插入前手动赋值: ```java String seqValue = orderItemMapper.selectSequenceValue(); // 调用 sequence.nextval item.setId(Long.valueOf(seqValue)); ``` 或者使用数据库触发器自动填充。 --- ### 总结说明 | 功能 | 是否支持 | |------|----------| | 多个 `@TableId` 字段 | ❌ 不支持 | | 复合主键自动 CRUD(如 updateById) | ❌ 不支持 | | 使用 `QueryWrapper` 实现多字段查询 | ✅ 支持 | | 使用 XML 自定义 SQL 操作复合主键 | ✅ 推荐 | | 结合 Oracle Sequence 自动生成主键 | ✅ 可行 | --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值