quartz 如何动态传入自定义参数
1. 如何动态传入自己需要的参数?
需求:动态传参 (eg:传入job的执行方法)
思考:quartz 利用什么存储自己传入的参数?
在数据库中存储的位置?
如何取出存入的参数显示?
一、首先发现quartz 中用 jobDataMap 去存储附加信息(eg:自己定义传入的参数)
-
jobDataMap类:
每个JobDetail都关联了一个JobDataMap实例,JobDataMap是java.util.Map的子类,基本上是提供key- value形式的数据,当你创建JobDetail的时候,可以把附加信息放到JobDataMap中,那么在execute方法中可以根据key找到需 要的值。 -
有两种方式将数据添加到jobDataMap中:
第一种:
JobDetail job = new JobDetail…
job.getJobDataMap().put(“key”,”value”);
第二种:
以上两种方法都可以将自定义传入参数保存到jobDataMap中,此时,我们可以通过jobExecutionContext获取到jobDataMap.
打开数据库中各个数据表发现并无法直接看到有jobDataMap这个字段,因为官方表的表结构中并没有这个字段。但是其实数据是已经保存到数据库中,以Blob类型存在了JOB_DATA (QRTZ_JOB_DETAIL表) 中。
即使直接查询数据库该字段也是无法显示具体我们存入的信息。因为我用的是Navicat,所以可以通过文本显示出blob字段里面的具体内容。
- 遇到的问题:
当使用数据库存储JobDetail的时候(默认情况下使用RAM),我们不能把没有实现 java.io.Serializable的对象放入JobDataMap中,因为Quartz将使用Blob字段保存(也可以通过配置文件关闭)序列化 过的JobDataMap中的对象。所以我们存到数据库中的信息都是经过序列化并用blob字段保存,这样就会导致一个问题,我们并不能直接利用直接的sql语句取出我们想要的数据,需要经过一系列的处理。
此处,可以通过配置文件关闭用blob保存。将下面代码处设为FALSE,默认值即为FALSE。因为最初参考别的人的配置文件是设置为TRUE,所以后来遇到blob转换问题,接下来会直接以TRUE为前提,分析一样遇到这种情况我如何从数据库中取出该 数据的。
三、如何取出利用jobDataMap存到数据库中的数据(Blob类型)?
如果利用SQL直接select取出,该字段值为null
最开始的思考时,在Java中编写工具类,把取出的blob类型进行转换,但是此处从数据库取出的时候就没有得到数据,使用网上的blob转string工具类并没有达到想要的结果。后来思考可以在数据库查询取出数据的时候就进行转化(网上有很多mysql如何读取blob数据类型数据的教程),此处贴出我是如何使用的:
- Java中创建一个工具类
具体代码如下:
public class BlobUtil extends BaseTypeHandler<String> {
//###指定字符集
private static final String DEFAULT_CHARSET = "utf-8";
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
String parameter, JdbcType jdbcType) throws SQLException {
ByteArrayInputStream bis;
try {
//###把String转化成byte流
bis = new ByteArrayInputStream(parameter.getBytes(DEFAULT_CHARSET));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
ps.setBinaryStream(i, bis, parameter.length());
}
@Override
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
Blob blob = rs.getBlob(columnName);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
try {
//###把byte转化成utf-8的字符串对象
return new String(returnValue, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}
@Override
public String getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
Blob blob = cs.getBlob(columnIndex);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
try {
return new String(returnValue, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}
@Override
public String getNullableResult(ResultSet arg0, int arg1)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
}
- 在jobMapper.xml 中,创建一个结果集,进行类型转化。
- 经过以上处理,用postman模拟得到结果:经过以上处理,用postman模拟得到结果:
问题:
此时得到结果为一串字符串,其中还包含了其他信息,但是我们需要的只是Method_Name=之后的信息。所以利用正则表达式,截取出需要的字符串。我们可以根据 取= 之后,\n之前的内容。
之后得到的结果: