============================================================
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.cache.Cache;
import javax.cache.integration.CacheLoaderException;
import javax.cache.integration.CacheWriterException;
import org.apache.ignite.cache.store.CacheStoreAdapter;
import org.apache.ignite.cache.store.CacheStoreSession;
import org.apache.ignite.lang.IgniteBiInClosure;
import org.apache.ignite.resources.CacheStoreSessionResource;
public class CacheJdbcPersonStoreTransactional extends CacheStoreAdapter<Long, Person> {
/** Auto-injected store session. */
@CacheStoreSessionResource
private CacheStoreSession ses;
// Complete transaction or simply close connection if there is no transaction.
// @Override
// public void sessionEnd(boolean commit) {
// try (Connection conn = ses.attachment()) {
// if (conn != null && ses.isWithinTransaction()) {
// if (commit)
// conn.commit();
// else
// conn.rollback();
// }
// } catch (SQLException e) {
// throw new CacheWriterException("Failed to end store session.", e);
// }
// }
// This mehtod is called whenever "get(...)" methods are called on IgniteCache.
@Override
public Person load(Long key) {
try (Connection conn = connection()) {
try (PreparedStatement st = conn.prepareStatement("select * from PERSON where id=?")) {
st.setLong(1, key);
ResultSet rs = st.executeQuery();
Person person = rs.next() ? new Person(rs.getLong(1), rs.getString(2), rs.getString(3)) : null;
System.out.println("---> load Person from DB: " + person);
return person;
}
} catch (SQLException e) {
throw new CacheLoaderException("Failed to load: " + key, e);
}
}
// This mehtod is called whenever "put(...)" methods are called on IgniteCache.
@Override
public void write(Cache.Entry<? extends Long, ? extends Person> entry) throws CacheWriterException {
Person val = null;
long key = 0;
try (Connection conn = connection()) {
// Syntax of MERGE statement is database specific and should be adopted for your database.
// If your database does not support MERGE statement then use sequentially update, insert statements.
// try (PreparedStatement st = conn.prepareStatement("merge into PERSON (id, firstname, lastname) key (id) VALUES (?, ?, ?)")) {
try (PreparedStatement st = conn.prepareStatement("insert into PERSON (id, firstname, lastname) values (?, ?, ?)")) {
val = entry.getValue();
st.setLong(1, entry.getKey());
st.setString(2, val.getFirstName());
st.setString(3, val.getLastName());
st.executeUpdate();
}
} catch (SQLException e) {
throw new CacheWriterException("Failed to write [key=" + key + ", val=" + val + ']', e);
}
}
// This mehtod is called whenever "remove(...)" methods are called on IgniteCache.
@Override
public void delete(Object key) {
try (Connection conn = connection()) {
try (PreparedStatement st = conn.prepareStatement("delete from PERSON where id=?")) {
st.setLong(1, (Long) key);
st.executeUpdate();
}
} catch (SQLException e) {
throw new CacheWriterException("Failed to delete: " + key, e);
}
}
// This mehtod is called whenever "loadCache()" and "localLoadCache()"
// methods are called on IgniteCache. It is used for bulk-loading the cache.
// If you don't need to bulk-load the cache, skip this method.
@Override
public void loadCache(IgniteBiInClosure<Long, Person> clo, Object... args) {
if (args == null || args.length == 0 || args[0] == null)
throw new CacheLoaderException("Expected entry count parameter is not provided.");
final int entryCnt = (Integer) args[0];
try (Connection conn = connection()) {
try (PreparedStatement st = conn.prepareStatement("select * from PERSON")) {
try (ResultSet rs = st.executeQuery()) {
int cnt = 0;
while (cnt < entryCnt && rs.next()) {
Person person = new Person(rs.getLong(1), rs.getString(2), rs.getString(3));
clo.apply(person.getId(), person);
cnt++;
}
}
}
} catch (SQLException e) {
throw new CacheLoaderException("Failed to load values from cache store.", e);
}
}
// Opens JDBC connection and attaches it to the ongoing
// session if within a transaction.
private Connection connection() throws SQLException {
if (ses.isWithinTransaction()) {
Connection conn = ses.attachment();
if (conn == null) {
conn = openConnection(false);
// Store connection in the session, so it can be accessed
// for other operations within the same transaction.
ses.attach(conn);
}
return conn;
}
// Transaction can be null in case of simple load or put operation.
else
return openConnection(true);
}
// Opens JDBC connection.
private Connection openConnection(boolean autocommit) throws SQLException {
// Open connection to your RDBMS systems (Oracle, MySQL, Postgres, DB2, Microsoft SQL, etc.)
// In this example we use H2 Database for simplification.
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.*.*/*****", "user", "pwd");
conn.setAutoCommit(true);
return conn;
}
}
===============================================================
import javax.cache.configuration.FactoryBuilder;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.Ignition;
import org.apache.ignite.cache.CachePeekMode;
import org.apache.ignite.configuration.IgniteConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class IgniteRWTest {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
String[] path = System.getProperty("java.class.path").split(";");
String filePath = path[0] + "/com/pingan/pilot/ignite/rwthru/person.xml";
ApplicationContext context = new FileSystemXmlApplicationContext(filePath);
IgniteConfiguration config = (IgniteConfiguration) context.getBean("igniteConfiguration");
config.getCacheConfiguration()[0].setCacheStoreFactory(FactoryBuilder.factoryOf(CacheJdbcPersonStoreTransactional.class));
Ignite ignite = Ignition.start(config);
IgniteCache<Long, Person> personCache = ignite.getOrCreateCache("personCache");
Thread monitor = new Thread(new IgniteRWTest().new Monitor(personCache));
monitor.start();
personCache.loadCache(null, 100);
// personCache.putIfAbsent(1l, new Person(1l, "Jeff", "Jiao"));
// personCache.putIfAbsent(2l, new Person(2l, "Leon", "Huang"));
// personCache.putIfAbsent(3l, new Person(3l, "Alvin", "He"));
// personCache.putIfAbsent(4l, new Person(4l, "Walt", "Zhang"));
// if data is already in cache, then return from cache directly, otherwise go into load() method
// personCache.get(1l);
// personCache.get(2l);
// personCache.get(3l);
// personCache.get(4l);
// personCache.remove(1l);
// personCache.remove(2l);
// personCache.remove(3l);
// personCache.remove(4l);
}
@SuppressWarnings("rawtypes")
class Monitor implements Runnable {
IgniteCache m_cache;
public Monitor(IgniteCache p_cache) {
m_cache = p_cache;
}
@Override
public void run() {
while (true) {
System.out.println("===================> Cache Size is: " + m_cache.size(CachePeekMode.PRIMARY));
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
============================================================
import java.io.Serializable;
public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private long id;
private String firstName;
private String lastName;
public Person(long id, String fN, String lN) {
this.id = id;
this.firstName = fN;
this.lastName = lN;
}
@Override
public String toString() {
return "[" + String.valueOf(id) + " , " + firstName + " , " + lastName + "]";
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
=============================================================
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/lang
http://www.springframework.org/schema/lang/spring-lang-4.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-4.0.xsd">
<bean id="igniteConfiguration" class="org.apache.ignite.configuration.IgniteConfiguration">
<property name="clientMode" value="false" />
<property name="gridLogger">
<bean class="org.apache.ignite.logger.slf4j.Slf4jLogger" />
</property>
<property name="cacheConfiguration">
<list>
<bean class="org.apache.ignite.configuration.CacheConfiguration">
<property name="name" value="personCache" />
<property name="cacheMode" value="PARTITIONED" />
<property name="atomicityMode" value="TRANSACTIONAL" />
<property name="statisticsEnabled" value="true" />
<property name="managementEnabled" value="true" />
<property name="readThrough" value="true" />
<property name="writeThrough" value="true" />
<property name="queryEntities">
<list>
<bean class="org.apache.ignite.cache.QueryEntity">
<property name="keyType" value="java.lang.Integer" />
<property name="valueType" value="Person" />
<property name="fields">
<map>
<entry key="id" value="java.lang.Long" />
<entry key="firstName" value="java.lang.String" />
<entry key="lastName" value="java.lang.String" />
</map>
</property>
<property name="indexes">
<list>
<bean class="org.apache.ignite.cache.QueryIndex">
<constructor-arg value="id" />
</bean>
<bean class="org.apache.ignite.cache.QueryIndex">
<constructor-arg value="firstName" />
</bean>
<bean class="org.apache.ignite.cache.QueryIndex">
<constructor-arg value="lastName" />
</bean>
</list>
</property>
</bean>
</list>
</property>
</bean>
</list>
</property>
</bean>
</beans>