3.6数据库初始化
3.6.1定义
应用中,如果需要平台为其自动初始化数据库,可以根据EMAP的规范,配置初始化文件。
初始化配置文件的位置如下:
[应用目录]/src/db/[模块名]/version[X].xml
[应用目录]即应用的工程目录
[模块名]可以自己任意定义,用于区分一个应用中多个模块的数据库初始化配置
[X]为数据库初始化配置的版本号,从1开始,之后的版本按顺序编号,编号必须连续
3.6.2样例
<?xml version="1.0" encoding="GBK"?>
<dbVersion>
<!-- 创建一个表 -->
<table name="T_USER" desc="用户信息表">
<!-- 字符型列 -->
<column name="name" type="String(300)" desc="用户姓名" nullable="false"/>
<!-- 整型列 -->
<column name="age" type="int" desc="年龄" default="10"/>
<!-- 浮点型列 -->
<column name="height" type="double(5,2)" desc="身高(米)"/>
<!-- 日期时间型列,注:没有日期类型 -->
<column name="lastModified" type="Datetime" desc="最后修改时间"/>
</table>
<!-- 创建主键 -->
<index name="PK_T_USER" type="key" tableName="T_USER">
<column name="name"/>
</index>
<!-- 创建索引 -->
<index name="IX_T_USER" tableName="T_USER">
<column name="age"/>
<column name="height"/>
</index>
<!-- 创建唯一键 -->
<index name="UK_T_USER" type="unique" tableName="T_USER">
<column name="lastModified"/>
</index>
<!-- 创建外键 -->
<index name="UK_T_USER" type="foreign" tableName="T_USER" ref="T_CLASS">
<column name="name"/>
<refColumn name="userName"/>
</index>
<!-- 删除主键 -->
<index name="PK_T_USER" type="key" tableName="T_USER" opt="drop">
</index>
<!-- 删除一个表 -->
<table name="T_USER" opt="drop">
</table>
<!-- 修改一个表 -->
<table name="T_USER" opt="modify">
<!-- 添加的列 -->
<column name="newColumn" type="String(10)" desc="新列"/>
<!-- 修改的列 -->
<column name="age" type="long" opt="modify"/>
<!-- 删除的列 -->
<column name="height" type="double(5,2)" opt="drop"/>
<!—修改列名 -->
<column name="oldName" newName="newName" type="String(5)" opt="modify"/>
</table>
<!—设置忽略插入数据时的主键冲突错误 -->
<ignore sameKey="true"/>
<!-- 执行一条语句,任何数据库上都会执行 -->
<script>
insert into T_USER (name) values ('tom')
</script>
<!-- 执行一条语句,指定在哪些数据库上执行 -->
<script dataBase="oracle,mysql">
create function …
</script>
</dbVersion>
3.6.3数据类型
1、String(40),字符串,长度为40
2、int,整数型
3、Datetime,日期时间型
4、Clob,大文本
5、Blob,大数据
6、double(10,2),长度10,小数位2
3.6.4初始化依赖
如果初始化的模块之间存在着依赖关系,则可以在初始化模块的目录下添加dependent.txt文件,在此文件中添加需要依赖的模块列表。如:
app:baseApp1,app:baseApp2,unit:tables2,unit:tables1
“app:”起始的表示需要依赖哪个应用,“unit:”起始的表示需要依赖本应用中哪个模块,多个依赖项之间可以用“,”分隔。
注:如果一个初始化模块中设置了依赖,那此模块下的delay.txt将不会生效。
3.6.5忽略初始化出错
如果数据库初始化出错后,会将应用置为无效。如果在数据库初始化出错后,仍然需要使应用可用,则可在应用的标识文件“EMAP_APP”中添加如下配置:
ds.init.ignoreError=true
如果需要忽略查询时的主键冲突错误,可以通过ignore节点来设置,如:
<ignore sameKey="true"/>
那么在此节点之后的插入语句执行时,如果是主键冲突,那就会忽略此错误,继续执行后面的步骤。
3.6.6问题查看及处理
注:EMAP运行环境1.7.60及之后的版本按此章节处理,之前的版本请参考后面一段旧版本的处理方式。
在EMAP_SYS_VERSION_INFO表中,可以查看到数据库初始化的结果,如下图:
versionName用于标识初始化哪些类别的表
versionValue表示当前更新到哪个版本
setp表示当前执行到第几步
optStatus表示当前步骤的状态,是开始执行(BEGIN)还是已完成(DONE),或者是当前版本处理完成(FINISH)
errorInfo为出错信息,如果这列有信息,表示此类别初始化失败,需要继续查看相关的执行脚本,手动处理
在EMAP_SYS_VERSION_SCRIPT表中,可以查看到初始化出错的脚本,如下图:
versionName和versionValue同前
exeduted表示此脚本是否已执行,0表示未执行
scriptIndex表示脚本的执行顺序,重小到大排列
有了脚本之后,就可以进行手动处理了。
将所有未执行的脚本,手动执行掉。如果有些无法执行的,如表或列已存在则跳过。
然后将EMAP_SYS_VERSION_INFO表中的errInfo列清除,optStatus列改为DONE,如下图:
最后,重启应用,再查看EMAP_SYS_VERSION_INFO表中是否还有出错信息。
3.6.7问题查看及处理(旧)
在EMAP_SYS_VERSION_INFO表中,可以查看到数据库初始化的结果,如下图:
versionName用于标识初始化哪些类别的表
versionValue表示当前更新到哪个版本
errorInfo为出错信息,如果这列有信息,表示此类别初始化失败,需要继续查看相关的执行脚本,手动处理
在EMAP_SYS_VERSION_SCRIPT表中,可以查看到初始化出错的脚本,如下图:
versionName和versionValue同前
exeduted表示此脚本是否已执行,0表示未执行
scriptIndex表示脚本的执行顺序,先按已执行的排列,再按未执行的排列
有了脚本之后,就可以进行手动处理了,可分为两种方式
第一种.将所有未执行的脚本,手动执行掉,然后清除EMAP_SYS_VERSION_INFO表中的出错信息,如下图
第二种.将所有已执行的脚本恢复(如将已建的表删除),然后清除EMAP_SYS_VERSION_INFO表中的出错信息,将版本号减1,如下图
最后,重启系统,再查看EMAP_SYS_VERSION_INFO表中是否还有出错信息。