/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ignite.examples.datagrid.store.jdbc; import java.sql.Connection; 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.CacheStore; import org.apache.ignite.cache.store.CacheStoreAdapter; import org.apache.ignite.cache.store.CacheStoreSession; import org.apache.ignite.examples.model.Person; import org.apache.ignite.lang.IgniteBiInClosure; import org.apache.ignite.resources.CacheStoreSessionResource; /** * Example of {@link CacheStore} implementation that uses JDBC * transaction with cache transactions and maps {@link Long} to {@link Person}. */ public class CacheJdbcPersonStore extends CacheStoreAdapter<Long, Person> { /** Store session. */ @CacheStoreSessionResource private CacheStoreSession ses; /** {@inheritDoc} */ @Override public Person load(Long key) { System.out.println(">>> Store load [key=" + key + ']'); Connection conn = ses.attachment(); try (PreparedStatement st = conn.prepareStatement("select * from PERSON where id = ?")) { st.setString(1, key.toString()); ResultSet rs = st.executeQuery(); return rs.next() ? new Person(rs.getLong(1), rs.getString(2), rs.getString(3)) : null; } catch (SQLException e) { throw new CacheLoaderException("Failed to load object [key=" + key + ']', e); } } /** {@inheritDoc} */ @Override public void write(Cache.Entry<? extends Long, ? extends Person> entry) { Long key = entry.getKey(); Person val = entry.getValue(); System.out.println(">>> Store write [key=" + key + ", val=" + val + ']'); try { Connection conn = ses.attachment(); int updated; // Try update first. If it does not work, then try insert. // Some databases would allow these to be done in one 'upsert' operation. try (PreparedStatement st = conn.prepareStatement( "update PERSON set first_name = ?, last_name = ? where id = ?")) { st.setString(1, val.firstName); st.setString(2, val.lastName); st.setLong(3, val.id); updated = st.executeUpdate(); } // If update failed, try to insert. if (updated == 0) { try (PreparedStatement st = conn.prepareStatement( "insert into PERSON (id, first_name, last_name) values (?, ?, ?)")) { st.setLong(1, val.id); st.setString(2, val.firstName); st.setString(3, val.lastName); st.executeUpdate(); } } } catch (SQLException e) { throw new CacheWriterException("Failed to write object [key=" + key + ", val=" + val + ']', e); } } /** {@inheritDoc} */ @Override public void delete(Object key) { System.out.println(">>> Store delete [key=" + key + ']'); Connection conn = ses.attachment(); 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 object [key=" + key + ']', e); } } /** {@inheritDoc} */ @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]; Connection conn = ses.attachment(); try (PreparedStatement stmt = conn.prepareStatement("select * from PERSON limit ?")) { stmt.setInt(1, entryCnt); ResultSet rs = stmt.executeQuery(); int cnt = 0; while (rs.next()) { Person person = new Person(rs.getLong(1), rs.getString(2), rs.getString(3)); clo.apply(person.id, person); cnt++; } System.out.println(">>> Loaded " + cnt + " values into cache."); } catch (SQLException e) { throw new CacheLoaderException("Failed to load values from cache store.", e); } } }