資料介紹
軟件簡介
dbVisitor(原 HasorDB)是一個全功能數(shù)據(jù)庫訪問工具,提供對象映射、豐富的類型處理、動態(tài)SQL、存儲過程、 內(nèi)置分頁方言20+、 支持嵌套事務(wù)、多數(shù)據(jù)源、條件構(gòu)造器、INSERT 策略、多語句/多結(jié)果。并兼容 Spring 及 MyBatis 用法。 它不依賴任何其它框架,因此可以很方便的和任意一個框架整合在一起使用。
功能特性?
- 熟悉的方式
-
事務(wù)支持
- 支持 5 個事務(wù)隔離級別、7 個事務(wù)傳播行為(與 Spring tx 相同)
- 提供 TransactionTemplate、TransactionManager 接口方式聲明式事務(wù)控制能力(用法與 Spring 相同)
-
特色優(yōu)勢
- 支持 分頁查詢 并且提供多種數(shù)據(jù)庫方言(20+)
- 支持 INSERT 策略(INTO、UPDATE、IGNORE)
- 更加豐富的 TypeHandler(MyBatis 40+,dbVisitor 60+)
- Mapper XML 支持多語句、多結(jié)果
- 提供獨特的規(guī)則機制,讓動態(tài) SQL 更加簡單
- 支持 存儲過程
- 支持 JDBC 4.2 和 Java8 中時間類型
- 支持多數(shù)據(jù)源
引入依賴
<dependency>
<groupId>net.hasor<groupId>
<artifactId>dbvisitor<artifactId>
<version>5.0.1<version>
dependency>
然后再引入數(shù)據(jù)庫驅(qū)動以 MySQL,Maven 方式為例:
<dependency>
<groupId>mysql<groupId>
<artifactId>mysql-connector-java<artifactId>
<version>8.0.22<version>
dependency>
使用 dbVisitor?可以不依賴數(shù)據(jù)庫連接池,但有數(shù)據(jù)庫連接池是大多數(shù)項目的標(biāo)配。這里選用 Alibaba 的 Druid
<dependency>
<groupId>com.alibaba<groupId>
<artifactId>druid<artifactId>
<version>1.1.23<version>
dependency>
最后準(zhǔn)備一個數(shù)據(jù)庫表,并初始化一些數(shù)據(jù)(CreateDB.sql
文件)
drop table if exists `test_user`;
create table `test_user` (
`id` int(11) auto_increment,
`name` varchar(255),
`age` int,
`create_time` datetime,
primary key (`id`)
);
insert into `test_user` values (1, 'mali', 26, now());
insert into `test_user` values (2, 'dative', 32, now());
insert into `test_user` values (3, 'jon wes', 41, now());
insert into `test_user` values (4, 'mary', 66, now());
insert into `test_user` values (5, 'matt', 25, now());
執(zhí)行 SQL?
使用 SQL 的方式讀取數(shù)據(jù),PrintUtils
和 DsUtils
兩個工具類可以在例子工程中找到
// 創(chuàng)建數(shù)據(jù)源
DataSource dataSource = DsUtils.dsMySql();
// 創(chuàng)建 JdbcTemplate 對象
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// 加載測試數(shù)據(jù)腳本
jdbcTemplate.loadSQL("CreateDB.sql");
// 查詢數(shù)據(jù)并 Map 形式返回
List<Map<String, Object>> mapList = jdbcTemplate.queryForList("select * from test_user");
// 打印測試數(shù)據(jù)
PrintUtils.printMapList(mapList);
控制臺可以得到如下結(jié)果
/--------------------------------------------\\
| id | name | age | create_time |
|--------------------------------------------|
| 1 | mali | 26 | 2021-11-12 19:14:06.0 |
| 2 | dative | 32 | 2021-11-12 19:14:06.0 |
| 3 | jon wes | 41 | 2021-11-12 19:14:06.0 |
| 4 | mary | 66 | 2021-11-12 19:14:06.0 |
| 5 | matt | 25 | 2021-11-12 19:14:06.0 |
\\--------------------------------------------/
如果想使用 DTO 對象接收數(shù)據(jù),則需要創(chuàng)建一個 DTO 對象。
// 如果屬性名和列名可以完全匹配,那么無需任何注解。
// - 本列中由于 `test_user` 的表名和列名符合駝峰轉(zhuǎn)下劃線,那么可以簡單的通過 @Table 注解聲明一下。
// - 如果需要映射表名和列名請參照注解 @Table、@Column 更多的屬性
@Table(mapUnderscoreToCamelCase = true)
public class TestUser {
private Integer id;
private String name;
private Integer age;
private Date createTime;
// getters and setters omitted
}
// 然后通過 `queryForList` 方法直接查詢,控制臺就可以得到相同的結(jié)果
String sqlString = "select * from test_user";
List<TestUser> dtoList = jdbcTemplate.queryForList(sqlString, TestUser.class);
PrintUtils.printObjectList(dtoList);
單表 CRUD
JdbcTemplate
的子類 LambdaTemplate
// 創(chuàng)建數(shù)據(jù)源
DataSource dataSource = DsUtils.dsMySql();
// 創(chuàng)建 LambdaTemplate 對象和創(chuàng)建 JdbcTemplate 一樣
LambdaTemplate lambdaTemplate = new LambdaTemplate(dataSource);
// 初始化一些數(shù)據(jù)
lambdaTemplate.loadSQL("CreateDB.sql");
// 查詢,所有數(shù)據(jù)
List<TestUser> dtoList = lambdaTemplate.lambdaQuery(TestUser.class)
.queryForList();
PrintUtils.printObjectList(dtoList);
// 插入新數(shù)據(jù)
TestUser newUser = new TestUser();
newUser.setName("new User");
newUser.setAge(33);
newUser.setCreateTime(new Date());
int result = lambdaTemplate.lambdaInsert(TestUser.class)
.applyEntity(newUser)
.executeSumResult();
// 更新,將name 從 mali 更新為 mala
TestUser sample = new TestUser();
sample.setName("mala");
int result = lambdaTemplate.lambdaUpdate(TestUser.class)
.eq(TestUser::getId, 1)
.updateToBySample(sample)
.doUpdate();
// 刪除,ID 為 2 的數(shù)據(jù)
int result = lambdaTemplate.lambdaUpdate(TestUser.class)
.eq(TestUser::getId, 1)
.updateToBySample(sample)
.doUpdate();
使用 DAO?
使用 DAO 可以繼承 BaseMapper
通用 DAO 接口來完成一些基本操作,仍然以單表 CRUD 為例。
// DAO 的一些接口需要識別 ID 屬性,因此有必要在 DTO 對象上通過 @Column 注解標(biāo)記出它們
@Table(mapUnderscoreToCamelCase = true)
public class TestUser {
@Column(primary = true)
private Integer id;
private String name;
private Integer age;
private Date createTime;
// getters and setters omitted
}
// 創(chuàng)建數(shù)據(jù)源
DataSource dataSource = DsUtils.dsMySql();
// 創(chuàng)建通用 DAO
DalSession session = new DalSession(dataSource);
BaseMapper<TestUser> baseMapper = session.createBaseMapper(TestUser.class);
// 初始化一些數(shù)據(jù)
baseMapper.template().loadSQL("CreateDB.sql");
// 查詢數(shù)據(jù)
List<TestUser> dtoList = baseMapper.query().queryForList();
PrintUtils.printObjectList(dtoList);
// 插入新數(shù)據(jù)
TestUser newUser = new TestUser();
newUser.setName("new User");
newUser.setAge(33);
newUser.setCreateTime(new Date());
int result = baseMapper.insert(newUser);
// 更新,將name 從 mali 更新為 mala
TestUser sample = baseMapper.queryById(1);
sample.setName("mala");
int result = baseMapper.updateById(sample);
// 刪除,ID 為 2 的數(shù)據(jù)
int result = baseMapper.deleteById(2);
作為 DAO 可以定義自己的方法,并通過注解配置具體執(zhí)行的 SQL 語句。
// BaseMapper 是可選的,繼承它相當(dāng)于多了一組單表 CURD 的擴展功能。
@SimpleMapper
public interface TestUserDAO extends BaseMapper<TestUser> {
@Insert("insert into `test_user` (name,age,create_time) values (#{name}, #{age}, now())")
public int insertUser(@Param("name") String name,
@Param("age") int age);
@Update("update `test_user` set age = #{age} where id = #{id}")
public int updateAge(@Param("id") int userId,
@Param("age") int newAge);
@Delete("delete from `test_user` where age > #{age}")
public int deleteByAge(@Param("age") int age);
@Query(value = "select * from `test_user` where #{beginAge} < age and age < #{endAge}",
resultType = TestUser.class)
public List<TestUser> queryByAge(@Param("beginAge") int beginAge,
@Param("endAge") int endAge);
}
// 創(chuàng)建 DalRegistry 并注冊 TestUserDAO
DalRegistry dalRegistry = new DalRegistry();
dalRegistry.loadMapper(TestUserDAO.class);
// 使用 DalRegistry 創(chuàng)建 Session
DalSession session = new DalSession(dataSource, dalRegistry);
// 創(chuàng)建 DAO 接口
TestUserDAO userDAO = session.createMapper(TestUserDAO.class);
使用 Mapper?
統(tǒng)一管理 SQL 的最佳場所仍然是 Mapper 文件,而且 dbVisitor?的 Mapper 文件高度兼容 MyBatis 學(xué)習(xí)成本極低。
// 利用 @RefMapper 注解將 Mapper 文件和 接口類聯(lián)系起來(繼承 BaseMapper 是可選的)
@RefMapper("/mapper/quick_dao3/TestUserMapper.xml")
public interface TestUserDAO extends BaseMapper<TestUser> {
public int insertUser(@Param("name") String name,
@Param("age") int age);
public int updateAge(@Param("id") int userId,
@Param("age") int newAge);
public int deleteByAge(@Param("age") int age);
public List<TestUser> queryByAge(@Param("beginAge") int beginAge,
@Param("endAge") int endAge);
}
為了更好了解和使用 dbVisitor?的 Mapper 文件建議增加 DTD加以驗證。另外 HasorDB 兼容 MyBatis3 的 DTD 對于絕大部分 MyBatis 工程都可以正常兼容。
DOCTYPE mapper PUBLIC "-//dbvisitor.net//DTD Mapper 1.0//EN"
"https://www.dbvisitor.net/schema/dbvisitor-mapper.dtd">
<mapper namespace="net.hasor.db.example.quick.dao3.TestUserDAO">
<resultMap id="testuser_resultMap" type="net.hasor.db.example.quick.dao3.TestUser">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="create_time" property="createTime"/>
resultMap>
<sql id="testuser_columns">
name,age,create_time
sql>
<insert id="insertUser">
insert into `test_user` (
<include refid="testuser_columns"/>
) values (
#{name}, #{age}, now()
)
insert>
<update id="updateAge">
update `test_user` set age = #{age} where id = #{id}
update>
<delete id="deleteByAge">
delete from `test_user` where age > #{age}
]]>delete>
<select id="queryByAge" resultMap="testuser_resultMap">
select id,<include refid="testuser_columns"/>
from `test_user`
where #{beginAge} < age and age < #{endAge}
select>
mapper>
快速條件拼接?
快速條件拼接包含 快速'與'條件
和 快速'或'條件
它們是兩個規(guī)則用于取代簡單的 if
標(biāo)簽和簡單的 foreach
標(biāo)簽。如下語句,當(dāng)參數(shù)不為空時候才拼接 sql
<select id="queryUser">
select * from `test_user`
where 1=1
<if test="age != null">
and age = #{age}
if>
select>
可以簡化為快速規(guī)則寫法,其中 :age
為屬性名。
<select id="queryUser">
select * from `test_user`
@{and, age = :age}
select>
例如如下 foreach
操作:
<select id="queryUser">
select * from `test_user`
where
id in <foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
foreach>
select>
可以簡化為快速規(guī)則寫法,其中 :list
為集合屬性名。
<select id="queryUser">
select * from `test_user`
@{and, id in (:list)}
select>
如果多個簡單條件,快速寫法將會極大的減少 Mapper 的工作量。
<select id="queryByNameAndAge">
select * from `test_user`
@{and, age = :age}
@{and, name = :name}
@{and, id in (:ids)}
select>
分頁查詢?
dbVisitor?的分頁能力僅在 LambdaTemplate
、BaseMapper
、Mapper DAO
三個層面上受到支持。下面為不同的使用方式:
使用 LambdaTemplate
進行分頁查詢
// 構(gòu)造 LambdaTemplate 和初始化一些數(shù)據(jù)
DataSource dataSource = DsUtils.dsMySql();
LambdaTemplate lambdaTemplate = new LambdaTemplate(dataSource);
lambdaTemplate.loadSQL("CreateDB.sql");
// 構(gòu)建分頁對象,每頁 3 條數(shù)據(jù)(默認(rèn)第一頁的頁碼為 0)
Page pageInfo = new PageObject();
pageInfo.setPageSize(3);
// 分頁查詢數(shù)據(jù)
List<TestUser> pageData1 = lambdaTemplate.lambdaQuery(TestUser.class)
.usePage(pageInfo)
.queryForList();
// 分頁查詢下一頁數(shù)據(jù)
pageInfo.nextPage();
List<TestUser> pageData2 = lambdaTemplate.lambdaQuery(TestUser.class)
.usePage(pageInfo)
.queryForList();
用接口 BaseMapper
進行分頁查詢
// 構(gòu)造 BaseMapper 和初始化一些數(shù)據(jù)
DataSource dataSource = DsUtils.dsMySql();
DalSession session = new DalSession(dataSource);
BaseMapper<TestUser> baseMapper = session.createBaseMapper(TestUser.class);
baseMapper.template().loadSQL("CreateDB.sql");
// 構(gòu)建分頁對象,每頁 3 條數(shù)據(jù)(默認(rèn)第一頁的頁碼為 0)
Page pageInfo = new PageObject();
pageInfo.setPageSize(3);
// 分頁查詢數(shù)據(jù)
PageResult<TestUser> pageData1 = baseMapper.pageBySample(null, pageInfo);
// 分頁查詢下一頁數(shù)據(jù)
pageInfo.nextPage();
PageResult<TestUser> pageData2 = baseMapper.pageBySample(null, pageInfo);
若想分頁查詢 Mapper 文件中的查詢,僅需在對應(yīng) DAO 接口方法中增加一個 Page 參數(shù)即可。
@RefMapper("/mapper/quick_page3/TestUserMapper.xml")
public interface TestUserDAO extends BaseMapper<TestUser> {
// 可以直接返回分頁之后的數(shù)據(jù)結(jié)果
public List<TestUser> queryByAge(@Param("beginAge") int beginAge,
@Param("endAge") int endAge,
Page pageInfo);
// 也可以返回包含分頁信息的分頁結(jié)果
public List<TestUser> queryByAge(@Param("beginAge") int beginAge,
@Param("endAge") int endAge,
Page pageInfo);
}
// 構(gòu)建分頁條件
Page pageInfo = new PageObject();
pageInfo.setPageSize(3);
// 分頁方式查詢 mapper 中的查詢
List<TestUser> data1 = userDAO.queryByAge(25, 100, pageInfo);
PageResult<TestUser> page1 = userDAO.queryByAge2(25, 100, pageInfo);
// 分頁方式查詢 mapper 中的查詢
pageInfo.nextPage();
List<TestUser> data2 = userDAO.queryByAge(25, 100, pageInfo);
PageResult<TestUser> page2 = userDAO.queryByAge2(25, 100, pageInfo);
使用事務(wù)?
dbVisitor?提供了兩種方式使用事務(wù),分別為:
-
聲明式事務(wù),通過調(diào)用
TransactionManager
接口來實現(xiàn)事務(wù)控制。 -
模版事務(wù),通過
TransactionTemplate
接口來實現(xiàn)事務(wù)控制。
聲明式事務(wù)?
啟動和遞交一個事務(wù),例如:
DataSource dataSource = DsUtils.dsMySql();
TransactionManager manager = DataSourceManager.getManager(dataSource);
TransactionStatus tranA = manager.begin();
...
manager.commit(tranA);
或者使用快捷方式
DataSource dataSource = DsUtils.dsMySql();
TransactionManager manager = DataSourceManager.getManager(dataSource);
manager.begin(); // 開啟一個事務(wù)
...
manager.commit(); //遞交最近的一個事務(wù)
啟動和遞交多個事務(wù),例如:
DataSource dataSource = DsUtils.dsMySql();
TransactionManager manager = DataSourceManager.getManager(dataSource);
TransactionStatus tranA = manager.begin();
TransactionStatus tranB = manager.begin();
TransactionStatus tranC = manager.begin();
...
manager.commit(tranC);
manager.commit(tranB);
manager.commit(tranA);
通過 begin
方法的參數(shù)可以設(shè)置事務(wù)的 傳播屬性 和 隔離級別
TransactionStatus tranA = manager.begin(
Propagation.REQUIRES_NEW, // 傳播屬性
Isolation.READ_COMMITTED // 隔離級別
);
模版事務(wù)?
使用模版事務(wù)的方式為:
Object result = template.execute(new TransactionCallback<Object>() {
@Override
public Object doTransaction(TransactionStatus tranStatus) throws Throwable {
...
return null;
}
});
// 使用 Java8 Lambda 語法可以簡化為下面這種
Object result = template.execute(tranStatus -> {
return ...;
});
在事務(wù)模版中拋出異常會導(dǎo)致事務(wù)回滾,同時異常會繼續(xù)上拋:
try {
Object result = template.execute(new TransactionCallback<Object>() {
public Object doTransaction(TransactionStatus tranStatus) throws Throwable {
throw new Exception("...");
}
});
} catch (Throwable e) {
... run here
}
也可以設(shè)置事務(wù)狀態(tài)為 rollBack
或 readOnly
也會導(dǎo)致回滾
Object result = template.execute(new TransactionCallback<Object>() {
public Object doTransaction(TransactionStatus tranStatus) throws Throwable {
tranStatus.setReadOnly();
// 或
tranStatus.setRollback();
return ...;
}
});
沒有返回值的模版事務(wù),需要用到 TransactionCallbackWithoutResult
接口。具體用法如下:
template.execute((TransactionCallbackWithoutResult) tranStatus -> {
...
});
最后
如果你喜歡這款軟件不妨收藏它、給它一個 Start 吧。 https://gitee.com/zycgit/dbvisitor
- 訪問數(shù)據(jù)庫必備工具包labSQL數(shù)據(jù)包下載 141次下載
- 基于PCA和隨機樹的數(shù)據(jù)庫異常訪問檢測算法 5次下載
- 數(shù)據(jù)庫教程之PHP訪問MySQL數(shù)據(jù)庫的理論知識詳細(xì)說明 15次下載
- 如何使用Java的Web數(shù)據(jù)庫訪問系統(tǒng) 6次下載
- 數(shù)據(jù)庫教程之如何進行數(shù)據(jù)庫設(shè)計 21次下載
- 數(shù)據(jù)庫設(shè)計時應(yīng)該考慮什么?數(shù)據(jù)庫設(shè)計和物理存儲結(jié)構(gòu)這里概述 5次下載
- ADO.NET數(shù)據(jù)庫訪問技術(shù) 16次下載
- 用ASP訪問數(shù)據(jù)庫的幾種常見方式 4次下載
- UDAT4.0數(shù)據(jù)庫管理工具 3次下載
- 基于雙層中間件的網(wǎng)格數(shù)據(jù)庫訪問與集成
- LabVIEW訪問Access數(shù)據(jù)庫的研究
- Oracle數(shù)據(jù)庫網(wǎng)絡(luò)安全訪問機制
- LabVIEW中訪問數(shù)據(jù)庫的幾種不同方法
- LabVIEW與Access數(shù)據(jù)庫訪問接口研究
- ADO 控件訪問數(shù)據(jù)庫的各種技巧探討
- 聊聊日志即數(shù)據(jù)庫 529次閱讀
- 一款數(shù)據(jù)庫自動化提權(quán)工具 557次閱讀
- 多平臺的關(guān)系數(shù)據(jù)庫管理和開發(fā)工具 698次閱讀
- Oracle:數(shù)據(jù)庫開發(fā)和管理的工具 539次閱讀
- 什么是數(shù)據(jù)庫 1190次閱讀
- 常見的數(shù)據(jù)庫管理 1916次閱讀
- 用docker啟動 postgres 數(shù)據(jù)庫 2468次閱讀
- 詳談一些主流開源數(shù)據(jù)庫及工具 2451次閱讀
- 云數(shù)據(jù)庫和自建數(shù)據(jù)庫的區(qū)別及應(yīng)用 4412次閱讀
- 三種方法教你限制某個IP或IP段訪問Oracle數(shù)據(jù)庫 9725次閱讀
- LabNotebook數(shù)據(jù)庫結(jié)構(gòu) LabNotebook 數(shù)據(jù)庫重建 993次閱讀
- 一文看懂數(shù)據(jù)庫原理與應(yīng)用 11.7w次閱讀
- 數(shù)據(jù)庫引擎是什么 1.1w次閱讀
- 常用的數(shù)據(jù)庫引擎有哪些_數(shù)據(jù)庫引擎分類 2.1w次閱讀
- 目前流行的數(shù)據(jù)庫_構(gòu)建數(shù)據(jù)庫系統(tǒng)的流程 7076次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數(shù)據(jù)手冊
- 1.06 MB | 532次下載 | 免費
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費
- 3TC358743XBG評估板參考手冊
- 1.36 MB | 330次下載 | 免費
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費
- 5元宇宙深度解析—未來的未來-風(fēng)口還是泡沫
- 6.40 MB | 227次下載 | 免費
- 6迪文DGUS開發(fā)指南
- 31.67 MB | 194次下載 | 免費
- 7元宇宙底層硬件系列報告
- 13.42 MB | 182次下載 | 免費
- 8FP5207XR-G1中文應(yīng)用手冊
- 1.09 MB | 178次下載 | 免費
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 2555集成電路應(yīng)用800例(新編版)
- 0.00 MB | 33566次下載 | 免費
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費
- 4開關(guān)電源設(shè)計實例指南
- 未知 | 21549次下載 | 免費
- 5電氣工程師手冊免費下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費
- 6數(shù)字電路基礎(chǔ)pdf(下載)
- 未知 | 13750次下載 | 免費
- 7電子制作實例集錦 下載
- 未知 | 8113次下載 | 免費
- 8《LED驅(qū)動電路設(shè)計》 溫德爾著
- 0.00 MB | 6656次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費
- 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
- 78.1 MB | 537798次下載 | 免費
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費
- 6電路仿真軟件multisim 10.0免費下載
- 340992 | 191187次下載 | 免費
- 7十天學(xué)會AVR單片機與C語言視頻教程 下載
- 158M | 183279次下載 | 免費
- 8proe5.0野火版下載(中文版免費下載)
- 未知 | 138040次下載 | 免費
評論
查看更多