<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          聯(lián)合創(chuàng)作 · 2023-09-30 20:57

              

          1 簡介

          ThinkJD,又名ThinkJDBC,一個(gè)簡潔而強(qiáng)大的開源JDBC操作庫。你可以使用Java像ThinkPHP框架的M方法一樣,一行代碼搞定數(shù)據(jù)庫操作。ThinkJD會(huì)自動(dòng)管理數(shù)據(jù)庫連接,默認(rèn)使用完畢或程序異常都會(huì)關(guān)閉連接以免造成內(nèi)存溢出。也可以設(shè)置手動(dòng)關(guān)閉以復(fù)用Connection連接,無需傳入連接實(shí)例參數(shù),ThinkJD內(nèi)部已做多線程安全處理,詳見【0x0A 多線程安全】。

          特性

          • 核心jar包只有30多KB
          • 支持復(fù)雜SQL語句以及直接執(zhí)行SQL語句
          • 自動(dòng)管理數(shù)據(jù)庫連接
          • 支持增刪改查ORM映射
          • 支持字段注解映射
          • 主鍵、自增、是否ORM字段等屬性配置
          • 動(dòng)態(tài)設(shè)置>注解設(shè)置>全局設(shè)置
          • 數(shù)據(jù)庫連接多線程安全
          • 支持?jǐn)?shù)據(jù)庫連接池
          • 簡易的事務(wù)操作
          • 支持調(diào)試模式,輸出SQL語句
          • 基于DBUtils,Apache出品,底層質(zhì)量有保障

          先睹為快:

          //數(shù)據(jù)庫配置(只需調(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)目主頁

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

          測(cè)試項(xiàng)目

          https://github.com/Leytton/ThinkJD_Demo

          2 使用方法

          0x01 添加依賴

          導(dǎo)入Jar包

          引入ThinkJDBC-x.x.x-core.jar核心庫和以下兩個(gè)依賴庫:

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

          或者

          Maven

          <dependency>
              <groupId>com.llqqww</groupId>
              <artifactId>thinkjdbc</artifactId>
              <version>1.4.4_13</version>
          </dependency>

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

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

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

          (1)配置文件方式

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

          程序第一次啟動(dòng)時(shí)會(huì)自動(dòng)加載讀取配置文件,如果文件不存在則忽略。【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

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

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

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

          例如使用Hikari連接池:

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

          注:如果定義了數(shù)據(jù)庫連接池,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語句(Exception形式)并且不會(huì)執(zhí)行數(shù)據(jù)庫操作。 

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

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

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

          注意:墻裂建議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ù)庫更新 字段隊(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語句如下
           *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語句
          D.M().execute( sql1 [ sql2 , sql3 ... ] );

          0x09 事務(wù)支持

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

          Connection conn=null;
          try {
          	//獲取已開啟事務(wù)的數(shù)據(jù)庫連接
          	conn = D.M().startTrans();
          	//使用事務(wù)連接操作數(shù)據(jù)庫
          	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();
          	}
          }

           

          0x0A 多線程安全

          【V1.4.4_12功能】

          /*設(shè)置數(shù)據(jù)庫操作完畢后不自動(dòng)關(guān)閉
          *此處是為了提高數(shù)據(jù)庫操作性能,不用頻繁地獲取和關(guān)閉連接,同一線程內(nèi)ThinkJD會(huì)使用同一連接;
          *默認(rèn)自動(dòng)關(guān)閉連接的話,每次操作都會(huì)獲取一個(gè)新的Connection,使用完畢立即自動(dòng)關(guān)閉
          */
          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();

          獲取數(shù)據(jù)庫連接處輸出日志為:

          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第一次操作數(shù)據(jù)庫時(shí)conn為空,會(huì)獲取一個(gè)新的conn,下次操作時(shí)conn不為空可以直接使用,直到調(diào)用D.closeConn();后conn才會(huì)關(guān)閉。線程2也是如此。

          3 許可證

          Apache License 2.0 免費(fèi)用于個(gè)人和商業(yè),請(qǐng)放心食用:)

          4 關(guān)于

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

          瀏覽 26
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          編輯 分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  奇米色一区二区三区 | 人妻天天爽 | 国产精品剧情亚洲二区 | 91黄色电影在线观看 | 操操操逼逼逼视频网站 |