项目经验-开发细节


项目经验-开发细节

MybatisPlus 中 @Param 用和不用的区别

单个参数

User getUser(String name);

xml 里的 SQL 语句,加不加 @Param 都可以。

and name = #{name}

对象

  • 加 @Param
User getUser(@Param("user") User user);

xml 里的 SQL 语句,加 @Param 获取的是对象属性。

and name = #{user.name}
  • 不加 @Param
User getUser(User user);

xml 里的 SQL 语句,不加 @Param 直接使用对象属性。

and name = #{name}

多个参数

  • 不加 @Param
User getUser(Integer id, String name);

xml 里的 SQL 语句。

id = #{param1} and name = #{param2}
<!-- 或者这样写也可以 -->
id = #{id} and name = #{name}
  • 加 @Param
User getUser(@Param("id") Integer id, @Param("name") String name);

xml 里的 SQL 语句。

id = #{param1} and name = #{param2}
<!-- 或者这样写也可以 -->
id = #{id} and name = #{name}

对象

User getUser(Integer id, User user);

xml 里的 SQL 语句,加不加 @Param 都是通过对象获取。

id = #{id} and name = #{user.name}

MyBatisPlus 自动填充

  • 实体类对应字段添加注解
@ApiModelProperty("创建人")
@TableField(fill = FieldFill.INSERT)
private String createBy;

@ApiModelProperty("更新人")
@TableField(fill = FieldFill.INSERT_UPDATE)
private String updateBy;
  • 定义类继承 MetaObjectHandler
@Component
@Slf4j
public class MybatisPlusHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        if (ObjectUtils.isNotEmpty(LoginUserUtils.get())) {
            this.setFieldValByName("createBy", LoginUserUtils.get().getName(), metaObject);
            this.setFieldValByName("updateBy", LoginUserUtils.get().getName(), metaObject);
        }
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        if (ObjectUtils.isNotEmpty(LoginUserUtils.get())) {
            this.setFieldValByName("updateBy", LoginUserUtils.get().getName(), metaObject);
        }
    }
}

项目 A 在 Redis 内的 Token 信息,项目 B 去获取,类型不能自动转换

项目 A 在 Redis 内的 Token 信息如下:

{
    "@type": "com.rhx.api.model.LoginUser",
    "id": 3,
    "lastLoginTime": 1688537137824,
    "name": "182xxxx",
    "phone": "182xxxx",
    "token": "563A73FAE0F7438697A32189C16CA59F",
    "tokenTime": 1688565937824
}

通过方法 LoginUser loginUser = (LoginUser) redisUtils.get(key);在 A 项目内直接可以获取对应的数据,并且获取的数据也是 LoginUser 类型的。

项目 B 通过同样的方式却无法获取数据,通过方法 redisUtils.get(key); 查看可知,获取到的数据是 JSONObject 类型的数据,但也无法根据 JSONObject 内的方法自动转换。

  • 原因

通过项目 A 内的 Token 信息可知,对应类型指定的类和位置:"@type":"com.rhx.api.model.LoginUser" 。项目 B 如果想自动转换,那么对应位置下就需要有对应的类存在。

  • 解决方法
  1. 在项目 B 内新建包:com.rhx.api.model,对应位置内新建类:LoginUser 。
  2. 手动去解析数据。
JSONObject jsonObject = (JSONObject) redisUtils.get(key);
if (ObjectUtils.isNotEmpty(jsonObject)) {
    long id = jsonObject.getLongValue("id");
    long lastLoginTime = jsonObject.getLongValue("lastLoginTime");
    long tokenTime = jsonObject.getLongValue("tokenTime");
    String name = jsonObject.getString("name");
    String phone = jsonObject.getString("phone");
    String tokens = jsonObject.getString("token");
    UserLogin userLogin = new UserLogin(id, lastLoginTime, name, phone, tokens, tokenTime);
    LoginUserUtils.set(userLogin);
}

使用 Optional 做参数处理

  • 判断对象是否为空
// 判断对象是否存在,不存在抛出异常
Optional.ofNullable(user).orElseThrow(()->new Exception("用户不存在"));

// 判断对象是否存在,如果存在返回true
Optional.ofNullable(param).isPresent();

// 如果对象存在,直接取对应的名称
Optional.ofNullable(user).map(u -> u.getName()).get()
  • 判断集合是否为空
// 判断集合是否为空
 Optional.ofNullable(param.getList()).orElse(Lists.newArrayList());

// 判断集合是否为空,然后遍历里面的元素
List userList = getList();
Optional.ofNullable(userList).orElse(new ArrayList<>()).forEach(user -> {
});

@Transactional(rollbackFor = Exception.class) 使用总结

方法 A 调 方法 B
方法 A 是否加注解 方法 B 是否加注解 A 异常 B 异常
A 和 B 同类 A 和 B 回滚 A 和 B 回滚
A 和 B 同类 A 和 B 不回滚 A 和 B 不回滚
A 和 B 不同类 A 和 B 回滚 A 和 B 回滚
A 和 B 不同类 A 和 B 不回滚 A 不回滚 B 回滚

说明:在 try{} catch{} 中,如果把错误抛出,throw new Exception(e); 那么事务会回滚,如果不抛出,则事务不会回滚。


文章作者: L Q
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 L Q !
  目录