ThinkJDBC—一行代碼搞定數(shù)據(jù)庫(kù)操作


版本V1.4.2_10

1 簡(jiǎn)介

ThinkJD,又名ThinkJDBC,一個(gè)簡(jiǎn)潔而強(qiáng)大的開源JDBC操作庫(kù)。你可以使用Java像ThinkPHP框架的M方法一樣,一行代碼搞定數(shù)據(jù)庫(kù)操作。ThinkJD會(huì)自動(dòng)管理數(shù)據(jù)庫(kù)連接,使用完畢或程序異常都會(huì)關(guān)閉連接以免造成內(nèi)存溢出。

先睹為快:

//數(shù)據(jù)庫(kù)配置(只需調(diào)用一次)
D.setDbConfig("jdbc:mysql://127.0.0.1:3306/DbName?characterEncoding=UTF-8","root","root");

//JavaBean模式,自動(dòng)獲取表名、主鍵、自增屬性、字段名和數(shù)據(jù)
User user = new User();
user.setAge(10);
user.setName("Hello");
user.setSex(true);
//插入數(shù)據(jù)
long id=D.M(user).add();
//查詢數(shù)據(jù)
user=D.M(User.class).find(id);
//更新數(shù)據(jù)
user.setSex(false);
D.M(user).field("sex").save();//不指定字段名默認(rèn)更新JavaBean的所有非空屬性
//刪除數(shù)據(jù)
D.M(user).delete();
//D.M(User.class).delete(id);

//Table模式,手動(dòng)指定表名、主鍵、自增屬性、字段名和數(shù)據(jù)
//插入數(shù)據(jù)
long id=D.M("user").field("name,weight").data("Tom",60).add();
//更新數(shù)據(jù)
D.M("user").field("name,weight").data("Tom",100).where("id=?",id).save();
//查詢數(shù)據(jù)
user=D.M(User.class).find(id);
//刪除數(shù)據(jù)
D.M("user").delete(id);

項(xiàng)目主頁(yè) https://gitee.com/Leytton/ThinkJD (碼云) https://github.com/Leytton/ThinkJD (Github)

測(cè)試項(xiàng)目 https://github.com/Leytton/ThinkJD_Demo

2 使用方法

0x01 添加依賴

ThinkJDBC-x.x.x-full.jar 包含了ThinkJDBC-x.x.x-core.jar核心庫(kù)和兩個(gè)依賴庫(kù),只需要添加這一個(gè)jar包就行了

  • mysql-connector-java-5.1.39.jar
  • commons-dbutils-1.6.jar

0x02 定義數(shù)據(jù)庫(kù)

ThinkJD支持直接定義用戶名密碼訪問數(shù)據(jù)庫(kù),也支持使用Hikari、C3P0等數(shù)據(jù)庫(kù)連接池。

數(shù)據(jù)庫(kù)連接方式有三種:

(1)配置文件方式

在項(xiàng)目根目錄下添加文件(跟Hikari配置文件格式一樣)

程序第一次啟動(dòng)時(shí)會(huì)自動(dòng)加載讀取配置文件,如果文件不存在則忽略?!綱1.2.4_5 增加功能】

thinkjdbc.properties

jdbcUrl = jdbc:mysql://127.0.0.1:3306/thinkjdbc?useUnicode=true&characterEncoding=UTF-8
dataSource.user = root
dataSource.password = root

(2)帳號(hào)密碼方式

D.setDbConfig("jdbc:mysql://127.0.0.1:3306/database?useUnicode=true&characterEncoding=UTF-8","root","root");

(3)使用數(shù)據(jù)庫(kù)連接池

例如使用Hikari連接池:

HikariConfig config = new HikariConfig("/hikari.properties");
HikariDataSource dataSource = new HikariDataSource(config);
D.setDataSource(dataSource);

注:如果定義了數(shù)據(jù)庫(kù)連接池,ThinkJD會(huì)優(yōu)先使用。

(3)配置表前綴

只需調(diào)用一次,配置表前綴不是必需的

D.setTablePrefix("jd_");
//D.M('user') D.M(User.class)將會(huì)操作 `jd_user` 表

注:D.M('user').prefix('jd_')方法可單獨(dú)指定表前綴【V1.2.3新增】

0x03 連貫操作

操作 參數(shù) 示例 說明
table table(String table) table("user")
pk pk(String key) pk("id")
autoInc autoInc(boolean isPkAutoInc) autoInc(false)
join join(String join) join("left join machine on user.id=user_id and machine_status=1")
field field(String filed) field("id,username")
data data(Object... dataParam) data(11,"Leytton")
setInc setInc(String key,long num) setInc("gold",5) //gold=gold+5
setDec setDec(String key,long num) setDec("gold",5) //gold=gold-5
where ①where(String where)
②where(String where, Object... whereParam)
①where("id=1111 and username='Leytton'")
②where("id=? and username=?",1111,"Leytton")
group group(String group) group("type")
having having(String having) having("id>1234")
order order(String order) order("id desc")
asc asc(String key) asc("id")
desc desc(String key) desc("id")
page page(long page, long rows) page(1,10)
limit ①limit(long rows)
②limit(long offset, long rows)
①limit(10)
②limit(1,10)
union union(String union,Boolean isAll) ①union("select * from user_two where id>1234",false)
②union("select * from user_two where id>1234",true)

