41 Star 104 Fork 17

Leytton / ThinkJD

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

ThinkJDBC

最新版本 中文文档 English Document Maven CSDN Blog

1 简介

ThinkJD,又名ThinkJDBC,一个简洁而强大的开源JDBC操作库。你可以使用Java像ThinkPHP框架的M方法一样,一行代码搞定数据库操作。ThinkJD会自动管理数据库连接,默认使用完毕或程序异常都会关闭连接以免造成内存溢出。也可以设置手动关闭以复用Connection连接,无需传入连接实例参数,ThinkJD内部已做多线程安全处理,详见【0x0A 多线程安全】

特性

  • 核心jar包只有19KB
  • 支持复杂SQL语句以及直接执行SQL语句
  • 自动管理数据库连接
  • 支持增删改查ORM映射
  • 支持字段注解映射
  • 主键、自增、是否ORM字段等属性配置
  • 动态设置>注解设置>全局设置
  • 数据库连接多线程安全
  • 支持数据库连接池
  • 简易的事务操作
  • 支持调试模式,输出SQL语句
  • 基于DBUtils,Apache出品,底层质量有保障

先睹为快:

//数据库配置(只需调用一次)
D.setDbConfig("jdbc:mysql://127.0.0.1:3306/DbName?characterEncoding=UTF-8","root","root");

//JavaBean模式,自动获取表名、主键、自增属性、字段名和数据
User user = new User();
user.setAge(10);
user.setName("Hello");
user.setSex(true);
//插入数据
long id=D.M(user).add();
//查询数据
user=D.M(User.class).find(id);
//更新数据
user.setSex(false);
D.M(user).field("sex").save();//不指定字段名默认更新JavaBean的所有非空属性
//删除数据
D.M(user).delete();
//D.M(User.class).delete(id);

//Table模式,手动指定表名、主键、自增属性、字段名和数据
//插入数据
long id=D.M("user").field("name,weight").data("Tom",60).add();
//更新数据
D.M("user").field("name,weight").data("Tom",100).where("id=?",id).save();
//查询数据
user=D.M(User.class).find(id);
//删除数据
D.M("user").delete(id);

项目主页

https://gitee.com/Leytton/ThinkJD (码云) https://github.com/Leytton/ThinkJD (Github)

测试项目

https://github.com/Leytton/ThinkJD_Demo

2 使用方法

0x01 添加依赖

导入Jar包

引入ThinkJDBC-x.x.x.jar库和commons-dbutils-1.6.jar依赖库:

或者

Maven

<dependency>
    <groupId>com.llqqww</groupId>
    <artifactId>thinkjdbc</artifactId>
    <version>1.4.5_16</version>
</dependency>

此外记得添加你要操作的数据库依赖库,如mysql-connector-javaojdbcsqljdbc

0x02 定义数据库

ThinkJD支持直接定义用户名密码访问数据库,也支持使用Hikari、C3P0等数据库连接池。

数据库连接方式有三种:

(1)配置文件方式

在项目根目录下添加文件(跟Hikari配置文件格式一样)

程序第一次启动时会自动加载读取配置文件,如果文件不存在则忽略。【V1.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
dataSource.driverClassName=com.mysql.jdbc.Driver

(2)帐号密码方式

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

默认驱动名是 com.mysql.jdbc.Driver,即默认操作MySQL数据库,若使用的是其他数据库则可以修改驱动路径

D.setDbConfig(new DbConfig(dbUrl, dbUser, dbPassword, driverName));

(3)使用数据库连接池

例如使用Hikari连接池:

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

注:如果定义了数据库连接池,ThinkJD会优先使用。

(3)配置表前缀

只需调用一次,配置表前缀不是必需的

D.setTablePrefix("jd_");
//D.M('user') D.M(User.class)将会操作 `jd_user` 表

注:D.M('user').prefix('jd_')方法可单独指定表前缀【V1.2.3新增】

0x03 连贯操作

操作 参数 示例 说明
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 查询数据

操作 参数 说明
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 根据id查询
//select * from jd_user where id=3 limit 0,1
User user = D.M(User.class).find(3);

//find根据字段查询
//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联表查询
//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联表查询
//(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();

//统计查询
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");

通过调用fetchSql(true)方法,可以获取到 ThinkJD产生的SQL语句(Exception形式)并且不会执行数据库操作。 fetchSql

user表结构:

字段名 数据类型 备注
id int 用户id,自增长主键
name varchar 用户名
age tinyint 年龄
weight float 体重
sex tinyint 性别 0女/1男
time int 时间

select()find()查询结果封装到JavaBean里返回,JavaBean可使用注解映射数据库字段。

