java通过程序连接远程SqlServer数据库,并将远程数据库的数据同步到本地oracle

偶然碰到这个需求,在各种百度下终于成功完成需求。第一次写博客,希望大家多多指教!

在开发过程中,我最开始的问题是如何用java程序连接远程数据库,为此百度了很久才成功连接上远程数据库。

而且需要需求是说不能在代码里写死远程数据库的地址,需要将数据源写在配置文件(db.properties)里。

db.properties内容如下:

driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:ORCL
user=tzsb
password=tzsb

driver1=com.microsoft.sqlserver.jdbc.SQLServerDriver
url1=jdbc:sqlserver://远程数据库地址:端口号;DatabaseName=数据库名称
user1=数据库用户名
password1=数据库密码

因为需要操作两个不同的数据库,所以我在配置文件里写好了远程数据库和本地数据库的数据源信息。

在此需要一个工具类来读取这个配置文件db.properties里面的数据源信息。这个工具类是ReadProperties。

ReadProperties.java内容如下:

package com.wintime.db;

import java.io.InputStream;
import java.util.Properties;

public class ReadProperties {
	static private String driver = null;
	static private String url = null;
	static private String user = null;
	static private String password = null;
	//因为需要操作远程和本地两个数据库,所以需要定义两种变量,下面的get方法同理
	static private String driver1 = null;
	static private String url1 = null;
	static private String user1 = null;
	static private String password1 = null;

	static {
		loads();
	}

	synchronized static public void loads() {
		if (driver == null || url == null || user == null || password == null) {
			InputStream is = ReadProperties.class.getResourceAsStream("/db.properties");
			Properties dbproperties = new Properties();
			try {
				dbproperties.load(is);
				driver = dbproperties.getProperty("driver").toString();
				url = dbproperties.getProperty("url").toString();
				user = dbproperties.getProperty("user").toString();
				password = dbproperties.getProperty("password").toString();
				//因为需要操作远程和本地两个数据库,所以需要分别获取数据源信息
				driver1 = dbproperties.getProperty("driver1").toString();
				url1 = dbproperties.getProperty("url1").toString();
				user1 = dbproperties.getProperty("user1").toString();
				password1 = dbproperties.getProperty("password1").toString();

			} catch (Exception e) {
				System.err.println("不能读取属性文件. " + "请确保db.properties在CLASSPATH指定的路径中");
			}
		}
	}

	public static String getDriver1() {
		if (driver1 == null)
			loads();
		return driver1;
	}

	public static String getUrl1() {
		if (url1 == null)
			loads();
		return url1;
	}

	public static String getUser1() {
		if (user1 == null)
			loads();
		return user1;
	}

	public static String getPassword1() {
		if (password1 == null)
			loads();
		return password1;
	}

	public static String getDriver() {
		if (driver == null)
			loads();
		return driver;
	}

	public static String getUrl() {
		if (url == null)
			loads();
		return url;
	}

	public static String getUser() {
		if (user == null)
			loads();
		return user;
	}

	public static String getPassword() {
		if (password == null)
			loads();
		return password;
	}

}

在写好工具类之后就开始最重要的部分,那就是连接远程数据库,并将数据同步到本地数据库中。

Yqxw.java内容如下:

package com.tzsb;

import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.wintime.db.ReadProperties;

public class Yqxw implements Runnable {
	
