ORCLE与MySQL的相互转化
1.情景展示
在实际开发中,不同的地方可能所需使用的数据库是不同的。
这就要求,我们开发的程序需要兼容不同的数据库,放到程序里面就是:
需要有不同类型的sqlMap文件。
以既要兼容MySQL,也要兼容Oracle进行举例说明。
2.准备工作
第一步
根据已经写好的一套sql进行复制,然后,在原有sql的基础上修改成对应数据库所支持的SQL。
第二步
修改mapper.xml的扫描路径
以及分页插件的数据库类型
第三步
修改数据库连接配置
MYSQL
spring:
datasource:
url: jdbc:mysql://192.168.0.1:3306/test?useUnicode=true&characterEncoding=utf8
username: 123
password: 123
driverClassName: com.mysql.cj.jdbc.Driver
hikari:
maximum-pool-size: 200
ORACLE
spring:
datasource:
url: jdbc:oracle:thin:@192.168.1.1:1521:orcl
username: TEST
password: TEST
driverClassName: oracle.jdbc.driver.OracleDriver
hikari:
maximum-pool-size: 200
3.具体转换
字符串拼接
MYSQL使用concat()
<if test="code != null and code != ''">
and code like CONCAT('%',#{code},'%')
</if>
ORACLE使用管道符||
<if test="code != null and code != ''">
and code like '%' || #{code} || '%'
</if>
虽然ORACLE也可以使用CONCAT()连接字符串,但是,它只能将两个字符串拼接到一起。
如果需要拼接2个以上的字符串,只能嵌套N次,形如:
CONCAT(CONCAT('%',#{code}),'%')
字符串转日期
日期转字符串
mysql使用DATE_FORMAT()
<if test="endTime != null">
,DATE_FORMAT(#{endTime},'%Y-%m-%d 23:59:59') as endTime
</if>
DATE_FORMAT(base_eva_detail.create_time,'%Y-%m-%d %H:%i:%s') as create_time,
在mysql中,%c表示月份,个位数月份前面不会自动补零;
而%m表示月份,个位数月份前面将会自动补零。
ORACLE使用TO_CHAR()
<if test="endTime != null">
,TO_CHAR(#{endTime},'YYYY-MM-DD 23:59:59') as endTime
</if>
TO_CHAR(base_eva_detail.create_time, 'YYYY-MM-DD HH24:MI:SS') as create_time,
系统时间
mysql使用now()
date_format(now(),'%Y-%c-%d')
oracle使用SYSDATE
TO_CHAR(SYSDATE, 'YYYY-MM-DD')
IF()函数
MYSQL
<if test="orgId != null and orgId != ''">
and if(boi.ORGSEQ is not null, boi.ORGSEQ like CONCAT('%',#{orgId},'.%'), boi.ORGID = #{orgId})
</if>
ORALCE
ORALCE没有IF函数
<if test="orgId != null and orgId != ''">
AND (
(boi.ORGSEQ IS NOT NULL AND boi.ORGSEQ LIKE '%' || #{orgId} || '%'
OR
boi.ORGID = #{orgId})
)
</if>
ifnull()/NVL()
mysql使用ifnull()
ifnull(sum(base_eva_question_detail.eva_value),0) as allScore,
ifnull(trim(at.city_name), '') as city_name,
ORALCE使用NVL()
NVL(sum(base_eva_question_detail.eva_value),0) as allScore,
NVL(trim(at.city_name),'') as city_name,
将多行数据合并成一行
mysql使用group_concat()
<foreach collection="headers" item="item" index="index">
<if test="item.evaQuestionType == 1">
,GROUP_CONCAT( CASE eva_question_num WHEN '${item.evaQuestionNum}' THEN base_eva_question_detail.eva_answer END ) '${item.dataKey}'
</if>
<if test="item.evaQuestionType == 6 || item.evaQuestionType == 5">
,GROUP_CONCAT( CASE eva_question_num WHEN '${item.evaQuestionNum}' THEN base_eva_question_detail.eva_answer END )'${item.dataKey}'
</if>
</foreach>
ORACLE使用LISTAGG()
<foreach collection="headers" item="item" index="index">
<if test="item.evaQuestionType == 1">
,LISTAGG(CASE eva_question_num WHEN '${item.evaQuestionNum}' THEN base_eva_question_detail.eva_answer END) '${item.dataKey}'
</if>
<if test="item.evaQuestionType == 6 || item.evaQuestionType == 5">
,LISTAGG(CASE eva_question_num WHEN '${item.evaQuestionNum}' THEN base_eva_question_detail.eva_answer END)'${item.dataKey}'
</if>
</foreach>
分页查询
mysql使用limit
SELECT
*
FROM
sso_access_token
WHERE
`status` = 1
AND user_id = #{userId}
AND user_name = #{userName}
ORDER BY
create_time DESC
LIMIT 0,1
oracle使用ROWNUM
<![CDATA[
SELECT *
FROM (
SELECT *
FROM sso_access_token
WHERE status = 1
AND user_id = #{userId}
AND user_name = #{userName}
ORDER BY create_time DESC
)
WHERE ROWNUM <= 1
]]>
字段名称(设置查询的别名)
mysql的字段名称是不区分大小写的。
换句话说就是:别名的大小写是啥,最终展示的就是啥。
<select id="getEvaluationObjectList" resultType="com.xyhsoft.platform.api.questionnaire.domain.EvaluationObjectDomain">
SELECT beo.id,beo.code,beo.name,qrCode, NVL(sum(btd.score),0) as score
FROM base_evaluation_object beo
</select>
oracle的字段名称是区分大小写的。
换句话说就是:不管你设置的别名是啥,最终展示的都将是大写。
如果要强制展示小写,需要使用双引号将其包裹起来。
<select id="getEvaluationObjectList" resultType="com.xyhsoft.platform.api.questionnaire.domain.EvaluationObjectDomain">
SELECT beo.id AS "id", beo.code AS "code",beo.name AS "name",qrCode AS "qrCode", NVL(sum(btd.score),0) as "score"
FROM base_evaluation_object beo
</select>
查询的别名为何非得使用驼峰或者小写?
因为查询返回的别名需要与Java实体类的属性名称保持一致,才能完成赋值。
如果不设置别名,我们也可以手动指定字段名称与属性名称的映射关系。
<resultMap id="BaseResultMap" type="com.xyhsoft.platform.api.questionnaire.domain.EvaluationObjectDomain">
<result column="ID" jdbcType="BIGINT" property="id"/>
<result column="TEMPLATEID" jdbcType="BIGINT" property="templateId"/>
<result column="NAME" jdbcType="VARCHAR" property="name"/>
<result column="CODE" jdbcType="VARCHAR" property="code"/>
<result column="ORGCODE" jdbcType="VARCHAR" property="orgCode"/>
<result column="QRCODE" jdbcType="VARCHAR" property="qrcode"/>
<result column="ISDEL" jdbcType="BIGINT" property="isDel"/>
<result column="CREATETIME" jdbcType="TIMESTAMP" property="createTime"/>
<result column="UPDATETIME" jdbcType="TIMESTAMP" property="updateTime"/>
</resultMap>
<select id="getEvaluationObjectById" resultMap="BaseResultMap">
SELECT *
FROM base_evaluation_object
where id = #{id}
</select>
主键设置
mysql的表主键一般情况下设置成自增即可。
<insert id="addEvaluationObject" useGeneratedKeys="true" keyProperty="id" parameterType="com.xyhsoft.platform.api.questionnaire.domain.EvaluationObjectDomain">
insert into base_evaluation_object(id,templateId,name,code,orgCode,qrCode)
value (#{id},#{templateId},#{name},#{code},#{orgCode},#{qrCode})
</insert>
主键可以为null,当往表中插入数据时,会自动填充主键。
oracle则需要使用序列。
如果是mysql转oracle,已经将mysql的数据导入到了oracle中,需要遵循以下步骤:
第一步: 确认表的主键,以及当前主键的最大值。
查询表的主键字段
查询表主键当前的最大值
第二步:
创建序列,并将序列的最小值设置为:当前主键值+1;
序列名称,一般定义为:SEQ_表名。
第三步:修改sql。
<insert id="addEvaluationObject" parameterType="com.xyhsoft.platform.api.questionnaire.domain.EvaluationObjectDomain">
insert into base_evaluation_object(id,templateId,name,code,orgCode,qrCode)
value ((SELECT SEQ_BASE_EVALUATION_OBJECT.NEXTVAL FROM DUAL),#{templateId},#{name},#{code},#{orgCode},#{qrCode})
</insert>
写在最后
哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!
相关推荐:
- 个人主页
- mybatis增删改查