JDBI Quick sample
ICategoryDAO.java : create a data access interface (implement is not required)
package com.prhythm.erotic.task.data.dao; import com.prhythm.erotic.entity.source.Category; import com.prhythm.erotic.task.data.mapper.CategoryMapper; import org.skife.jdbi.v2.sqlobject.Bind; import org.skife.jdbi.v2.sqlobject.BindBean; import org.skife.jdbi.v2.sqlobject.SqlQuery; import org.skife.jdbi.v2.sqlobject.SqlUpdate; import org.skife.jdbi.v2.sqlobject.customizers.RegisterMapper; import org.skife.jdbi.v2.sqlobject.mixins.Transactional; import java.util.List; /** * Created by nanashi07 on 15/6/14. */ @RegisterMapper(CategoryMapper.class) public interface ICategoryDAO extends Transactional<ICategoryDAO> { @SqlUpdate("insert into Category (Source, Url, Category, SubCategory, Enabled) values (:source, :url, :category, :subCategory, :enabled)") int insert(@BindBean Category category); @SqlUpdate("update Category set Source = :source, Category = :category, SubCategory = :subCategory, Enabled = :enabled where Url = :url") int update(@BindBean Category category); @SqlUpdate("update Category set Enabled = :enabled") int setEnabled(@Bind("enabled") boolean enabled); @SqlQuery("select * from Category where Url = :url") Category findCategory(@Bind("url") String url); @SqlQuery("select * from Category") List<Category> getCategories(); void close(); }
CategoryMapper.java : create a object mapper for convertion
package com.prhythm.erotic.task.data.mapper; import com.prhythm.erotic.entity.source.Category; import org.skife.jdbi.v2.StatementContext; import org.skife.jdbi.v2.tweak.ResultSetMapper; import java.sql.ResultSet; import java.sql.SQLException; /** * Created by nanashi07 on 15/6/14. */ public class CategoryMapper extends MetaDataSupport implements ResultSetMapper<Category> { @Override public Category map(int index, ResultSet r, StatementContext ctx) throws SQLException { Category category = new Category(); if (hasColumn(r, "source")) category.setSource(r.getString("source")); if (hasColumn(r, "url")) category.setUrl(r.getString("url")); if (hasColumn(r, "category")) category.setCategory(r.getString("category")); if (hasColumn(r, "subCategory")) category.setSubCategory(r.getString("subCategory")); if (hasColumn(r, "enabled")) category.setEnabled(r.getBoolean("enabled")); return category; } }
ICategoryService.java : create a data access service interface
package com.prhythm.erotic.task.data; import com.prhythm.erotic.entity.source.Category; import java.util.Collection; import java.util.List; /** * Created by nanashi07 on 15/6/14. */ public interface ICategoryService { /** * Retrive all categories * * @return */ List<Category> getCategories(); /** * Update categories * * @param categories * @return */ int updateCategories(Collection<Category> categories); }
CategoryServiceImpl.java : Implement the data access interface
package com.prhythm.erotic.task.data.impl; import com.prhythm.erotic.entity.source.Category; import com.prhythm.erotic.logging.LogHandler; import com.prhythm.erotic.task.data.ICategoryService; import com.prhythm.erotic.task.data.dao.ICategoryDAO; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.IDBI; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Service; import java.util.Collection; import java.util.List; /** * Created by nanashi07 on 15/6/14. */ @Service public class CategoryServiceImpl implements ICategoryService { @Autowired IDBI dbi; @Override public List<Category> getCategories() { Handle h = dbi.open(); ICategoryDAO dao = h.attach(ICategoryDAO.class); List<Category> categories = dao.getCategories(); dao.close(); h.close(); return categories; } @Override public int updateCategories(Collection<Category> categories) { int count = 0; Handle handle = dbi.open(); try { updateCategories(handle, categories); handle.commit(); } catch (Exception e) { LogHandler.error(e); handle.rollback(); } finally { handle.close(); } return count; } int updateCategories(Handle handle, Collection<Category> categories) { int count = 0; ICategoryDAO dao = handle.attach(ICategoryDAO.class); // Disable all items dao.setEnabled(false); for (Category c : categories) { Category found = dao.findCategory(c.getUrl()); if (found == null) { count += dao.insert(c); } else { count += dao.update(c); } } return count; } }
CategoryServiceTester.java : test usage
package com.prhythm.erotic.test.dao; import com.google.common.base.Stopwatch; import com.prhythm.erotic.entity.source.Category; import com.prhythm.erotic.logging.LogHandler; import com.prhythm.erotic.task.data.ICategoryService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.skife.jdbi.v2.IDBI; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import java.util.Arrays; import java.util.List; /** * Created by nanashi07 on 15/6/14. */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:spring/application-context.xml") public class CategoryServiceTester { @Autowired ICategoryService categoryService; @Test public void testGetCategories() { Stopwatch stopwatch = Stopwatch.createStarted(); List<Category> categories = categoryService.getCategories(); stopwatch.stop(); LogHandler.info("%d items loaded in %s", categories.size(), stopwatch); } @Test public void testUpdateCategories() { // Get current items List<Category> categories = categoryService.getCategories(); // Append 10 new items for (int i = 0; i < 10; i++) { Category c = new Category(); c.setSource("Prhythm"); c.setUrl("http://app.prhtyhm.com/sample/" + UUID.randomUUID()); c.setCategory("Blog"); c.setEnabled(true); categories.add(c); } Stopwatch stopwatch = Stopwatch.createStarted(); int count = categoryService.updateCategories(categories); stopwatch.stop(); LogHandler.info("%d items updated in %s", count, stopwatch); } }
datasourc.xml
<?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:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${com.prhythm.erotic.datasource.driver}"/> <property name="url" value="${com.prhythm.erotic.datasource.temp.url}"/> <property name="username" value="${com.prhythm.erotic.datasource.user}"/> <property name="password" value="${com.prhythm.erotic.datasource.password}"/> </bean> <tx:annotation-driven transaction-manager="txManager"/> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <constructor-arg ref="dataSource"/> </bean> <bean id="txDataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy"> <constructor-arg ref="dataSource"/> </bean> <bean class="org.skife.jdbi.v2.DBI" depends-on="txManager"> <constructor-arg ref="txDataSource"/> <property name="SQLLog"> <bean class="com.prhythm.erotic.task.logging.SQLLogAppender"/> </property> </bean> </beans>