	@Override
	public void run() {
		Connection conn = null;
		Connection conn1 = null;
		Statement stmt = null;
		Statement stmt1 = null;
		ResultSet rs = null;
		ResultSet rs1 = null;
		String sql = "";
		String sql1 = "";
		try {
                        //开始获取远程服务器的连接,要非常注意的地方是getDriver1()而不是                getDriver()因为db.properties配置文件中远程数据库的数据源信息是driver1而不是driver
    			Class.forName(ReadProperties.getDriver1());
                        //这里也要改成对应的getUrl1()、getUser1()和getPassword1()
			conn1 = DriverManager.getConnection(ReadProperties.getUrl1(), ReadProperties.getUser1(),
					ReadProperties.getPassword1());
                        //编写sql语句
			sql = "select title,time,laiyuan,url,company from 远程数据库的某张表";
                        
			stmt = conn1.createStatement();
                        //执行查询的sql
			rs = stmt.executeQuery(sql);
                        //因为查询出多条记录,并且每条记录有多个字段,所以用List<Map<String, Object>>集合来存放数据
			List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
                        //循环遍历rs结果集,将结果集存放到list集合中
			while (rs.next()) {
				Map<String, Object> map = new HashMap<String, Object>();
                                //将查询出的结果集中的数据分别用变量存放
				map.put("title", rs.getString("title"));
				map.put("time", rs.getString("time"));
				map.put("laiyuan", rs.getString("laiyuan"));
				map.put("url", rs.getString("url"));
				map.put("company", rs.getString("company"));
				listMap.add(map);
			}
			conn1.close();
			stmt.close();
			rs.close();
                        //将远程数据库的数据存放到list集合后开始连接本地的oracle数据库
                        //注意这里是getDriver()
			Class.forName(ReadProperties.getDriver());
                        //注意这里是getUrl()、getUser()和getPassword()
			conn = DriverManager.getConnection(ReadProperties.getUrl(), ReadProperties.getUser(),
					ReadProperties.getPassword());

			String title = "";
			String time = "";
			String laiyuan = "";
			String url = "";
			String company="";
			String sql2="";
			for (int i = 0; i < listMap.size(); i++) {
				title = (String) listMap.get(i).get("title");
				time = (String) listMap.get(i).get("time");
				laiyuan = (String) listMap.get(i).get("laiyuan");
				laiyuan=laiyuan.replaceAll(" ", "");
				url = (String) listMap.get(i).get("url");
				company = (String) listMap.get(i).get("company");
				sql1 = "insert into 本地要插入的表(id,TITLE,pubtime,Source,URL,COMPANY_NAME,lev) "
						+ "values(SEQ_BAIDUNEWS.nextval,'" + title + "','" + time + "','" + laiyuan + "','" + url + "','"+company+"','*')";
				sql2="select count(1) zs from 本地要插入的表 where title ='"+title+"'";
				stmt1 = conn.createStatement();
                                //插入数据前先判断该表是否存在该数据,防止重复插入
				rs1=stmt1.executeQuery(sql2);
				if(rs1.next()) {
					if("0".equals(rs1.getString("zs"))) {
						stmt1.executeQuery(sql1);
						stmt1.close();
					}else {
						
					}
				}
				stmt1.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (rs1 != null) {
				try {
					rs1.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (stmt1 != null) {
				try {
					stmt1.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (conn != null) {
				try {
					conn.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
			if (conn1 != null) {
				try {
					conn1.close();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

}

需要特别注意的一点是:如果将操作数据库的语句写在循环中时,一定要在操作后写关闭语句stmt1.close(); ,不然会报错java.sql.SQLException: ORA-00604: 递归 SQL 级别 1 出现错误。切记!!!

因为需求中说需要定时执行,所以还需要一个定时执行的程序YqxwSchedule.java。

YqxwSchedule.java内容如下:

package com.tzsb;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class YqxwSchedule {
	/**
	 * 以固定周期频率执行任务
	 */
	public static void executeFixedRate() {
		ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);
		// 每7天更新一次,需要定时执行时取消注释
		//executor.scheduleAtFixedRate(new Yqxw(), 0, 7, TimeUnit.DAYS);
		new  Thread(new Yqxw()).start();
	}

	public static void main(String[] args) {
		executeFixedRate();
	}

}

在这个java文件中点击鼠标右键Run As——>Java Application就可以运行。

第一次写博客,如有错误之处,希望大家批评指正!

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值