注意:墙裂建议JavaBean字段基础数据类型用【Integer、Long、Boolean、Float、Double、Byte、Short、Char】 不要使用【integer、long、boolean、float、double、byte、short、char】,因为前者可以赋值为null而后者不行(null时为0),所以获取到的值是不准确的。ThinkJD的save更新等操作通过判断属性值不为null则加入数据库更新 字段队列。ThinkJD会自动检测以上不符合的数据类型并发出警告。如需关闭调用D.setCheckField(false);

//@Table(name="user")默认类名为表名,可注解重定义
public class User {
	//@Column(isKey=true)默认id为主键、isAutoInc=true自增,可注解重定义
	private Long id;
	private Integer age;
	//@Column(name="user_name")默认属性名为表字段,可注解重定义
	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 插入数据

操作 参数 说明
add long add() Table模式前提方法:data()
返回自动生成的主键值;
/*指定插入字段*/
long id=D.M(User.class).field("name,weight").data("Tom",60).add();

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

/*使用javaBean半自动模式,自动获取表名、主键、字段名,给定data按javaBean属性顺序插入,生成的sql语句如下
 *insert into jd_user (age,name,weight,sex,time) values(?,?,?,...)
 */
id=D.M(User.class).data("Tom",60,...).add();

//使用javaBean全自动模式,自动获取表名、主键、字段名和数据
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 更新数据

操作 参数 说明
save long save() Table模式前提方法:data(),where();
返回执行生效行数
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 删除数据

操作 参数 说明
delete long delete() Table模式前提方法:where()
返回执行生效行数

注:为防止误删除,where条件不能为空。

long num=D.M("user").delete(5);//默认为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 执行SQL

操作 参数 说明
execute void execute(String... sqls) 直接执行SQL语句
D.M().execute( sql1 [ sql2 , sql3 ... ] );

0x09 事务支持

数据库表引擎应该为InnoDB以支持事务操作。 代码示例:

Connection conn=null;
try {
	//获取已开启事务的数据库连接
	conn = D.M().startTrans();
	//使用事务连接操作数据库
	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);
	//提交事务
	D.M().commit(conn);
} catch (SQLException e) {
	e.printStackTrace();
	try {
		//事务回滚
		D.M().rollback(conn);
	} catch (SQLException e1) {
		e1.printStackTrace();
	}
}

0x0A 多线程安全

【V1.4.4_12功能】

/*设置数据库操作完毕后不自动关闭
*此处是为了提高数据库操作性能,不用频繁地获取和关闭连接,同一线程内ThinkJD会使用同一连接;
*默认自动关闭连接的话,每次操作都会获取一个新的Connection,使用完毕立即自动关闭
*/
D.setAutoClose(false);
new Thread(new Runnable() {	
	@Override
	public void run() {
		Gold gold = new Gold();
		gold.setUser_id(1L);
		gold.setGold(5);
		gold.setGold_type(0);
		try {
			D.M(gold).add();
			D.M(gold).add();
		} catch (SQLException e) {
			D.closeConn();
			e.printStackTrace();
		}
	}
}, "Thread_1").start();

new Thread(new Runnable() {
	
	@Override
	public void run() {
		Gold gold = new Gold();
		gold.setUser_id(2L);
		gold.setGold(5);
		gold.setGold_type(0);
		try {
			D.M(gold).add();
			D.M(gold).add();
		} catch (SQLException e) {
			D.closeConn();
			e.printStackTrace();
		}
	}
}, "Thread_2").start();

获取数据库连接处输出日志为:

Thread:Thread_1,conn==null:true
Thread:Thread_2,conn==null:true
Thread:Thread_2,conn==null:false
Thread:Thread_1,conn==null:false

由此可见,线程1第一次操作数据库时conn为空,会获取一个新的conn,下次操作时conn不为空可以直接使用,直到调用D.closeConn();后conn才会关闭。线程2也是如此。

3 许可证

Apache License 2.0 免费用于个人和商业,请放心食用:)

4 关于

如果喜欢的话,请点个赞让我知道哦~在找到比它用得更顺手的JDBC库之前,这个项目会持续更新。

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [2018] [Leytton] Licensed 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.

简介

ThinkJD,又名ThinkJDBC,一个强大的开源JDBC/ORM操作库,让你尽可能简洁地用一行代码搞定数据库操作。 展开 收起
Java
Apache-2.0
取消

发行版 (6)

全部

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/Leytton/ThinkJD.git
git@gitee.com:Leytton/ThinkJD.git
Leytton
ThinkJD
ThinkJD
master

搜索帮助