0x04 查詢數(shù)據(jù)

操作 參數(shù) 說明
select ①<T> List<T> select()
②<T> List<T> select(String key, Object value)
find ①<T> T find()
②<T> T find(Object value)
③<T> T find(String key, Object value)
count ①long count()
②long count(String field)
max double max(String field)
min double min(String field)
avg double avg(String field)
sum double sum(String field)
//find查詢
//select id,name from jd_user where id>4 order by id asc limit 0,1
User res = D.M(User.class).field("id,name").where("id>?",4).order("id asc").find();

//find 根據(jù)id查詢
//select * from jd_user where id=3 limit 0,1
User user = D.M(User.class).find(3);

//find根據(jù)字段查詢
//select * from jd_user where name='Tom' limit 0,1
User user=D.M(User.class).fetchSql(true).find("name","Bob");

//where,field過濾
//select id,name,weight from jd_user where id>3
List<User> res = D.M(User.class).field("id,name,weight").where("id>3").select();

//group分組查詢
//select sex,sum(weight) as weight,avg(age) as age,count(id) as num from jd_user where id>5 group by sex order by sex desc limit 0,10
res = D.M(User.class).field("sex,sum(weight) as weight,avg(age) as age,count(id) as num").where("id>?",5).group("sex").order("sex desc").page(1, 10).select();

//join聯(lián)表查詢
//select jd_user.id,name,weight,sum(gold) as num from jd_user left join jd_gold on user_id=jd_user.id where jd_user.id>3 group by jd_user.id
res = D.M(User.class).field("jd_user.id,name,weight,sum(gold) as num").join("left join jd_gold on user_id=jd_user.id").where("jd_user.id>3").group("jd_user.id").select();

//union聯(lián)表查詢
//(select id,name from jd_user where id=4 ) union all (select id,name from jd_user where id<3) union (select id,name from jd_user where id=3)
res = D.M(User.class).field("id,name").where("id=4").union("select id,name from jd_user where id<3",true)
    .union("select id,name from jd_user where id=3",false).select();

//統(tǒng)計(jì)查詢
long num= new M(User.class).where("id>3").count();
num= D.M(User.class).fetchSql(true).where("id>3").count("id");
num= (long) D.M(User.class).fetchSql(false).where("id<0").max("id");
num= (long) D.M(User.class).where("id<3").max("id");
num= (long) D.M(User.class).min("id");
num= (long) D.M(User.class).where("id>3").min("id");
num= (long) D.M(User.class).fetchSql(false).where("id>3").avg("id");
double avg= D.M(User.class).fetchSql(false).where("id>3").avg("id");
num= (long) D.M(User.class).where("id>13441").sum("age");

通過調(diào)用fetchSql(true)方法,可以獲取到 ThinkJD產(chǎn)生的SQL語(yǔ)句(Exception形式)并且不會(huì)執(zhí)行數(shù)據(jù)庫(kù)操作。

fetchSql

user表結(jié)構(gòu):

字段名 數(shù)據(jù)類型 備注
id int 用戶id,自增長(zhǎng)主鍵
name varchar 用戶名
age tinyint 年齡
weight float 體重
sex tinyint 性別 0女/1男
time int 時(shí)間

select()find()查詢結(jié)果封裝到JavaBean里返回,JavaBean可使用注解映射數(shù)據(jù)庫(kù)字段。

注意:墻裂建議JavaBean字段基礎(chǔ)數(shù)據(jù)類型使用【Integer、Long、Boolean、Float、Double、Byte、Short、Char】不要使用【integer、long、boolean、float、double、byte、short、char】,因?yàn)榍罢呖梢再x值為null而后者不行(null時(shí)為0),所以獲取到的值是不準(zhǔn)確的。ThinkJD的save更新等操作通過判斷屬性值不為null則加入數(shù)據(jù)庫(kù)更新字段隊(duì)列。ThinkJD會(huì)自動(dòng)檢測(cè)以上不符合的數(shù)據(jù)類型并發(fā)出警告。如需關(guān)閉調(diào)用D.setCheckField(false);

//@Table(name="user")默認(rèn)類名為表名,可注解重定義
public class User {
    //@Column(isKey=true)默認(rèn)id為主鍵、isAutoInc=true自增,可注解重定義
    private Long id;
    private Integer age;
    //@Column(name="user_name")默認(rèn)屬性名為表字段,可注解重定義
    private String name;
    private Float weight;
    private Boolean sex;
    
    @Column(isColumn=false)
    private Integer num;
    
    private Long time;
    
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Float getWeight() {
        return weight;
    }
    public void setWeight(Float weight) {
        this.weight = weight;
    }
    public Boolean getSex() {
        return sex;
    }
    public void setSex(Boolean sex) {
        this.sex = sex;
    }
    public Integer getNum() {
        return num;
    }
    public void setNum(Integer num) {
        this.num = num;
    }
    public Long getTime() {
        return time;
    }
    public void setTime(Long time) {
        this.time = time;
    }
}

