刪除了不少對其餘包的引用,如今應該是最小可用的版本了。html
索性opensource,LGPL協議,歡迎你們試用。這玩意最大的優勢,就是隻是一個工具,而不是框架,因此與標準的JDBC和preparedstatement結合的很順暢,能大幅度下降jdbc寫法的工做量,java
不過我的仍是建議,寫入用orm,讀取在合適的時候稍微用一下綁定數據的DTO的代碼,因此提供了GenericSelect類和GenericUpdate的rawSql函數,方便你們本身拼where的sql,真遇到複雜的select查詢,你們仍是別期望了,其實hibernate甚至nutzDAO也都期望不上的。mysql
這個工具包,完全貫徹了讀寫分離的思想,若是實現讀取,須要繼承GenericReader,若是實現寫入,繼承GenericWriter。git
並且閒的蛋疼,把自動建立表和數據庫也加上了。具體代碼參考GenericCreator。github
不過裏面依賴的的guava,這個是用來測試的。實際用能夠刪掉。sql
話說回來,用異步的guava的AsyncEventBus+Executors.newFixedThreadPool()+CountDownLatch()進行多線程的測試,很是高效,強烈推薦。數據庫
github地址:多線程
https://github.com/hubinix/com.kamike.db 框架
剛剛有更新了,修改了幾個bug異步
依賴的包:
c3p0-0.9.2.1 cos-26Dec2008 guava-15.0 mchange-commons-java-0.2.3.4 mysql-connector-java-5.1.18-bin
下面貼一個具體的實現:代碼在github的com.kami.console包下面.
關於最麻煩的Select操做,能夠參考以下:
新建一個繼承了BaseReader的對象,具體如何在本身的DAO用這個工具能夠參考find(TestTable t)的實現,這個find(TestTable t)只是一個例子,無任何實際意義。在這裏面也能夠隨意添加findByXXX的方法。
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.kami.console; import com.kamike.db.SysDbInst; import com.kamike.db.generic.BaseReader; import com.kamike.db.generic.GenericSelect; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author THiNk */ public class TestTableReader extends BaseReader<TestTable> { public TestTableReader(String dbName) { super(dbName); } @Override public GenericSelect<TestTable> createSelect() { return new TestTableSelect(); } @Override public GenericSelect<TestTable> createSelect(TestTable t) { return new TestTableSelect(t); } public long count(T t) { GenericSelect<TestTable> select = createSelect(); ResultSet rs = null; PreparedStatement ps = null; Connection conn = null; long ret = 0; try { conn = SysDbInst.getInstance().getDatabase().getSingleConnection(); ps = conn.prepareStatement(select.countSQL(select.rawSql(dbName)+ "where t.count=? "), ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ps.setLong(1, t.getCount());//這裏的查詢參數的綁定,只能本身動手,豐衣足食了。 rs = ps.executeQuery(); ret = select.count(rs); } catch (Exception e) { ret =0; System.out.println(this.getClass().getName() + e.toString()); } finally { try { if (rs != null) { rs.close(); rs = null; } if (ps != null) { ps.close(); ps = null; } if (conn != null) { conn.close(); conn = null; } } catch (SQLException ex) { Logger.getLogger(BaseReader.class.getName()).log(Level.SEVERE, null, ex); } } return ret; } @Override public ArrayList<TestTable> find(TestTable t) { GenericSelect<TestTable> select = createSelect(); ResultSet rs = null; PreparedStatement ps = null; Connection conn = null; ArrayList<TestTable> ret = null; try { conn = SysDbInst.getInstance().getDatabase().getSingleConnection(); ps = conn.prepareStatement(select.rawSql(dbName) + "where t.count=? ", ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ps.setLong(1, t.getCount());//這裏的查詢參數的綁定,只能本身動手,豐衣足食了。 rs = ps.executeQuery(); ret = select.fetch(rs); } catch (Exception e) { ret = new ArrayList<>(); System.out.println(this.getClass().getName() + e.toString()); } finally { try { if (rs != null) { rs.close(); rs = null; } if (ps != null) { ps.close(); ps = null; } if (conn != null) { conn.close(); conn = null; } } catch (SQLException ex) { Logger.getLogger(BaseReader.class.getName()).log(Level.SEVERE, null, ex); } } return ret; } }
而後是實體對象定義:
/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.kami.console; import com.kamike.db.generic.FieldLength; import com.kamike.db.generic.FieldName; import com.kamike.db.generic.Id; import com.kamike.db.generic.TableName; import java.util.Date; /** * * @author THiNk */ @TableName("test_table") public class TestTable { @Id @FieldName("id") @FieldLength(64) private String id; @FieldName("count") private long count; @FieldName("name") @FieldLength(255) private String name; @FieldName("ready") private boolean ready; @FieldName("create_date") private Date createDate; /** * @return the id */ public String getId() { return id; } /** * @param id the id to set */ public void setId(String id) { this.id = id; } /** * @return the count */ public long getCount() { return count; } /** * @param count the count to set */ public void setCount(long count) { this.count = count; } /** * @return the name */ public String getName() { return name; } /** * @param name the name to set */ public void setName(String name) { this.name = name; } /** * @return the ready */ public boolean isReady() { return ready; } /** * @param ready the ready to set */ public void setReady(boolean ready) { this.ready = ready; } /** * @return the createDate */ public Date getCreateDate() { return createDate; } /** * @param createDate the createDate to set */ public void setCreateDate(Date createDate) { this.createDate = createDate; } }
而後要實現GenericSelect須要的幾個對象new的方法,重載一下GenericSelect。。萬惡的Java半吊子泛型。。
/* * 就寫一個new。。不過兩個構造器,有參的無參的都要這麼實現,還有調用父類的構造器 */ package com.kami.console; import com.kamike.db.generic.GenericSelect; /** * * @author THiNk */ public class TestTableSelect extends GenericSelect<TestTable> { public TestTableSelect(TestTable t) { super(t); } public TestTableSelect() { super(); } @Override public TestTable create() { return new TestTable(); } }
而後就是調用了。
//查詢測試 TestTableReader tts=new TestTableReader("kamike"); TestTable template=new TestTable(); template.setCount(500); ArrayList<TestTable> testList=tts.find(template);