实体类片段如下:
public class City implements Serializable{
/** 城市主键id */
private int id;
/** 城市名 */
private String name;
mybatis模板片段如下:
<resultMap type="City" id="CityMap">
<result column="ID" property="id" jdbcType="INTEGER" />
<result column="NAME" property="name" jdbcType="VARCHAR" />
产生问题现象:
插入的时候如果id不设置值,默认传入的是0,查询时如果数据库为null查出来的值为0,而不是报异常,造成异常隐藏。
解决方案:
应该采用对象类型如Integer
问题写法:
<insert id="insertEntityTransfer" parameterType="com.netease.payment.model.Transfer">
insert into tb_payment_transfer_order(status,name)
values(
#{status,jdbcType=VARCHAR},
#{name,jdbcType=VARCHAR}
)
建议写法:
insert into tb_payment_transfer_order(
<if test="status!= null">
status
</if>
产生问题的现象:
表中的status字段数据库中设置的为非空,并且默认值为0,模板中没有判断为空,导致插入null值,报异常
产生问题的现象:
存在一个资产对象,我们系统采用主动缓存的策略把该对象存在redis中,有需求变更资产对象,修改了字段的类型,忘记调整redis,导致上线过程,历史数据报无法序列化异常
产生问题的原因:
serialVersionUID只能保证增加字段无影响,删除字段修改调整redis的历史数据,或者在redis层做兼容。
serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。
类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的 serialVersionUID,也有可能相同。为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。
显式地定义serialVersionUID有两种用途:
1、 在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;
2、 在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。
问题的解决方案:
调整redis中的历史数据,serialVersionUID必须要指定,重写序列化和反序列化。
错误代码:
public class A {
public void noTransationMethod() {
doTransationMethod();
}
@Transactional
public void doTransationMethod() {
// do some transation
}
}
问题现象:
外部调用noTransationMethod,期望do some transation 但是没有起作用。
问题原因:
这与AOP的实现有关系,因AOP采用的是动态代理,同一个类中的不同方法之间的调用无法通过扫包拦截。
问题的解决方案:
1、 把方法拆出来放到两个类中
2、 采用实现自感知接口
3、 采用获取代理对象
if (AopUtils.isAopProxy(this))
AopContext.currentProxy()).doTransationMethod ();
需求:
需要根据客户端的特定版本号区间进行特色处理
问题现象:
对客户端版本采用oracle的比较处理发现获取的版本为非正确版本
比如 获取1.0.0-1.2.0的版本,但是库中存有1.2 1.0 1.0.2这种版本,导致查询失败
解决方案:
1、 规范版本为三位版本号
2、 采用oracle的substring方法进行处理(不建议,会导致索引失效)
网易云新用户大礼包:https://www.163yun.com/gift
本文来自网易实践者社区,经作者崔翔授权发布。