0x05 插入數(shù)據(jù)

操作 參數(shù) 說明
add long add() Table模式前提方法:data()
返回自動(dòng)生成的主鍵值;
/*指定插入字段*/
long id=D.M(User.class).field("name,weight").data("Tom",60).add();

/*不指定插入字段,按表字段順序插入*/
id=D.M("user").data(null,"Tom",60,...).add();

/*使用javaBean半自動(dòng)模式,自動(dòng)獲取表名、主鍵、字段名,給定data按javaBean屬性順序插入,生成的sql語(yǔ)句如下
 *insert into jd_user (age,name,weight,sex,time) values(?,?,?,...)
 */
id=D.M(User.class).data("Tom",60,...).add();

//使用javaBean全自動(dòng)模式,自動(dòng)獲取表名、主鍵、字段名和數(shù)據(jù)
User user = new User();
user.setId(5);
user.setAge(10);
user.setName("Hello");

//insert into jd_user (age,name) values(?,?) Params[10,Hello]
num=D.M(user).add();

//insert into jd_user (name) values(?) Params[Hello]
num=D.M(user).field("name").add();

//insert into jd_user (id,age,name) values(?,?,?) Params[5,10,Hello]
num=D.M(user).autoInc(false).add();

0x06 更新數(shù)據(jù)

操作 參數(shù) 說明
save long save() Table模式前提方法:data(),where();
返回執(zhí)行生效行數(shù)
long num=D.M("user").field("name,weight").data("Mike",100).where("id=?",1234).save();
User user = new User();
user.setId(5);
user.setAge(10);
user.setName("Hello");

//update jd_user set age=?,name=? where id=?; Params[10,Hello,5]
num=D.M(user).save();

//update jd_user set name=? where id=?; Params[Hello,5]
num=D.M(user).field("name").save();

//update jd_user set id=?,age=?,name=? where id=?; Params[5,10,Hello,4]
id=D.M(user).autoInc(false).fetchSql(true).where("id=?",user.getId()-1).save();

0x07 刪除數(shù)據(jù)

操作 參數(shù) 說明
delete long delete() Table模式前提方法:where()
返回執(zhí)行生效行數(shù)

注:為防止誤刪除,where條件不能為空。

long num=D.M("user").delete(5);//默認(rèn)為id=?
num=D.M("user").delete("time",1523681398);//time=?
num=D.M(User.class).where("id>=?",13421).delete();

//JavaBean模式
User user=new User();
user.setId(10L);
long num=D.M(user).delete();

0x08 執(zhí)行SQL

操作 參數(shù) 說明
execute void execute(String... sqls) 直接執(zhí)行SQL語(yǔ)句
D.M().execute( sql1 [ sql2 , sql3 ... ] );

0x09 事務(wù)支持

數(shù)據(jù)庫(kù)表引擎應(yīng)該為InnoDB以支持事務(wù)操作。
代碼示例:

Connection conn=null;
try {
    //獲取已開啟事務(wù)的數(shù)據(jù)庫(kù)連接
    conn = D.M().startTrans();
    //使用事務(wù)連接操作數(shù)據(jù)庫(kù)
    long id=new M("gold").trans(conn).field("user_id,gold,type,time").data(3,5,0,System.currentTimeMillis()/1000).add();
    System.out.println(id);
    if(id>0) {
        throw new SQLException("Transaction Rollback Test");
    }
    id=new M("gold").trans(conn).field("user_id,gold,type,time").data(3,5,0,System.currentTimeMillis()/1000).add();
    System.out.println(id);
    //提交事務(wù)
    D.M().commit(conn);
} catch (SQLException e) {
    e.printStackTrace();
    try {
        //事務(wù)回滾
        D.M().rollback(conn);
    } catch (SQLException e1) {
        e1.printStackTrace();
    }
}

3 許可證

Apache License 2.0

4 關(guān)于

如果喜歡的話,請(qǐng)點(diǎn)個(gè)贊讓我知道哦~在找到比它用得更順手的JDBC庫(kù)之前,這個(gè)項(xiàng)目會(huì)持續(xù)更新。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,654評(píng)論 19 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,281評(píng)論 6 342
  • 你偷偷地潛入我的城池 我緩緩地解開那把枷鎖 從這座城池逃到那座城池 ...
    守時(shí)閱讀 443評(píng)論 10 4
  • 今天寶貝兒又和我生氣了,因?yàn)樗x書字讀錯(cuò)了。我說你讀錯(cuò)了,就生氣了不讓我看他的書了。
    我想要的你不懂閱讀 191評(píng)論 0 0
  • Block 代碼塊本質(zhì)上是和變量類似,不同的是,代碼塊存儲(chǔ)的數(shù)據(jù)是一個(gè)函數(shù)體.使用代碼塊是,可以有參數(shù)和返回值.你...
    俊月閱讀 353評(píng)論 0 3

友情鏈接更多精彩內(nèi)容