Appearance
informat.jdbc 数据库操作
概述
使用informat.jdbc对象进行数据库相关操作
INFO
- 连接MYSQL、SQLSERVER、DB2、Oracle等数据库,需要下载对应的jdbc驱动。
- 目录:{织信安装目录}/instance/informat-biz/libs
createConnection
创建数据库连接
javascript
informat.jdbc.createConnection(connection)TIP
- 连接创建不成功会抛出异常
- 设置了
autoCommit等于true时,在执行update、insert、delete语句时将会自动提交事务 - 执行过程中出错会自动回滚
- 在脚本执行结束后,创建的连接会自动关闭
| 参数 | 类型 | 描述 |
|---|---|---|
| connection | ConnectionInfo | 数据库连接信息 |
返回值
返回数据库连接对象Connection,使用此对象可进行数据库的添查删改操作
示例
javascript
const connection = informat.jdbc.createConnection({
dburl: 'jdbc:oracle:thin:@host/XE',
dbuser: 'user',
dbpassword: 'pass',
driverClassName: 'oracle.jdbc.driver.OracleDriver',
autoCommit: false
})
connection.select('select * form table', (row) => {
console.log(row.getString(1))
})Connection
select
执行查询,如果查询失败会抛出异常
javascript
connection.select(sql, handler, ...args)| 参数 | 类型 | 描述 |
|---|---|---|
| sql | String | 查询的SQL |
| handler(ResultSet) | Function | 查询结果回调函数 |
| args | ...Object | 查询的参数 |
示例1
javascript
//查询 user 表中name等于tom的数据
connection.select('select * from user where name=?', (rs) => {
console.log(rs.getString('name'))
}, 'tom')示例2 使用like
javascript
//查询 user 表中name包含tom的数据
connection.select('select * from user where name like concat(' % ',?,' % ')', (rs) => {
console.log(rs.getString('name'))
}, 'tom')示例3 使用in
javascript
//查询 user 表中name是tom或jerry的数据
connection.select('select name from user where name in(?,?)', (rs) => {
console.log(rs.getString('name'))
}, 'tom', 'jerry')insert
执行插入,如果插入失败会抛出异常
javascript
connection.insert(sql, returnAutoGeneratedKeys, ...args)| 参数 | 类型 | 描述 |
|---|---|---|
| sql | String | 查询的SQL |
| returnAutoGeneratedKeys | Boolean | 是否返回自增的主键ID |
| args | ...Object | 插入的参数 |
返回值
类型为Integer
如果设置了returnAutoGeneratedKeys为true,并且执行的操作为insert则返回最后插入数据的自增ID
示例
javascript
connection.insert('insert into user(name,age) values (?, ?)', true, 'tom', 10)update
执行更新或者删除, 如果更新或者删除失败会抛出异常
javascript
connection.update(sql, ...args)| 参数 | 类型 | 描述 |
|---|---|---|
| sql | String | 查询的SQL |
| args | ...Object | 更新的参数 |
返回值 类型为Integer
返回更新或删除成功的记录条数
示例
javascript
connection.update('update user set age=?', 10)javascript
connection.update('delete from user where age=?', 10)commit
提交事务,如果提交事务失败会抛出异常
javascript
connection.commit()rollback
回滚事务,如果回滚事务失败会抛出异常
javascript
connection.rollback()callProcedure
执行存储过程,适用于只有IN参数的场景
javascript
connection.callProcedure(sql, ...args)| 参数 | 类型 | 描述 |
|---|---|---|
| sql | String | 存储过程调用语句 |
| args | ...Object | IN参数(按顺序传入,支持null) |
TIP
callProcedure只支持IN参数,不返回OUT参数值- 适用于只执行操作不需要获取返回值的场景
- 如果需要获取OUT/INOUT参数的返回值,请使用
callProcedureFull
示例1 - 无参数存储过程
javascript
var conn = informat.jdbc.systemConnection();
// 调用无参数的存储过程
conn.callProcedure('CALL update_all_status()');示例2 - 带IN参数的存储过程
javascript
var conn = informat.jdbc.systemConnection();
// 调用带参数的存储过程,按顺序传入参数
conn.callProcedure('CALL insert_user(?, ?, ?)', 'tom', 25, 'developer');示例3 - PostgreSQL类型转换
javascript
var conn = informat.jdbc.systemConnection();
// PostgreSQL需要显式类型转换
conn.callProcedure('CALL update_user_status(?, CAST(? AS INTEGER))', 'u001', 1);callProcedureFull
执行存储过程,支持IN、OUT、INOUT参数以及结果集处理
javascript
connection.callProcedureFull(sql, params, handler)| 参数 | 类型 | 描述 |
|---|---|---|
| sql | String | 存储过程调用语句 |
| params | List<ProcParam> | 参数数组(支持IN/OUT/INOUT) |
| handler(ResultSet) | Function | 结果集回调函数(必填,处理返回的结果集数据) |
注意
- handler参数是必填的,用于处理存储过程返回的结果集
- 如果存储过程不返回结果集,handler函数体可以为null,但参数必须提供
- OUT/INOUT参数的返回值通过方法返回的Object对象获取,结果集数据通过handler处理
参数对象结构
javascript
// IN参数
{
value: '参数值', // 参数值
sqlType: 4, // SQL类型(PostgreSQL当参数值为数值时必填,否则需要在sql中进行显式类型转换)
isOut: false // 标记为IN参数
}
// OUT参数(仅MySQL、Oracle等支持,PostgreSQL不支持纯OUT)
{
name: '参数名', // 用于返回值的键名(非必填)
sqlType: 4, // SQL类型(必填,见下方类型表)
isOut: true, // 标记为OUT参数
isOutOnly: true // true=纯OUT
}
// INOUT参数
{
name: '参数名', // 用于返回值的键名(非必填)
value: 初始值, // 输入值(可以是null)
sqlType: 4, // SQL类型(必填)
isOut: true, // 标记为INOUT
isOutOnly: false // false=INOUT
}SQL类型常量表
| 数据库类型 | sqlType值 | 说明 |
|---|---|---|
| BIT | -7 | 位类型 |
| TINYINT | -6 | 微整数(8位) |
| SMALLINT | 5 | 短整数(16位) |
| INTEGER | 4 | 整数(32位) |
| BIGINT | -5 | 长整数(64位) |
| FLOAT | 6 | 浮点数 |
| REAL | 7 | 单精度浮点数 |
| DOUBLE | 8 | 双精度浮点数 |
| NUMERIC | 2 | 精确数值 |
| DECIMAL | 3 | 十进制数 |
| CHAR | 1 | 定长字符串 |
| VARCHAR | 12 | 变长字符串 |
| LONGVARCHAR | -1 | 长文本 |
| NCHAR | -15 | Unicode定长字符串 |
| NVARCHAR | -9 | Unicode变长字符串 |
| LONGNVARCHAR | -16 | Unicode长文本 |
| DATE | 91 | 日期 |
| TIME | 92 | 时间 |
| TIMESTAMP | 93 | 时间戳 |
| TIME_WITH_TIMEZONE | 2013 | 带时区的时间 |
| TIMESTAMP_WITH_TIMEZONE | 2014 | 带时区的时间戳 |
| BINARY | -2 | 定长二进制数据 |
| VARBINARY | -3 | 变长二进制数据 |
| LONGVARBINARY | -4 | 长二进制数据 |
| BLOB | 2004 | 二进制大对象 |
| CLOB | 2005 | 字符大对象 |
| NCLOB | 2011 | Unicode字符大对象 |
| BOOLEAN | 16 | 布尔值 |
| ROWID | -8 | 行标识符 |
| NULL | 0 | SQL NULL值 |
| OTHER | 1111 | 其他类型(PostgreSQL游标可用此类型) |
| JAVA_OBJECT | 2000 | Java对象 |
| DISTINCT | 2001 | 用户自定义类型 |
| STRUCT | 2002 | SQL结构类型 |
| ARRAY | 2003 | SQL数组类型 |
| REF | 2006 | SQL引用类型 |
| DATALINK | 70 | 数据链接类型 |
| REF_CURSOR | 2012 | Oracle游标类型 |
| SQLXML | 2009 | XML类型 |
常用类型速查
数值类型:
- 整数:
TINYINT(-6)SMALLINT(5)INTEGER(4)BIGINT(-5) - 小数:
FLOAT(6)DOUBLE(8)NUMERIC(2)DECIMAL(3)
字符类型:
- 普通字符:
CHAR(1)VARCHAR(12)LONGVARCHAR(-1) - Unicode字符:
NCHAR(-15)NVARCHAR(-9)LONGNVARCHAR(-16)
日期时间:
DATE(91)TIME(92)TIMESTAMP(93)
二进制:
BINARY(-2)VARBINARY(-3)BLOB(2004)
特殊类型:
BOOLEAN(16)OTHER(1111)REF_CURSOR(2012)
返回值
类型为Object,包含所有OUT/INOUT参数的键值对:
- 如果设置了
name,使用name作为键 - 否则使用
out1、out2等作为键
handler回调函数
javascript
function(resultSet) {
// resultSet 是 ResultSet 对象
// 可以使用 getString、getInt 等方法获取数据
}示例1 - MySQL: 基本INOUT参数
javascript
var conn = informat.jdbc.createConnection({
dburl: 'jdbc:mysql://localhost:3306/mydb',
dbuser: 'root',
dbpassword: 'password',
driverClassName: 'com.mysql.cj.jdbc.Driver'
});
var params = [
{ value: 1, isOut: false }, // IN参数:状态
{
name: 'count',
value: null,
sqlType: 4, // INTEGER
isOut: true,
isOutOnly: false // INOUT参数
}
];
var result = conn.callProcedureFull(
'CALL count_users_by_status(?, ?)',
params,
function(rs) {
// 如果存储过程不返回结果集,函数体可以为空
}
);
console.log('用户数量:', result.count);示例2 - PostgreSQL: 多个INOUT参数
javascript
var conn = informat.jdbc.systemConnection();
var params = [
{ value: 'u001', isOut: false }, // IN参数:用户ID
{ value: 50, isOut: false }, // IN参数:增加积分数
{
name: 'totalPoints',
value: null,
sqlType: 4, // INTEGER
isOut: true,
isOutOnly: false
},
{
name: 'message',
value: null,
sqlType: 12, // VARCHAR
isOut: true,
isOutOnly: false
}
];
var result = conn.callProcedureFull(
'CALL update_user_points(?, CAST(? AS INTEGER), ?, ?)', // 第二个IN参数未设置sqlType,此处需要显式类型转换
params,
null // 没有结果集需要处理时,可以置空
);
console.log('更新后的总积分:', result.totalPoints);
console.log('返回消息:', result.message);示例3 - 创建用户并获取返回值
javascript
var conn = informat.jdbc.systemConnection();
// 生成唯一ID
var recordId = informat.jdbc.nextRecordId();
var params = [
{ value: recordId, isOut: false },
{ value: 'zhangsan', isOut: false },
{ value: 'zhang@test.com', isOut: false },
{ value: 25, sqlType: 4, isOut: false },
{
name: 'userId',
value: null,
sqlType: 12, // VARCHAR
isOut: true,
isOutOnly: false
},
{
name: 'points',
value: null,
sqlType: 4, // INTEGER
isOut: true,
isOutOnly: false
},
{
name: 'message',
value: null,
sqlType: 12, // VARCHAR
isOut: true,
isOutOnly: false
}
];
var result = conn.callProcedureFull(
'CALL register_user(?, ?, ?, ?, ?, ?, ?)',
params,
null
);
console.log('注册结果:', result.message);
if (result.userId) {
console.log('新用户ID:', result.userId);
console.log('赠送积分:', result.points);
}示例4 - 处理返回的结果集
javascript
var conn = informat.jdbc.systemConnection();
var users = [];
var params = [
{ value: 1, sqlType: 4, isOut: false }, // IN参数:状态
{
name: 'totalCount',
value: null,
sqlType: 4,
isOut: true,
isOutOnly: false
}
];
// 使用handler处理结果集中的每一行
var result = conn.callProcedureFull(
'CALL get_users_with_count(?, ?)',
params,
function(rs) {
// 这个函数会对每一行数据调用一次
users.push({
id: rs.getString('id'),
username: rs.getString('username'),
email: rs.getString('email'),
age: rs.getInt('age'),
points: rs.getInt('points')
});
}
);
console.log('总用户数:', result.totalCount);
console.log('查询到', users.length, '个用户:');
users.forEach(function(user, index) {
console.log(' ' + (index + 1) + '.', user.username,
'- 年龄:', user.age, '- 积分:', user.points);
});示例5 - Oracle: 使用REF CURSOR
javascript
var conn = informat.jdbc.createConnection({
dburl: 'jdbc:oracle:thin:@localhost:1521/XE',
dbuser: 'user',
dbpassword: 'password',
driverClassName: 'oracle.jdbc.driver.OracleDriver'
});
var employees = [];
var params = [
{ value: 'IT', isOut: false }, // IN参数:部门
{
name: 'cursor',
sqlType: 2012, // REF_CURSOR
isOut: true,
isOutOnly: true // Oracle支持纯OUT
}
];
conn.callProcedureFull(
'{CALL get_employees_by_dept(?, ?)}',
params,
function(rs) {
// 游标数据会自动在handler中处理
employees.push({
empId: rs.getString('emp_id'),
empName: rs.getString('emp_name'),
salary: rs.getDouble('salary')
});
}
);
console.log('员工列表:', employees);示例6 - 获取统计信息(多个OUT参数)
javascript
var conn = informat.jdbc.systemConnection();
var params = [
{ value: 1, sqlType: 4, isOut: false }, // IN参数:状态
{
name: 'totalCount',
value: null,
sqlType: 4, // INTEGER
isOut: true,
isOutOnly: false
},
{
name: 'avgSalary',
value: null,
sqlType: 8, // DOUBLE
isOut: true,
isOutOnly: false
},
{
name: 'totalPoints',
value: null,
sqlType: 4, // INTEGER
isOut: true,
isOutOnly: false
}
];
var result = conn.callProcedureFull(
'CALL get_user_statistics(?, ?, ?, ?)',
params,
null
);
console.log('统计信息:');
console.log(' 总用户数:', result.totalCount);
console.log(' 平均工资:', result.avgSalary);
console.log(' 总积分:', result.totalPoints);示例7 - 使用索引获取结果集字段
javascript
var conn = informat.jdbc.systemConnection();
var data = [];
var params = [
{ value: 1, sqlType: 4, isOut: false }
];
conn.callProcedureFull(
'CALL get_users(?)',
params,
function(rs) {
// 可以使用索引(从1开始)或字段名
data.push({
id: rs.getString(1), // 第1列
username: rs.getString(2), // 第2列
email: rs.getString(3), // 第3列
age: rs.getInt(4) // 第4列
});
}
);
console.log('获取数据:', data.length, '条');示例8 - 处理多个结果集
javascript
var conn = informat.jdbc.createConnection({
dburl: 'jdbc:mysql://localhost:3306/mydb',
dbuser: 'root',
dbpassword: 'password',
driverClassName: 'com.mysql.cj.jdbc.Driver'
});
var topUsers = [];
var statsInfo = null;
var params = [
{ value: 1, sqlType: 4, isOut: false }
];
conn.callProcedureFull(
'CALL get_user_summary(?)',
params,
function(rs) {
// handler会自动处理多个结果集
// 可以通过列数判断当前是哪个结果集
var colCount = rs.getColumnCount();
if (colCount === 3) {
// 第一个结果集: id, username, points
topUsers.push({
id: rs.getString('id'),
username: rs.getString('username'),
points: rs.getInt('points')
});
} else if (colCount === 5) {
// 第二个结果集: 统计信息
statsInfo = {
totalCount: rs.getInt('total_count'),
avgSalary: rs.getDouble('avg_salary'),
totalPoints: rs.getInt('total_points'),
maxAge: rs.getInt('max_age'),
minAge: rs.getInt('min_age')
};
}
}
);
console.log('Top用户(前5名):', topUsers.length, '人');
topUsers.forEach(function(user, idx) {
console.log(' ' + (idx + 1) + '.', user.username, '- 积分:', user.points);
});
if (statsInfo) {
console.log('统计信息:');
console.log(' 总数:', statsInfo.totalCount);
console.log(' 平均工资:', statsInfo.avgSalary);
console.log(' 总积分:', statsInfo.totalPoints);
console.log(' 年龄范围:', statsInfo.minAge, '-', statsInfo.maxAge);
}示例9 - SQL Server: 带返回值和OUT参数
javascript
var conn = informat.jdbc.createConnection({
dburl: 'jdbc:sqlserver://localhost:1433;databaseName=mydb',
dbuser: 'sa',
dbpassword: 'password',
driverClassName: 'com.microsoft.sqlserver.jdbc.SQLServerDriver'
});
var params = [
{
name: 'returnValue',
value: null,
sqlType: 4, // INTEGER (RETURN值)
isOut: true,
isOutOnly: true
},
{ value: 'zhangsan', isOut: false }, // IN参数:用户名
{ value: 'password123', isOut: false }, // IN参数:密码
{
name: 'userId',
value: null,
sqlType: 12, // VARCHAR
isOut: true,
isOutOnly: true
},
{
name: 'roleId',
value: null,
sqlType: 4, // INTEGER
isOut: true,
isOutOnly: true
}
];
// SQL Server: 使用 {? = CALL ...} 语法获取RETURN值
var result = conn.callProcedureFull(
'{? = CALL sp_user_login(?, ?, ?, ?)}',
params,
function(rs) {
// 如果存储过程返回结果集,在这里处理
}
);
console.log('返回值:', result.returnValue); // 0=成功, -1=失败
console.log('用户ID:', result.userId);
console.log('角色ID:', result.roleId);
if (result.returnValue === 0) {
console.log('登录成功');
} else {
console.log('登录失败');
}数据库差异说明
参数类型支持:
- PostgreSQL: 只支持INOUT参数,不支持纯OUT参数,
isOutOnly应设为false。支持通过游标(sqlType: 1111)返回结果集 - MySQL: 支持IN、OUT、INOUT三种参数类型。支持返回多个结果集
- Oracle: 支持IN、OUT、INOUT,通过REF_CURSOR(sqlType: 2012)返回结果集
- SQL Server: 支持IN、OUT、INOUT,并有RETURN返回值(需作为第一个参数)
SQL语法差异:
- PostgreSQL:
CALL procedure_name(?, ?) - MySQL:
CALL procedure_name(?, ?) - Oracle:
{CALL procedure_name(?, ?)} - SQL Server:
{CALL procedure_name(?, ?)}或{? = CALL procedure_name(?, ?)}
类型转换:
- PostgreSQL: 如果在params中指定了
sqlType,则无需在SQL中使用CAST(? AS 类型),系统会自动处理类型转换 - 其他数据库: 建议在params中指定
sqlType,可以避免类型转换问题
注意事项
- handler参数必填: 即使存储过程不返回结果集,也必须提供handler函数
- OUT/INOUT参数必须设置sqlType: 类型值参考上方"SQL类型常量表"
- 参数命名: 为OUT/INOUT参数设置
name属性,便于获取返回值 - NULL值处理: INOUT参数的初始值可以为null,需要在JavaScript中妥善处理返回的null值
- 多结果集处理: handler函数会按顺序处理所有结果集,可以通过
rs.getColumnCount()或列名判断当前结果集 - 游标处理: PostgreSQL和Oracle的游标会在handler中自动展开为逐行数据
- 类型指定优势: 在params中指定sqlType可以简化SQL语句,避免手动类型转换
tableConnection
获取应用数据表的数据库连接
javascript
informat.jdbc.tableConnection()INFO
- 使用应用数据表的数据库连接可以查询、更新、删除应用的数据表。
- 如果连接创建不成功会抛出异常。
- 在使用数据表连接执行查询的时候,需要将数据表的标识符转换为小写形式
返回值
返回数据库连接对象Connection,使用此对象可进行数据库里的数据表进行添查删改操作。
示例
例如有数据表tableDemo
| 字段标识符 | 名称 |
|---|---|
| id | ID |
| name | 名称 |
| maxAge | 最大年龄 |
需要使用以下SQL执行查询
sql
select id, name, max_age from table_demo;javascript
var ret = []
var conn = informat.jdbc.tableConnection();
conn.select(`select id,name,create_time from task limit 10`, (rs) => {
ret.push({
id: rs.getString('id'),
name: rs.getString('name'),
createTime: rs.getTimestamp('create_time'),
})
});
console.log('ret', ret);如果想查询关联列表字段对应的邻接表,查询的格式为:
数据表标识符$字段标识符(驼峰转为下划线)
示例
javascript
var ret = []
var conn = informat.jdbc.tableConnection();
var sql = `select a.id from task$report a
inner join task b on a.id=b.id`;
conn.select(sql, (rs) => {
ret.push(rs.getString('id'))
})
console.log('ret', ret);systemConnection
获取系统数据库连接
javascript
informat.jdbc.systemConnection()TIP
- 连接创建不成功会抛出异常,使用系统数据库连接可以查询、更新、删除系统内的所有表。
- 使用系统数据库连接可以查询、更新、删除系统内的所有数据表。需要注意的是除非是非常必要的情况下,不要使用此功能。织信内部的数据表会随着版本的迭代发生变化,直接访问系统底层数据表有可能会导致在织信版本更新后应用功能异常。
- 需要注意的是当使用
systemConnection执行SQL语句时,表名的中appid要使用informat.app.appId()获取。在应用分发的过程中appid会发生变化。
返回值
返回数据库连接对象Connection
示例
javascript
var conn = informat.jdbc.systemConnection();
var ret = []
conn.select(`select id,name,create_time from v_croe0zft168y3_task limit 10`, (rs) => {
ret.push({
id: rs.getString('id'),
name: rs.getString('name'),
createTime: rs.getTimestamp('create_time'),
})
})
console.log('ret', ret);nextRecordId
为记录生成唯一ID
javascript
informat.jdbc.nextRecordId();返回值 类型String,返回13位小写字母和数字组成的字符串,并且首字母为小写字母。
示例
javascript
informat.jdbc.nextRecordId();text
u5wxh9kl3mxvisafesql
生成安全的sql,为带有占位符?的sql生成安全的完整sql
javascript
informat.jdbc.safesql(sql, params);| 参数 | 类型 | 描述 |
|---|---|---|
| sql | String | 数据库语句 |
| params | ...Object | 入参 |
返回值 类型为String,安全Sql
示例
javascript
const sql = `update tab set age=?,name=? where id=?`;
const params = [18, "李四", `'张' or 1=1`];
const result = informat.jdbc.safesql(sql, params);sql
update
tab
set age = 18,
name = '李四'
where id = ''
'张'
' or 1=1'ResultSet
TIP
columnIndex为索引时,起始索引为1
| 方法 | 返回值 | 描述 |
|---|---|---|
| getString(columnIndex) | String | 按照索引或者列名获取String类型的列 |
| getBoolean(columnIndex) | String | 按照索引或者列名获取Boolean类型的列 |
| getByte(columnIndex) | String | 按照索引或者列名获取Byte类型的列 |
| getShort(columnIndex) | String | 按照索引或者列名获取Short类型的列 |
| getInt(columnIndex) | String | 按照索引或者列名获取Integer类型的列 |
| getLong(columnIndex) | String | 按照索引或者列名获取Long类型的列 |
| getFloat(columnIndex) | String | 按照索引或者列名获取Float类型的列 |
| getDouble(columnIndex) | String | 按照索引或者列名获取Double类型的列 |
| getBytes(columnIndex) | String | 按照索引或者列名获取byte[]类型的列 |
| getDate(columnIndex) | String | 按照索引或者列名获取Date类型的列 |
| getTime(columnIndex) | String | 按照索引或者列名获取Time类型的列 |
| getTimestamp(columnIndex) | String | 按照索引或者列名获取Timestamp类型的列 |
| getObject(columnIndex) | String | 按照索引或者列名获取Object类型的列 |
| getBigDecimal(columnIndex) | String | 按照索引或者列名获取BigDecimal类型的列 |
| getColumnCount() | Integer | 返回结果集的列数量 |
| getColumnName(columnIndex) | String | 按照索引返回列名 |
| getColumnTypeName(columnIndex) | String | 按照索引返回列类型 |

