项目经验-开发细节
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 如果想自动转换,那么对应位置下就需要有对应的类存在。
- 解决方法
- 在项目 B 内新建包:
com.rhx.api.model
,对应位置内新建类:LoginUser 。 - 手动去解析数据。
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); 那么事务会回滚,如果不抛出,则事务不会回滚。