您的位置:首页 > 数据库 > Oracle

JAVA结合Oracle的Database Change Notification实现替代获取实时数据需要的刷库操作

2014-11-10 16:50 961 查看
本文的编写目的是建立在这个一个需求基础上:某个系统需要不停的读取数据库中的数据来保证系统中展示的数据为最新的实时数据,并且系统的数据库Oracle10.2以上的版本

Database Change Notification的官方资料可以参考https://docs.oracle.com/cd/E11882_01/java.112/e16548/dbchgnf.htm#JJDBC28815

一、首先我们创建一个表做测试用
create table nj_tmp_tmp(id number, val number);

insert into nj_tmp_tmp values(1,100);
insert into nj_tmp_tmp values(2,200);
insert into nj_tmp_tmp values(3,300);
commit;


二、给操作该表的数据库赋予相应的权限
grant change notification to scott;


此处scott仅作示例用,按照实际用户为准

三、编写相应的java代码

oracle官方给出的步骤



简单的翻译就是第一步创建一个注册器,如下所示

 
DatabaseChangeRegistration dcr = conn.registerDatabaseChangeNotification(prop);


其中conn为OracleConnection的实例对象,prop为一些连接的参数

第二步就是写一个查询表示要监听那些表的修改通知,如下所示
statement.executeQuery("select * from nj_tmp_tmp");


此处表示监听nj_tmp_tmp表

第三步就是注册事件,进行绑定,创建notification来用于响应表或者结果集的变动,Oracle数据库使用JDBC驱动通过一个特定网络来通知java事件

 
dcr.addListener(new DatabaseChangeListener(){

@Override
public void onDatabaseChangeNotification(DatabaseChangeEvent arg0) {
TableChangeDescription[] td=arg0.getTableChangeDescription();
for(TableChangeDescription t:td){
for(RowChangeDescription r:t.getRowChangeDescription()){
ROWID rowid = r.getRowid();
System.out.println("--------"+new String(rowid.getBytes()));
}
}
}

});


接下来上完整代码:代码参考了oracle官网的资料及网络大牛的各种资料,该 代码中仅对插入事件进行监听
public class DBChangeNotification
{
static final String USERNAME= "*****";//数据库用户名
static final String PASSWORD= "*****";//数据库密码
static String URL;

public static void main(String[] argv)
{
URL = "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=127.0.0.1)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=orcl)))";
try
{
OracleConnection conn = connect();
Properties prop = new Properties();
prop.setProperty(OracleConnection.DCN_NOTIFY_ROWIDS,"true");
prop.setProperty(OracleConnection.NTF_TIMEOUT, "0");
prop.setProperty(OracleConnection.DCN_IGNORE_DELETEOP, "true");
prop.setProperty(OracleConnection.DCN_IGNORE_UPDATEOP,"true");
DatabaseChangeRegistration dcr = conn.registerDatabaseChangeNotification(prop);

try
{
dcr.addListener(new DatabaseChangeListener(){

@Override
public void onDatabaseChangeNotification(DatabaseChangeEvent arg0) {
TableChangeDescription[] td=arg0.getTableChangeDescription();
for(TableChangeDescription t:td){
for(RowChangeDescription r:t.getRowChangeDescription()){
ROWID rowid = r.getRowid();
System.out.println("--------"+new String(rowid.getBytes()));
}
}
}

});
Statement stmt = conn.createStatement();
((OracleStatement)stmt).setDatabaseChangeRegistration(dcr);
ResultSet rs = stmt.executeQuery("select * from nj_tmp_tmp");
String[] tableNames = dcr.getTables();
for(int i=0;i<tableNames.length;i++)
System.out.println(tableNames[i]+" is part of the registration.");
rs.close();
stmt.close();
}
catch(SQLException ex)
{
if(conn != null)
conn.unregisterDatabaseChangeNotification(dcr);
throw ex;
}
finally
{
try
{
conn.close();
}
catch(Exception innerex){ innerex.printStackTrace(); }
}
}
catch(SQLException mainSQLException )
{
mainSQLException.printStackTrace();
}
}

/**
* Creates a connection the database.
*/
static OracleConnection connect() throws SQLException
{
OracleDriver dr = new OracleDriver();
Properties prop = new Properties();
prop.setProperty("user",DBChangeNotification.USERNAME);
prop.setProperty("password",DBChangeNotification.PASSWORD);
return (OracleConnection)dr.connect(DBChangeNotification.URL,prop);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息