在mybatis中,根据使用的数据库不同,执行不同的sql语句

时间:2025-01-27 08:51:01

在我们的项目中,使用的是SqlServer数据库,由于需要多地部署,即A地点部署一套,B地点部署一套,C地点部署一套,部署的项目之间是相互独立的。由于最近领导说以后部署的项目要使用mysql数据库,那么问题就来了,以前的项目是sqlServer 的,现在还要兼容mysql,维护两套mapper有点难受,而且大部分sql其实都是通用的,只是在一些函数和方言上有所区别,所以我刚开始想将当前的数据库类型写在配置文件中,通过mybatis 的if 标签进行判断当前的数据库类型,再执行相应的语句。

<select id="findProcessHistory" resultType="RepairTicket">
	SELECT * FROM table a
    <where>
    	 like 
        <if test="dbName == 'oracle'">'%'||#{code}||'%'</if>
        <if test="dbName == 'mssql'">'%'+#{code}+'%'</if>
        <if test="dbName == 'mysql'">concat('%',#{code},'%')</if>
    </where>
</select>

这样写完的确是可以了,不过也带来了恶心的问题,每个接口传值的时候,我都要去加一个名为dbName的参数,然后传进来。无形中又添加了很多的工作量,

这是原来的接口

@MyBatisDao
public interface RepairTicketDao extends CrudDao<RepairTicket> {
    List<RepairTicket> findProcessHistory(String cloum);
}

这是修改后的接口

@MyBatisDao
public interface RepairTicketDao extends CrudDao<RepairTicket> {
    List<RepairTicket> findProcessHistory(@Param("cloum")String cloum,@Param("dbName") String dbName);
}

没个mapper都这么改的话我得改死。所以我就在想,有没有什么办法能直接读取配置文件中的属性,而不是通过接口来传过来。然后在网上找了半天。结果很遗憾,没找到!
但是,我找到了另外一种方式,那就是使用OJNL表达式调用java类来获取配置文件中的数据。mybatis中的 if 标签中的判断都是通过OGNL表达式来实现的。OGNL可以调用java的方法并获取其中的返回值。具体参考这篇博文:
/isea533/article/details/50061705
最后通过调用项目中读取配置文件的java类来从配置文件中获取数据库类型

<select id="findProcessHistory" resultType="RepairTicket">
	SELECT * FROM table a
    <where>
    	 like 
         <if test="@@getConfig('') == 'oracle'">'%'||#{code}||'%'</if>
         <if test="@@getConfig('') == 'mssql'">'%'+#{code}+'%'</if>
         <if test="@@getConfig('') == 'mysql'">concat('%',#{code},'%')
    </where>
</select>

@ 为类的名字,@getConfig(‘’) 是静态方法的名字 这是一个获取配置文件属性的方法

到现在。我的问题就已经解决了。

不足之处

老实说,我觉得这种方式还是有些问题,或者说不妥的地方。由于是从配置文件中读取数据,那如果是多数据源的情况下如果第一和第二数据源都去访问这个方法且数据库类型不同的情况下就会出现问题。
如果能直接从链接中获取数据库类型会更好一点。再或者有没有更好的判断方式。反正这个就先告一段落。如果有大佬有更好的方案,欢迎大佬来喷!