Javamysql语法转化oracle_MyBatis项目实战 快速将MySQL转换成Oracle语句
一、前言
因项目需求,小编要将项目从mysql迁移到oracle中 ~
现在将完成 基于MyBatis-Plus将项目中的MySQL语句全部转换成Oracle语句
大概实现步骤:
将项目改成支持双库配置(因项目基于mysql数据库已经全部完成,也不想直接替换掉,于是新增oracle库,让整个项目可支持多个数据库,这里不是多数据源哦!)
Oracle中创建常用函数
遍历项目中的xxxMapper.xml文件,找到mysql与oracle语句的区别,然后替换绝大部分SQL
最后将一些特殊的mysql语句手动修改为oracle语句
二、MyBatis-Plus 支持双库配置 【mysql,oracle】
1、application.yml中配置mybatis-plus的database-id
# mybatis-plus配置
mybatis-plus:
configuration:
jdbc-type-for-null: 'null' # 解决oracle更新数据为null时无法转换报错
database-id: oracle # 支持多库配置 mysql,oracle
2、MybatisPlus核心配置文件 -> 根据不同的数据库厂商执行不同的SQL
@Configuration
@MapperScan("com.zhengqing.demo.modules.**.mapper*")
public class MybatisPlusConfig {
/**
* `xxxMapper.xml`文件中的`databaseId`会自动识别使用的数据库类型与这里相对应
* 注: 如果没有指定`databaseId`则该SQL语句适用于所有数据库哦~
*
* databaseIdProvider:支持多数据库厂商
* VendorDatabaseIdProvider: 得到数据库厂商的标识(驱动getDatabaseProductName()),mybatis就能根据数据库厂商标识来执行不同的sql;
* MySQL,Oracle,SQL Server,xxxx
*/
@Bean
public DatabaseIdProvider getDatabaseIdProvider(){
DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
Properties properties = new Properties();
// 为不同的数据库厂商起别名
properties.setProperty("MySQL","mysql");
properties.setProperty("Oracle","oracle");
databaseIdProvider.setProperties(properties);
return databaseIdProvider;
}
}
3、xxxMapper.xml中通过databaseId指定数据库类型
SELECT * FROM 表名 LIMIT 1
SELECT * FROM 表名 WHERE ROWNUM <= 1
三、Oracle中创建常用函数
这里根据个人项目情况去实际应用即可~
1、ORACLE_TO_UNIX
Oracle时间 Date类型转换为Unix时间戳,等同于mysql中的UNIX_TIMESTAMP
create or replace function ORACLE_TO_UNIX(in_date IN DATE) return number is
begin
return( ROUND( (in_date -TO_DATE('19700101','yyyymmdd'))*86400 - TO_NUMBER(SUBSTR(TZ_OFFSET(sessiontimezone),1,3))*3600, 0) );
end ORACLE_TO_UNIX;
2、FIND_IN_SET
CREATE OR REPLACE FUNCTION FIND_IN_SET(piv_str1 varchar2, piv_str2 varchar2, p_sep varchar2 := ',')
RETURN NUMBER IS
l_idx number:=0; -- 用于计算piv_str2中分隔符的位置
str varchar2(500); -- 根据分隔符截取的子字符串
piv_str varchar2(500) := piv_str2; -- 将piv_str2赋值给piv_str
res number:=0; -- 返回结果
loopIndex number:=0;
BEGIN
-- 如果piv_str中没有分割符,直接判断piv_str1和piv_str是否相等,相等 res=1
IF instr(piv_str, p_sep, 1) = 0 THEN
IF piv_str = piv_str1 THEN
res:= 1;
END IF;
ELSE
-- 循环按分隔符截取piv_str
LOOP
l_idx := instr(piv_str,p_sep);
loopIndex:=loopIndex+1;
-- 当piv_str中还有分隔符时
IF l_idx > 0 THEN
-- 截取第一个分隔符前的字段str
str:= substr(piv_str,1,l_idx-1);
-- 判断 str 和piv_str1 是否相等,相等 res=1 并结束循环判断
IF str = piv_str1 THEN
res:= loopIndex;
EXIT;
END IF;
piv_str := substr(piv_str,l_idx+length(p_sep));
ELSE
-- 当截取后的piv_str 中不存在分割符时,判断piv_str和piv_str1是否相等,相等 res=1
IF piv_str = piv_str1 THEN
res:= loopIndex;
END IF;
-- 无论最后是否相等,都跳出循环
EXIT;
END IF;
END LOOP;
-- 结束循环
END IF;
-- 返回res
RETURN res;
END FIND_IN_SET;
四、工具类(MySQL语句转换Oracle语句)
替换步骤:
在 xxxMapper.xml 中将所有sql语句上加入 databaseId="mysql"
复制一份mysql的sql(即 将替换的oracle语句)
在复制的sql上加入databaseId="oracle"
找出mysql与oracle语句区别,然后替换sql
温馨小提示: 这里工具类只供参考,实际操作根据自己的项目做修改哦,操作前建议先备份自己的项目,以防操作不当丢失代码哦!
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import java.io.*;
import java.util.*;
/**
*
mysql迁移oracle 测试工具类
*
* @description :
* @author : zhengqing
* @date : 2020/1/08 10:10
*/
public class MySQLToOracleTest {
private final static String ORACLE_SQL = " ";
@Test // 替换项目中的sql语句
public void testSQL() throws Exception {
String path = System.getProperty("user.dir") + "\\src\\main\\java\\com\\zhengqing\\xxx"; // TODO 这里替换为自己的项目路径
File file = new File(path);
HashMap fileMap = new HashMap<>();
getAllFileByRecursion(fileMap, file);
fileMap.forEach((key, value) -> {
String fileXmlName = (String) key;
File fileXml = (File) value;
String filePath = fileXml.getPath();
if (fileXmlName.equals("Test.xml")) {
System.out.println(filePath);
try {
// 1、加入 databaseId="mysql"
addMysql(filePath);
// 2、复制一份oracle的sql
if (!checkHasOracle(filePath)) {
copyMysqlToOracle(filePath);
}
// 3、加入 databaseId="oracle"
addOracle(filePath);
// 4、替换mybatis `xxxMapper.xml` 中的sql语句
repalceSQL(filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
});
System.out.println(fileMap);
}
/**
* 替换mybatis `xxxMapper.xml` 中的sql语句
*/
private static void repalceSQL(String path) throws IOException {
File file = new File(path);
FileReader in = new FileReader(file);
BufferedReader bufIn = new BufferedReader(in);
// 内存流, 作为临时流
CharArrayWriter tempStream = new CharArrayWriter();
// 替换
String line = null;
int row = 0;
int rowOracle = 0;
while ((line = bufIn.readLine()) != null) {
row++;
if (line.contains(ORACLE_SQL)) {
rowOracle = row;
}
if (rowOracle != 0 && row > rowOracle) {
// ① 替换 `LIMIT` -> `AND ROWNUM <= 1` TODO 【注: 部分包含`ORDER BY` 关键字,需单独处理】
if (line.contains("limit") || line.contains("LIMIT")) {
System.out.println();
System.out.println(" ==============================↓↓↓↓↓↓ copy分页所需 (" + row + ") ↓↓↓↓↓↓===================================== ");
System.out.println("SELECT * FROM ( SELECT TMP.*, ROWNUM ROW_ID FROM (");
System.out.println();
System.out.println(") TMP WHERE ROWNUM <=1) WHERE ROW_ID > 0");
System.out.println();
}
line = StringUtils.replace(line, "limit 1", "AND ROWNUM <= 1");
line = StringUtils.replace(line, "LIMIT 1", "AND ROWNUM <= 1");
line = StringUtils.replace(line, "limit 0,1", "AND ROWNUM <= 1");
line = StringUtils.replace(line, "LIMIT 0,1", "AND ROWNUM <= 1");
// ② oracle中不能使用“ ` ”符号
line = StringUtils.replace(line, "`", "");
// ③ CONCAT('%', #{name}, '%') -> '%'||#{name}||'%' (Oracle中concat函数只能放两个参数)
if (line.contains("concat")) {
// String newLine = line.substring(line.indexOf("concat(") + 7, line.lastIndexOf("'%')") + 3);
line = line.replaceAll(",", " || ");
line = line.replaceAll("concat", "");
}
if (line.contains("CONCAT")) {
// String newLine = line.substring(line.indexOf("CONCAT(") + 7, line.lastIndexOf("'%')") + 3);
line = line.replaceAll(",", " || ");
line = line.replaceAll("CONCAT", "");
}
// ④ `UNIX_TIMESTAMP` -> `ORACLE_TO_UNIX` date类型时间转10位时间戳
line = line.replaceAll("UNIX_TIMESTAMP", "ORACLE_TO_UNIX");
// ⑤ 部分关键字需加上双引号 TODO 【注: 字段名大写,映射的别名需保存原本小写!】 `level -> "LEVEL"` `user -> "USER"` `number -> "NUMBER"` `desc -> "DESC"`
List keywordList = new ArrayList<>(Arrays.asList("level", "user", "number"));
if (!line.contains("test=")) {
for (String e : keywordList) {
// StringUtils.swapCase(e) : 大小写互换
line = line.replaceAll(" " + e + " ", " \"" + StringUtils.swapCase(e) + "\" ");
line = line.replaceAll("." + e + " ", "\\.\"" + StringUtils.swapCase(e) + "\" ");
if (line.endsWith(e) || line.endsWith(e + ",")) {
line = line.replaceAll(e, "\"" + StringUtils.swapCase(e) + "\"");
}
}
}
if (line.endsWith(" date") || line.endsWith(" date,") || line.endsWith(" 'date'") || line.endsWith(" 'DATE'") || line.endsWith("DATE")) {
line = line.replaceAll(" date", " \"date\"");
line = line.replaceAll(" date,", " \"date,\"");
line = line.replaceAll(" 'date'", " \"date\"");
line = line.replaceAll(" 'DATE'", " \"date\"");
line = line.replaceAll(" DATE", " \"date\"");
}
line = line.replaceAll(" date ", " \"date\" ");
line = line.replaceAll(" DATE ", " \"date\" ");
// ⑥ `IFNULL` -> `NVL`
line = line.replaceAll("IFNULL", "NVL");
line = line.replaceAll("ifnull", "NVL");
// ⑦ 时间 `str_to_date` -> `to_date` `date_format` -> `to_char`
// `%Y-%m-%d` -> `yyyy-MM-dd` `%Y-%m` -> `yyyy-MM`
line = line.replaceAll("str_to_date", "TO_DATE");
line = line.replaceAll("STR_TO_DATE", "TO_DATE");
line = line.replaceAll("date_format", "TO_CHAR");
line = line.replaceAll("DATE_FORMAT", "TO_CHAR");
// 这里注意替换顺序问题,最长的应该放最前面!!!
line = line.replaceAll("%Y-%m-%d %H:%i:%S", "yyyy-MM-dd HH24:mi:ss");
line = line.replaceAll("%Y-%m-%d %H:%i:%s", "yyyy-MM-dd HH24:mi:ss");
line = line.replaceAll("%Y-%m-%d %H:%i", "yyyy-MM-dd HH24:mi");
line = line.replaceAll("%Y-%m-%d %H", "yyyy-MM-dd HH24");
line = line.replaceAll("%Y-%m-%d %h", "yyyy-MM-dd HH");
line = line.replaceAll("%Y-%m-%d", "yyyy-MM-dd");
line = line.replaceAll("%Y-%m", "yyyy-MM");
line = line.replaceAll("%Y", "yyyy");
line = line.replaceAll("%H", "HH24");
line = line.replaceAll("%k", "HH24");
line = line.replaceAll("now\\(\\)", "(SELECT SYSDATE + 8/24 FROM DUAL)");
line = line.replaceAll("NOW\\(\\)", "(SELECT SYSDATE + 8/24 FROM DUAL)");
// ⑧ ...
// 需手动处理的SQL 【 group by | 批量插入 | ... 】
}
// 将该行写入内存
tempStream.write(line);
// 添加换行符
tempStream.append(System.getProperty("line.separator"));
}
// 关闭 输入流
bufIn.close();
// 将内存中的流 写入 文件
FileWriter out = new FileWriter(file);
tempStream.writeTo(out);
out.close();
}
/**
* 加入 databaseId="mysql"
*/
private static void addMysql(String path) throws IOException {
File file = new File(path);
FileReader in = new FileReader(file);
BufferedReader bufIn = new BufferedReader(in);
// 内存流, 作为临时流
CharArrayWriter tempStream = new CharArrayWriter();
// 替换
String line = null;
while ((line = bufIn.readLine()) != null) {
if ((line.contains("
if (line.endsWith(">")) {
line = line.replaceAll(">", " databaseId=\"mysql\">");
} else {
line = line + " databaseId=\"mysql\"";
}
}
// 将该行写入内存
tempStream.write(line);
// 添加换行符
tempStream.append(System.getProperty("line.separator"));
}
// 关闭 输入流
bufIn.close();
// 将内存中的流 写入 文件
FileWriter out = new FileWriter(file);
tempStream.writeTo(out);
out.close();
}
/**
* 加入 databaseId="oracle"
*/
private static void addOracle(String path) throws IOException {
File file = new File(path);
FileReader in = new FileReader(file);
BufferedReader bufIn = new BufferedReader(in);
// 内存流, 作为临时流
CharArrayWriter tempStream = new CharArrayWriter();
HashSet lineSet = new HashSet<>();
// 替换
String line = null;
while ((line = bufIn.readLine()) != null) {
if (line.contains("databaseId=\"mysql\"")) {
if (lineSet.contains(line)) {
line = line.replaceAll("databaseId=\"mysql\"", "databaseId=\"oracle\"");
}
lineSet.add(line);
}
// 将该行写入内存
tempStream.write(line);
// 添加换行符
tempStream.append(System.getProperty("line.separator"));
}
// 关闭 输入流
bufIn.close();
// 将内存中的流 写入 文件
FileWriter out = new FileWriter(file);
tempStream.writeTo(out);
out.close();
}
/**
* 复制一份oracle的sql
*/
private static void copyMysqlToOracle(String path) throws IOException {
File file = new File(path);
FileReader in = new FileReader(file);
BufferedReader bufIn = new BufferedReader(in);
// 内存流, 作为临时流
CharArrayWriter tempStream = new CharArrayWriter();
// 替换
String line = null;
// 需要替换的行
List lineList = new LinkedList<>();
int row = 0;
int firstRow = 0;
while ((line = bufIn.readLine()) != null) {
row++;
if (line.contains("
firstRow = row;
}
// 添加替换内容
if (firstRow != 0 && row >= firstRow && !line.contains("")) {
lineList.add(line);
}
// 查询结束位置
if (line.contains("")) {
tempStream.append(System.getProperty("line.separator"));
tempStream.write(ORACLE_SQL);
tempStream.append(System.getProperty("line.separator"));
tempStream.append(System.getProperty("line.separator"));
lineList.forEach(lineValue -> {
// copy mysql 语句 转为oracle
try {
tempStream.write(lineValue);
tempStream.append(System.getProperty("line.separator"));
} catch (IOException e) {
e.printStackTrace();
}
});
tempStream.append(System.getProperty("line.separator"));
}
// 将该行写入内存
tempStream.write(line);
// 添加换行符
tempStream.append(System.getProperty("line.separator"));
}
// 关闭 输入流
bufIn.close();
// 将内存中的流 写入 文件
FileWriter out = new FileWriter(file);
tempStream.writeTo(out);
out.close();
}
/**
* 检查是否已经复制SQL
*/
private static boolean checkHasOracle(String path) throws IOException {
File file = new File(path);
FileReader in = new FileReader(file);
BufferedReader bufIn = new BufferedReader(in);
// 内存流, 作为临时流
CharArrayWriter tempStream = new CharArrayWriter();
// 替换
String line = null;
boolean result = false;
while ((line = bufIn.readLine()) != null) {
if (line.contains(ORACLE_SQL)) {
result = true;
}
// 将该行写入内存
tempStream.write(line);
// 添加换行符
tempStream.append(System.getProperty("line.separator"));
}
// 关闭 输入流
bufIn.close();
// 将内存中的流 写入 文件
FileWriter out = new FileWriter(file);
tempStream.writeTo(out);
out.close();
return result;
}
/**
* 递归文件夹 -> 找到所有xml文件
*/
private static void getAllFileByRecursion(HashMap fileMap, File file) {
File[] fs = file.listFiles();
for (File f : fs) {
String fileName = f.getName();
if (f.isDirectory()) {
// 若是目录则递归,否则打印该目录下的文件
getAllFileByRecursion(fileMap, f);
}
if (f.isFile() && fileName.endsWith(".xml")) {
fileMap.put(fileName, f);
}
}
}
}
五、总结
这里简单说下MySQL和Oracle中的SQL区别,以及mysql语句转换oracle语句示例
1、分页
mysql: LIMIT 0,1
oracle: ROWNUM <= 1
情景①:mysql中不含ORDER BY
-- mysql
SELECT * FROM 表名 LIMIT 1
-- oracle
SELECT * FROM 表名 WHERE ROWNUM <= 1
情景②:mysql中含ORDER BY
-- mysql
SELECT * FROM 表名 ORDER BY 字段名 DESC LIMIT 1
-- oracle
SELECT * FROM (
SELECT TMP.*, ROWNUM ROW_ID FROM (
SELECT * FROM 表名 ORDER BY 字段名 DESC
) TMP WHERE ROWNUM <= 1 )
WHERE ROW_ID > 0;
温馨小知识:SQL SELECT语句执行顺序
FROM子句组装来自不同数据源的数据
WHERE子句基于指定的条件对记录进行筛选
GROUP BY子句将数据划分为多个分组
聚集函数进行计算
HAVING子句筛选分组
计算所有表达式
ORDER BY对结果进行排序
2、oracle中字段名不能使用符号 " ` " 包括
-- mysql
SELECT `字段名` FROM 表名
-- oracle
SELECT 字段名 FROM 表名
3、字符串拼接
注: Oracle中CONCAT函数只能放两个参数,因此改为 || 拼接
mysql: CONCAT('%', 'xxx' , '%')
oracle: '%' || 'xxx' || '%'
-- mysql
SELECT 字段名 FROM 表名 WHERE 字段名 LIKE CONCAT('%','helloworld','%')
-- oracle
SELECT 字段名 FROM 表名 WHERE 字段名 LIKE ('%' || 'helloworld' || '%')
4、date类型时间转10位时间戳
mysql: UNIX_TIMESTAMP
oracle: ORACLE_TO_UNIX (注:此函数为步骤三中手动创建的,并非oracle自带哦!)
5、字段名为Oracle关键字需加上双引号
温馨小提示: 字段名需大写,如果Java实体类对应字段为小写,映射的别名注意需保持原本小写与之对应 ~
例如:
level -> "LEVEL"
user -> "USER"
number -> "NUMBER"
desc -> "DESC"
date -> DATE
6、判断是否为 NULL: 如果x为NULL,则返回value,否则返回x值本身
mysql: IFNULL(x, value)
oracle: NVL(x, value)
7、日期时间互换
前mysql,后oracle
字符串类型转时间类型: STR_TO_DATE -> TO_DATE
时间类型转指定字符串类型: DATE_FORMAT -> TO_CHAR
获取系统当前时间: NOW() -> SELECT SYSDATE FROM DUAL
-- 时间类型转指定字符串类型
SELECT DATE_FORMAT( NOW(),'%Y-%m-%d %H:%i:%s'); -- mysql
SELECT TO_CHAR( SYSDATE,'yyyy-MM-dd HH24:mi:ss') FROM DUAL; -- oracle
-- 字符串类型转时间类型
SELECT STR_TO_DATE( NOW(), '%Y-%m-%d %H'); -- mysql
SELECT TO_DATE( '2020-01-09', 'yyyy-MM-dd') FROM DUAL; -- oracle 【 注:oracle中前者字符串时间的格式需与后者转换格式相同哦~ 】
-- 获取系统当前时间
SELECT NOW(); -- mysql
SELECT SYSDATE + 8/24 FROM DUAL; -- oralce 【注:如果服务器时间没有相差8小时则无需加上`8/24`】
-- mysql
SELECT YEAR( NOW() ); -- 求年份
SELECT QUARTER( NOW() ); -- 求季度
SELECT MONTH( NOW() ); -- 求月份
-- oracle
SELECT TO_CHAR(SYSDATE, 'Q') FROM DUAL; -- 求季度
另外这里给出小编所用到的时间标识符格式
-- 前:mysql 后:oracle
"%Y-%m-%d %H:%i:%S" "yyyy-MM-dd HH24:mi:ss"
"%Y-%m-%d %H:%i:%s" "yyyy-MM-dd HH24:mi:ss"
"%Y-%m-%d %H:%i" "yyyy-MM-dd HH24:mi"
"%Y-%m-%d %H" "yyyy-MM-dd HH24"
"%Y-%m-%d %h" "yyyy-MM-dd HH"
"%Y-%m-%d" "yyyy-MM-dd"
"%Y-%m" "yyyy-MM"
"%Y" "yyyy"
"%H" "HH24"
"%k" "HH24"
8、判断时 左 右 字段类型必须相同
这里注意是必须,可能在oracle版本不同的情况下,老版本不同类型也会查询出来,但建议还是改为相同类型关联,避免以后数据库版本升级出现问题!!!
建议小转大,比如:数字转字符串;并使用CONCAT去修改类型,因为mysql和oracle都支持此函数,并且不会在特殊类型上出现问题 ~
-- ex: `JOIN` 关联表时 两张表的关联`字段类型`必须`相同`
SELECT a.*,b.*
FROM 表1 a
LEFT JOIN 表2 b on a.字符串类型字段 = CONCAT(b.数字类型字段, '')
9、批量插入
-- mysql
INSERT INTO 表名( `字段名1`, `字段名2`, `字段...`) VALUES
#{item.字段1},#{item.字段2},#{item中的每一个字段名...}
-- oracle
INSERT INTO 表名(字段名1,字段名2,xxx...)
SELECT A.*
FROM(
SELECT
#{item.字段1},#{item.字段2},#{item中的每一个字段名...}
FROM DUAL
) A
10、分组 GROUP BY
oracle中GROUP BY分组后,查询出来的所有字段(除分组字段)必须为聚合函数的字段,否则会报错!
解决:
查询字段改为聚合函数
使用如下分析函数 OVER (Partition BY ...) 及开窗函数
-- mysql
SELECT 字段名,xxx... FROM 表名 GROUP BY 分组字段
-- oracle
SELECT
*
FROM (
SELECT tb.*, ROW_NUMBER ( ) OVER ( PARTITION BY tb.分组字段 ORDER BY tb.排序字段 DESC ) AS result
FROM (
SELECT 字段名,xxx... FROM 表名 -- 此处为查询sql,去掉`GROUP BY`分组条件,将分组字段加到上面 【 注:此sql的查询字段中要么全是聚合函数字段,要么都不是! 】
) tb
) WHERE result = 1
11、Oracle中表的别名不能用AS, 列的别名可以用AS
why ?:为了防止和Oracle存储过程中的关键字AS冲突的问题
12、注意Oracle对数据类型要求很严!!!
MySQL与Oracle不同之处远不止小编提及的如上几点,更多的还需要大家根据在实际项目中做对比,然后去修改哦 ~
六、本文MySQL转Oracle语句工具源码
温馨小提示:如果后期小编空闲会将上文中提供的测试替换工具类再加以修改,到时候会存放在如下github仓库中...
springBoot 整合 mybatis 项目实战
二.springBoot 整合 mybatis 项目实战 前言 上一篇文章开始了我们的springboot序篇,我们配置了mysql数据库,但是我们sql语句直接写在controller中并且使用 ...
使用navicat将mysql转换成sqlserver
使用navicat将mysql转换成sqlserver 1. 打开navicat,连接所需要装换的mysql数据库. 2. 选择所需要转换的数据源,点击右键选择数据传输.如图: 3. 打开数据传输面板 ...
将json文件转换成insert语句的sql文件
引入是要的maven依赖:
excel转换成oracle建表脚本
package excel2sql; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundE ...
【springmvc+mybatis项目实战】杰信商贸-7.生产厂家新增
我们要实现新的功能,就是生产厂家的新增先来回顾一下系统架构图我们数据库这边已经建好表了,接下来要做的就是mapper映射 编辑FactoryMapper.xml文件,加入“添加”的逻辑配置代码块 &l ...
【springmvc+mybatis项目实战】杰信商贸-5.生产厂家DAO+SERVICE+CONTROLLER+JSP+配置文件
上一篇我们创建了工程和一个Factory的po对象(javaBean),我们也写好了Mapper的映射文件,接下来我们来完成生产厂家的DAO与SERVICE,以及CONTROLLER,还有做显示的JS ...
【springmvc+mybatis项目实战】杰信商贸-1.项目背景
1.项目背景杰信项目物流行业的项目,杰信商贸是国际物流行业一家专门从事进出口玻璃器皿贸易的公司.公司总部位于十一个朝代的帝王之都西安,业务遍及欧美.随着公司不断发展壮大,旧的信息系统已无法满足公司的快 ...
二、springBoot 整合 mybatis 项目实战
前言 上一篇文章开始了我们的springboot序篇,我们配置了mysql数据库,但是我们sql语句直接写在controller中并且使用的是jdbcTemplate.项目中肯定不会这样使用,上篇文章 ...
【springmvc+mybatis项目实战】杰信商贸-2.数据库配置
首先我们来了解项目的架构 我们分别使用了MySql和Oracle数据库,即是异构数据库.我们做到一个平台支持多个数据库.数据库建模我们使用Sybase公司的PowerDesigner(以后简称PD), ...
随机推荐
测试MailUtils,作用是发邮件
package cn.itcast.test; import java.io.IOException; import javax.mail.MessagingException; import jav ...
Java Web解决解析乱码和响应乱码
package cn.edu.aynu.rjxy.servlet; import java.io.IOException; import java.io.PrintWriter; import jav ...
web开发技术-过滤器
纪录自己的学习过程,帮助记忆 1.简介 过滤器是服务器端的一个组件,可以接收用户端的请求和响应信息,并且对这些信息进行过滤 过滤器不处理结果,只做一些辅助性操作 2.过滤器的工作原理 3.过滤器的生命 ...
(七)HTTP协议
HTTP协议报文基本格式 HTTP协议报文基本格式 HTTP协议(Hypertext Transfer Protocol――超文本传输协议),浏览器端(客户端)向WEB服务器端访问页面的过 ...
Logdump使用指引
Logdump使用指引 Logdump使用指引在GGSCI中使用如下命令查看当前处理的队列文件和RBA号,例如:GGSCI (br-jl-accs-db1) 3> info REPYXAREPL ...
iOS远程推送之友盟Push
更新记录: 1.2015年10月23日上午10:10分更新,优化了该类,去除了不必要的方法. ----------------------------------------------------- ...
python 练习 1
from math import sqrt from datetime import date def k1(): #某人是1999年9月29日生日 #问到2006年9月29日他活了多少天 a=dat ...
Eclipse-----jrebel实现jetty热部署
步骤1:下载jrebel将文件解压缩到任意文件夹 步骤2:配置jetty watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaGVrZXdhbmd6aQ==/f ...
Dynamics CRM2011中通过JS脚本方式显示和隐藏ribbon中的自定义按钮
首先该方法不能写在页面的onload中,因为当从子网格返回常规表单的时候ribbon区域会重新加载而常规表单所在的iframe区域是不会被刷新的,所以如果写在onload中的话就控制的不那么完全了,我 ...
CyclicBarrier的用法
CyclicBarrier是一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point).在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待, ...
Javamysql语法转化oracle_MyBatis项目实战 快速将MySQL转换成Oracle语句相关推荐
- MyBatis快速将MySQL转换成Oracle语句
1.分页 mysql: LIMIT 0,1 oracle: ROWNUM <= 1 情景①:mysql中不含ORDER BY -- mysql SELECT * FROM 表名 LIMIT 1- ...
- 基于C++的OpenCV项目实战——文档照片转换成扫描文件
基于C++的OpenCV项目实战--文档照片转换成扫描文件 一.背景 前段时间都是基于Python的OpecCV进行一些学习和实践,但小的知识点并没有应用到实际的项目中:并且基于Python的版本的移 ...
- 在线快速将pdf转换成word
在线快速将pdf转换成word 处理同样1000个PDF文件的格式转换,在线PDF转换成Word转换器比普通PDF转换器快8-12倍以上,是一款全自动化的转换模式,为用户提供了高质量的PDF转换服务的 ...
- 一分钟快速将ogg转换成MP3格式
很多人对于ogg的这种格式认知还停留在很久之前,这种格式刚出来的时候也是非常受人追捧的,但是随着MP3格式的出现,它就慢慢的淡出了人们的视线,即使这样大家在下载东西的时候有可能还会遇到这种格式,如果我 ...
- 如何快速将pdf转换成cad呢?
我们在工作中会遇到各种文件格式,最常见的就是pdf文件格式.但有不少小伙伴不喜欢用pdf文件,认为内容不容易修改.那么当我们工作中不得不把PDF转换成其他文件格式的时候,我们应该怎么做呢?下面就由小编 ...
- 怎么快速把音乐转换成mp3格式
喜欢听歌的用户肯定少不了平时下载歌曲,有些用户现在可能觉得歌曲的格式不是那么的重要,但是如果你们想要出门的时候在手机播放或者开车的时候想要在车内播放歌曲,那么这个时候你们就会知道格式的重要性了,像这种 ...
- 怎样快速将pdf转换成word转换器在线
怎样快速将pdf转换成word转换器在线 闲暇时候上网下载资料,发现绝大多数的文章都是以PDF格式发布的,使用复制粘贴的方法虽然可以将文字.图片等信息转移到Word文档中,但原PDF文档中的格式.编排 ...
- 电脑上快速将PDF转换成TXT的教程
电脑上的PDF转TXT 的问题,很多小伙伴都选择了用手打字来进行实现,但是这种方法费时费力,并不是十 分适合在日常工作中的使用,那么下面小编就通过借助迅捷OCR文字识别软件,来为大家分享一个电脑上将P ...
- Javamysql语法转化oracle_数据库移植之oracle To mysql(java)
一年没写博客了,准备记录一下. 1.java 实体的移植 主键生成策略有JPA 提供与Hibernate 提供之分 JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO. ...
最新文章
- Java位运算在程序设计中的使用:位掩码(BitMask)
- JavaScript_原型和继承(2017-03-15)
- Windows VS c++复制文件到网络共享文件夹的实现
- pytorch创建dataloader和可视化图片
- OpenResity + nginx + mysq配置
- Maven默认的生命周期
- modbus调试工具的使用
- 中国银行 网银 控件造成 IE8 崩溃的解决办法
- 参数检验和非参数检验(结合SPSS分析)
- 简易计算器app的制作
- latex 琐粹记录
- mac外接显示器wifi无法正常使用的问题
- 现在玩cf的计算机配置要求,穿越火线电脑配置要求-玩CF所需的电脑配置
- 数据库SQL Server 如何将数据库表名等前缀转换成dbo
- Handler原理(自己实现Handler)
- MarkDown高阶语法手册
- 史上最全的Android文章精选合集
- Ubuntu 16.04卸载LibreOffice等不常用软件
- 精美底部营销通用型插件(客服+电话+微信)按钮
- list与tuple
热门文章
- matlab2c使用c++实现matlab函数系列教程-range函数
- ---M文件-函数式M文件/脚本式、m文件基本构成
- -函数-MATLAB提供的函数/主子函数/匿名-嵌套函数
- 量子计算机时空穿越,科学家用量子计算机模拟时间机器 人类能否回到过去?...
- AtCoder Grand Contest 010 D - Decrementing
- 结对项目:黄金点游戏(何珠赵艳)
- PHP程序员进阶学习书籍参考指南
- [转] Java内部类详解
- 一个开发周期为6个月的中小型软件开发项目成本预算大致表,不足之处请指点...
- [转载] python+selenium定时爬取丁香园的新冠病毒每天的数据,并制作出类似的地图(部署到云服务器)