一、前言:
有这样一个需求,需要将某个库的数据,同步到其他的N个库中,保证数据的一致性即可。
从文字上来看,不是很简单的一个东西吗,用JAVA很快就搞定了,用azkaban编写脚本的方式也是可以搞定的。很不幸,azkaban编写的脚本因为某些原因,挂掉了,需要用JAVA来写一套。JAVA写,so easy!
二、事情往往不是那么简单
乍一看是非常的简单啊,且不知已经被以前埋下了一个大坑。直接上表及整个处理过程。
1.表结构如下:很简单的一个表啦。注意:思考这里的命名是否会引起某些错误,或者功力不够的直接会进去出不来?
2.开始写JAVA吧
写完逻辑后,发现用jpa的查询查不出来任何数据,虽然数据库中有。
报错信息:QuerySyntaxException: TestAccount(实体类)is not mapped
网上查询一番后,试验过感觉都没能解决问题。
将映射返回的结果改为:List<Object[]> 这样的 就能成功映射。
将映射结果改为:List<TestAccount> 这样不能成功映射,提示 cloumn group_account is not found
由此说明,数据库中数据是已经查询到程序里面了,只是在数据到po的转换过程中出现了异常。再去看转换规则,是根据驼峰命名这种方式寻找setter方法,因此修改查询出来的数据的别名为驼峰。
这样修改后,就搞定啦。
三、踩的坑
1.JPA 是有点坑,当数据库中的字段是groupAccount,而实体也是groupAccount时,会报异常:group_account not found,这个时候需要加别名 group_account 来处理;同样的情况,mysql完全不存在这个问题。但是mysql的查询要写很多sql,利弊全看项目要求了。
2.hql 和 sql 和 jpa 自带的命名,这三者需要区分清楚
3.如果上面的这张表里面,要查询 account in(),无法实现这个功能。业务需要,要么改表字段,要么用mybatis来做吧。
四、总结
1.数据库命名尽量用驼峰命名,不然很容易踩坑;
2.要区分清楚 自定义@Query注解时,hql 和 sql
3.jpa在执行自定义sql时,拿到结果后,需要进行数据转换才能映射到实体。而数据转换时按照驼峰命名的规则来进行映射的。在我们的例子中,因为数据库的字段不是驼峰命名,因此,会报cloumn group_account not found 这样的异常。
4.需要了解整个的流转流程,问题定位就更加清晰了。