GemFire读写示例

一、Gemfire相关

Gemfire是内存数据库,即它依托于内存实现数据的操作,但是对于单机来说,内存不是很大,因此Gemfire也支持集群。Gemfire利用集群机器的内存,然后将其划分成一个个Region,Region相当于关系型数据库中的表,其内部存储结构为key/value的形式,换句话说,存储的数据类似于一个大map。Gemfire支持OQL(Object Query Language),可以编写OQL语句查询数据。

二、Demo设计流程

首先通过JDBC从sqlserver中读出数据;然后将数据组按照每行的ID作为键,每行数据作为对象实例放入到map集合;然后利用Gemfire提供的接口将该map存入Gemfire,之后写OQL语句查询数据。

三、设计实现

1、JDBC查询sql读取数据并转化成Map<ID,Obj>的形式

package gemfire.getdata;

import gemfire.model.DynamicNews;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class GetDataFromSqlServer {

	private final String driverName  = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
	private final String url				   ="jdbc:sqlserver://10.1.5.106:1433; DatabaseName=JYDB";
	private final String username     ="READ";
	private final String password	   ="READ";
	
	/**
	 * 根据URL,username,Password获取数据库连接
	 * @author shihj
	 * @return
	 */
	private Connection getConnection(){
		Connection dbConn = null;
		try{
			Class.forName(driverName);
			dbConn = DriverManager.getConnection(url, username, password);
		}catch(Exception e){
			e.printStackTrace();
		}
		return dbConn;
	}
	
	/**
	 * 根据sql查询结果集
	 * @author shihj
	 * @param sql
	 * @return
	 * @throws  
	 * @throws IllegalArgumentException 
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public Map<Long,DynamicNews> query(String sql){
		Map<Long,DynamicNews> ret = new HashMap();
		try(Statement st = getConnection().createStatement();ResultSet rs  = st.executeQuery(sql);) {
			   ResultSetMetaData md = rs.getMetaData(); //得到结果集(rs)的结构信息,比如字段数、字段名等   
	           int columnCount = md.getColumnCount(); //返回此 ResultSet 对象中的列数   
	           //业务对象的属性数组  
	           Field[] fields = DynamicNews.class.getDeclaredFields();  
	           while(rs.next()){//对每一条记录进行操作  
	               Object obj = DynamicNews.class.newInstance();//构造业务对象实体  
	               //将每一个字段取出进行赋值  
	               for(int i = 1;i<=columnCount;i++){  
	                   Object value = rs.getObject(i);  
	                   //寻找该列对应的对象属性  
	                   for(int j=0;j<fields.length;j++){  
	                       Field f = fields[j];  
	                       //如果匹配进行赋值  
	                       if(f.getName().equalsIgnoreCase(md.getColumnName(i))){  
	                           boolean flag = f.isAccessible();  
	                           f.setAccessible(true);
	                           switch(f.getGenericType().toString()){
	                           		case "class java.lang.Integer":
	                           			f.set(obj, value == null ? value : Integer.parseInt(value.toString().trim()));  
	                           			break;
	                           		case "class java.lang.Long":
	                           			f.set(obj, value == null ? value : Long.parseLong(value.toString().trim()));  
	                           			break;
	                           		default:
	                           			f.set(obj, value);  
	                           			break;
	                           			
	                           }
	                           f.setAccessible(flag);  
	                       }  
	                   }  
	               }  
	               ret.put(((DynamicNews)obj).getID(),(DynamicNews)obj);
	           }   
		} catch (SQLException | IllegalAccessException|InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return ret;
	}
	
	public static void main(String[] args) throws Exception{
		System.out.println(new GetDataFromSqlServer().query("Select top 2 * from NI_DynamicNews"));
	}
}

2、sqlserver表映射实体类

package gemfire.model;

import java.io.Serializable;
import java.util.Date;

public class DynamicNews implements Serializable{
	private static final long serialVersionUID = 8421034353120794834L;
	private Long ID;
	private Date InfoPublDate;
	private String InfoTitle;
	private Integer Category;
	private Integer NewsType;
	private Integer MediaCode;
	private String Media;
	private String InfoURL;
//	private Text Content;
	
//	private Byte[] PictureContent;
	private Integer PictureType;
	private String PictureURL;
	private Date UpdateTime;
	private Long JSID;
	private Integer Flag;
	public Long getID() {
		return ID;
	}
	public void setID(Long iD) {
		ID = iD;
	}
	public Date getInfoPublDate() {
		return InfoPublDate;
	}
	public void setInfoPublDate(Date infoPublDate) {
		InfoPublDate = infoPublDate;
	}
	public String getInfoTitle() {
		return InfoTitle;
	}
	public void setInfoTitle(String infoTitle) {
		InfoTitle = infoTitle;
	}
	public Integer getCategory() {
		return Category;
	}
	public void setCategory(Integer category) {
		Category = category;
	}
	public Integer getNewsType() {
		return NewsType;
	}
	public void setNewsType(Integer newsType) {
		NewsType = newsType;
	}
	public Integer getMediaCode() {
		return MediaCode;
	}
	public void setMediaCode(Integer mediaCode) {
		MediaCode = mediaCode;
	}
	public String getMedia() {
		return Media;
	}
	public void setMedia(String media) {
		Media = media;
	}
	public String getInfoURL() {
		return InfoURL;
	}
	public void setInfoURL(String infoURL) {
		InfoURL = infoURL;
	}
	public Integer getPictureType() {
		return PictureType;
	}
	public void setPictureType(Integer pictureType) {
		PictureType = pictureType;
	}
	public String getPictureURL() {
		return PictureURL;
	}
	public void setPictureURL(String pictureURL) {
		PictureURL = pictureURL;
	}
	public Date getUpdateTime() {
		return UpdateTime;
	}
	public void setUpdateTime(Date updateTime) {
		UpdateTime = updateTime;
	}
	public Long getJSID() {
		return JSID;
	}
	public void setJSID(Long jSID) {
		JSID = jSID;
	}
	public Integer getFlag() {
		return Flag;
	}
	public void setFlag(Integer flag) {
		Flag = flag;
	}
	
	public String toString(){
		return "id=" + this.ID+
					";InfoPublDate="+this.InfoPublDate+
					";InfoTitle="+this.InfoTitle+
					";Category="+this.Category+
					";NewsType="+this.NewsType+
					";MediaCode="+this.MediaCode+
					";Media="+this.Media+
					";InfoURL="+this.InfoURL+
					";PictureType="+this.PictureType+
					";PictureURL="+this.PictureURL+
					";UpdateTime="+this.UpdateTime+
					";JSID="+this.JSID+
					";Flag="+this.Flag;
	}
	
}
注意:因为后面需要将该实体类放到Gemfire中,以便能够在查询时能将结果再变成实体类对象,所以,实体类的实现需要实现序列化接口,否则,在查询时会报错。

3、构造Gemfire服务

首先,需要通过配置文件配置Gemfire集群的位置,命名为cache.xml,配置文件如下:
<?xml version="1.0"?>
<!DOCTYPE client-cache PUBLIC
    "-//GemStone Systems, Inc.//GemFire Declarative Caching 6.5//EN"
    "http://www.gemstone.com/dtd/cache6_5.dtd">
<client-cache>
	<pool name="client" subscription-enabled="true">
		<locator host="10.139.101.113" port="1527"/>
		<locator host="10.139.106.159" port="1527"/>
	</pool>
</client-cache>
然后,读取该配置文件,建立CacheServer,代码如下:
package gemfire.option;

import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;

public class CacheServer {

    private volatile static ClientCache singleton = null;
	
	private CacheServer (){
		
	}  
	
    public static  ClientCache getCache(){
		 if (singleton == null) {  
			 synchronized (CacheServer.class) {  
				 if (singleton == null) {  
		              singleton =  new ClientCacheFactory() .set("name", "client")
		            		  .set("cache-xml-file", "cache.xml").create();
		         }  
			 }
			 
		 }
		 return singleton;  
	}
    
    @Override
	protected void finalize() throws Throwable 
    { 
    	singleton.close();
    	singleton = null;
        super.finalize(); 
    } 
}
第三步,可以依托写好的CacheServer封装一些操作,比如查询,或者写入操作,因Gemfire可以定义很多个Region,所以,可以将Region写入配置文件,然后读取配置文件,再通过regionName获得相应的region操作,本例中region配置如下:
<?xml version="1.0"?>
<!DOCTYPE client-cache PUBLIC
    "-//GemStone Systems, Inc.//GemFire Declarative Caching 6.5//EN"
    "http://www.gemstone.com/dtd/cache6_5.dtd">

<client-cache>

	<region-attributes id="clientAttributes" pool-name="client"
		refid="CACHING_PROXY" />

	<region name="TEST_REGION">
		<region-attributes refid="clientAttributes" />
	</region>
</client-cache>
第四步,创建GemfireOption类:
package gemfire.option;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.Map;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.query.Query;
import com.gemstone.gemfire.cache.query.QueryService;

public class GemfireOption{

	//获取一个cache操作,类似于操作数据库的句柄
	ClientCache cache = CacheServer.getCache();

	//读取region的配置
	public GemfireOption() throws FileNotFoundException{
		String path = System.getProperty("user.dir")
				+ java.io.File.separator + "bin"+"\\"+"Rengion.xml";
		System.out.println(path);
		File f = new File(path);
		InputStream in = new FileInputStream(f);
		this.cache.loadCacheXml(in);
	}

	//存值
	public void RengionPutAll(String rengionName, Map<?, ?> map){
		cache.getRegion(rengionName).putAll(map);
	}

	//查询数据
	public Object query(String queryStr){
		Object obj = null;
		try{
			QueryService queryService = cache.getQueryService();
			Query query = queryService.newQuery(queryStr);
			obj = query.execute();
		}catch (Exception e){
			e.printStackTrace();
		}
		return obj;
	}
}

4、测试类

package gemfire;

import java.io.FileNotFoundException;

import gemfire.getdata.GetDataFromSqlServer;
import gemfire.option.GemfireOption;

public class App {

	public static void main(String[] args) throws FileNotFoundException {
		GemfireOption co = new GemfireOption();
		co.RengionPutAll("TEST_REGION", new GetDataFromSqlServer().query("SELECT TOP 10000 * FROM NI_DynamicNews"));
		System.out.println(co.query("SELECT * FROM /TEST_REGION d WHERE d.JSID ="+Long.parseLong("467322321052".trim())+"l").toString());
		System.out.println(Long.parseLong("467322321052".trim()));
	}

}

四、运行测试

1、首先如果region不存在则需要在集群先创建

上图所示创建region成功。
2、将数据实体类打包上传至gemfire
3、以上步骤完成之后运行App.java并查看执行结果

五、总结

Gemfire算是一款优秀的内存数据库,查询时不仅仅是取出内存中的值,而且可以按照内存中的列来进行数据查询,从上面的查询语句可以看出,操作完全跟数据库中的操作是相同的,这也是它的特点之一。由于是第一次接触Gemfire,研究的也不是很深入,做个记录方便以后查阅。
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值