1、问题
环境中MySQL数据库需要改成大小写敏感形式,而系统中存在着以前留下来的老sql,格式不规范,数目庞大,使用多种jdbc框架,如hibernate,jdbctemplate等;需要老sql的表名全部改为大写
2、mysql 大小写策略说明
my.cnf里将lower_case_table_names=1 表示对表名大写不敏感;
MySQL在Linux下数据库名、表名、列名、别名大小写规则是这样的:
1) 数据库名与表名是严格区分大小写的
2) 表的别名是严格区分大小写的;
3) 列名与列的别名在所有的情况下均是忽略大小写的;
4) 变量名也是严格区分大小写的;
5) MySQL在Windows下都不区分大小写,但是在Linux下默认是区分大小写的
3、在应用中,sql存在的情况
现在应用持久化,一般有以下情况:mybatis, hibernate, jpa, spring jdbcTemplate、jdbc(原生)等
1) hibernate 中自动生成sql,表名一般是小写
2) Mybatic、jdbcTemplat、jdbc中有可能是自己编写的sql
3) jpa实际依赖实现(如hibernate), 可以认为类似hibernate
4、当应用需要适配大小写敏感的数据库时,有以下解决方案
1) 通过在druid连接池中中拦截待执行的sql,通过druid解析器获取这条sql中的所有表名,并将表名转为大写;
2) 当数据库为mysql时,通过在druid连接池中中拦截待执行的sql,将sql全部转成大写;这种方案的可行性在于mysql数据库对值是大小写不敏感的,这样在执行查询的时候将值直接转成大写不会影响
3)Hibernate 可以通过hibernate.physical_naming_strategy的实现进行改写。大致做法是,实现
org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
重写方法:
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment context)
4)Mybatis 通过增加拦截器插件方式进行改写。如参考mybatis分页插件做法,是类似的。
5、我的处理方法
我的选择是方法1,原因是它能够比较好的兼容其他的数据库,以下为相关代码
1) 在druid配置中添加
<!-- 配置sql转大写 -->
<property name="proxyFilters">
<list>
<ref bean="tableNamesToUppercaseFilter"/>
</list>
</property>
2) 注册bean
<!-- sql转成大写配置 classPath需要自行替换为具体的路径-->
<bean id="tableNamesToUppercaseFilter" class="classPath.TableNamesToUppercaseFilter"></bean>
3) 重写 FilterEventAdapter