dbVisitor 全功能数据库访问工具开源项目

我要开发同款
匿名用户2021年12月18日
46阅读
开发技术Java
所属分类数据库相关、数据库管理工具
授权协议Apache

作品详情

dbVisitor(原HasorDB)是一个全功能数据库访问工具,提供对象映射、丰富的类型处理、动态SQL、存储过程、内置分页方言20+、支持嵌套事务、多数据源、条件构造器、INSERT策略、多语句/多结果。并兼容Spring及MyBatis用法。它不依赖任何其它框架,因此可以很方便的和任意一个框架整合在一起使用。

功能特性​熟悉的方式 JdbcTemplate接口方式(高度兼容SpringJDBC)Mapper文件方式(高度兼容MyBatis)LambdaTemplate(高度接近MyBatisPlus、jOOQ和BeetlSQL)@Insert、@Update、@Delete、@Query、@Callable注解(类似JPA)事务支持支持5个事务隔离级别、7个事务传播行为(与Springtx相同)提供TransactionTemplate、TransactionManager接口方式声明式事务控制能力(用法与Spring相同)特色优势支持分页查询并且提供多种数据库方言(20+)支持INSERT策略(INTO、UPDATE、IGNORE)更加丰富的TypeHandler(MyBatis40+,dbVisitor60+)MapperXML支持多语句、多结果提供独特的规则机制,让动态SQL更加简单支持存储过程支持JDBC4.2和Java8中时间类型支持多数据源引入依赖在https://mvnrepository.com/artifact/net.hasor/dbvisitor上也可以查询到最新版本<dependency><groupId>net.hasor<groupId><artifactId>dbvisitor<artifactId><version>5.0.1<version>dependency>然后再引入数据库驱动以MySQL,Maven方式为例:

<dependency><groupId>mysql<groupId><artifactId>mysql-connector-java<artifactId><version>8.0.22<version>dependency>使用dbVisitor 可以不依赖数据库连接池,但有数据库连接池是大多数项目的标配。这里选用Alibaba的Druid

<dependency><groupId>com.alibaba<groupId><artifactId>druid<artifactId><version>1.1.23<version>dependency>最后准备一个数据库表,并初始化一些数据(CreateDB.sql文件)

droptableifexists`test_user`;createtable`test_user`(`id`int(11)auto_increment,`name`varchar(255),`age`int,`create_time`datetime,primarykey(`id`));insertinto`test_user`values(1,'mali',26,now());insertinto`test_user`values(2,'dative',32,now());insertinto`test_user`values(3,'jonwes',41,now());insertinto`test_user`values(4,'mary',66,now());insertinto`test_user`values(5,'matt',25,now());执行SQL​使用SQL的方式读取数据,PrintUtils和DsUtils两个工具类可以在例子工程中找到

//创建数据源DataSourcedataSource=DsUtils.dsMySql();//创建JdbcTemplate对象JdbcTemplatejdbcTemplate=newJdbcTemplate(dataSource);//加载测试数据脚本jdbcTemplate.loadSQL("CreateDB.sql");//查询数据并Map形式返回List<Map<String,Object>>mapList=jdbcTemplate.queryForList("select*fromtest_user");//打印测试数据PrintUtils.printMapList(mapList);控制台可以得到如下结果

/--------------------------------------------\\|id|name|age|create_time||--------------------------------------------||1|mali|26|2021-11-1219:14:06.0||2|dative|32|2021-11-1219:14:06.0||3|jonwes|41|2021-11-1219:14:06.0||4|mary|66|2021-11-1219:14:06.0||5|matt|25|2021-11-1219:14:06.0|\\--------------------------------------------/如果想使用DTO对象接收数据,则需要创建一个DTO对象。

//如果属性名和列名可以完全匹配,那么无需任何注解。//-本列中由于`test_user`的表名和列名符合驼峰转下划线,那么可以简单的通过@Table注解声明一下。//-如果需要映射表名和列名请参照注解@Table、@Column更多的属性@Table(mapUnderscoreToCamelCase=true)publicclassTestUser{privateIntegerid;privateStringname;privateIntegerage;privateDatecreateTime;//gettersandsettersomitted}//然后通过`queryForList`方法直接查询,控制台就可以得到相同的结果StringsqlString="select*fromtest_user";List<TestUser>dtoList=jdbcTemplate.queryForList(sqlString,TestUser.class);PrintUtils.printObjectList(dtoList);单表CRUD对于单表CRUD操作可以使用JdbcTemplate的子类LambdaTemplate//创建数据源DataSourcedataSource=DsUtils.dsMySql();//创建LambdaTemplate对象和创建JdbcTemplate一样LambdaTemplatelambdaTemplate=newLambdaTemplate(dataSource);//初始化一些数据lambdaTemplate.loadSQL("CreateDB.sql");//查询,所有数据List<TestUser>dtoList=lambdaTemplate.lambdaQuery(TestUser.class).queryForList();PrintUtils.printObjectList(dtoList);//插入新数据TestUsernewUser=newTestUser();newUser.setName("newUser");newUser.setAge(33);newUser.setCreateTime(newDate());intresult=lambdaTemplate.lambdaInsert(TestUser.class).applyEntity(newUser).executeSumResult();//更新,将name从mali更新为malaTestUsersample=newTestUser();sample.setName("mala");intresult=lambdaTemplate.lambdaUpdate(TestUser.class).eq(TestUser::getId,1).updateToBySample(sample).doUpdate();//删除,ID为2的数据intresult=lambdaTemplate.lambdaUpdate(TestUser.class).eq(TestUser::getId,1).updateToBySample(sample).doUpdate();使用DAO​

使用DAO可以继承BaseMapper通用DAO接口来完成一些基本操作,仍然以单表CRUD为例。

//DAO的一些接口需要识别ID属性,因此有必要在DTO对象上通过@Column注解标记出它们@Table(mapUnderscoreToCamelCase=true)publicclassTestUser{@Column(primary=true)privateIntegerid;privateStringname;privateIntegerage;privateDatecreateTime;//gettersandsettersomitted}//创建数据源DataSourcedataSource=DsUtils.dsMySql();//创建通用DAODalSessionsession=newDalSession(dataSource);BaseMapper<TestUser>baseMapper=session.createBaseMapper(TestUser.class);//初始化一些数据baseMapper.template().loadSQL("CreateDB.sql");//查询数据List<TestUser>dtoList=baseMapper.query().queryForList();PrintUtils.printObjectList(dtoList);//插入新数据TestUsernewUser=newTestUser();newUser.setName("newUser");newUser.setAge(33);newUser.setCreateTime(newDate());intresult=baseMapper.insert(newUser);//更新,将name从mali更新为malaTestUsersample=baseMapper.queryById(1);sample.setName("mala");intresult=baseMapper.updateById(sample);//删除,ID为2的数据intresult=baseMapper.deleteById(2);

作为DAO可以定义自己的方法,并通过注解配置具体执行的SQL语句。

//BaseMapper是可选的,继承它相当于多了一组单表CURD的扩展功能。@SimpleMapperpublicinterfaceTestUserDAOextendsBaseMapper<TestUser>{@Insert("insertinto`test_user`(name,age,create_time)values(#{name},#{age},now())")publicintinsertUser(@Param("name")Stringname,@Param("age")intage);@Update("update`test_user`setage=#{age}whereid=#{id}")publicintupdateAge(@Param("id")intuserId,@Param("age")intnewAge);@Delete("deletefrom`test_user`whereage>#{age}")publicintdeleteByAge(@Param("age")intage);@Query(value="select*from`test_user`where#{beginAge}<ageandage<#{endAge}",resultType=TestUser.class)publicList<TestUser>queryByAge(@Param("beginAge")intbeginAge,@Param("endAge")intendAge);}//创建DalRegistry并注册TestUserDAODalRegistrydalRegistry=newDalRegistry();dalRegistry.loadMapper(TestUserDAO.class);//使用DalRegistry创建SessionDalSessionsession=newDalSession(dataSource,dalRegistry);//创建DAO接口TestUserDAOuserDAO=session.createMapper(TestUserDAO.class);使用Mapper​

统一管理SQL的最佳场所仍然是Mapper文件,而且dbVisitor 的Mapper文件高度兼容MyBatis学习成本极低。

//利用@RefMapper注解将Mapper文件和接口类联系起来(继承BaseMapper是可选的)@RefMapper("/mapper/quick_dao3/TestUserMapper.xml")publicinterfaceTestUserDAOextendsBaseMapper<TestUser>{publicintinsertUser(@Param("name")Stringname,@Param("age")intage);publicintupdateAge(@Param("id")intuserId,@Param("age")intnewAge);publicintdeleteByAge(@Param("age")intage);publicList<TestUser>queryByAge(@Param("beginAge")intbeginAge,@Param("endAge")intendAge);}

为了更好了解和使用dbVisitor 的Mapper文件建议增加DTD加以验证。另外HasorDB兼容MyBatis3的DTD对于绝大部分MyBatis工程都可以正常兼容。

DOCTYPEmapperPUBLIC"-//dbvisitor.net//DTDMapper1.0//EN""https://www.dbvisitor.net/schema/dbvisitor-mapper.dtd"><mappernamespace="net.hasor.db.example.quick.dao3.TestUserDAO"><resultMapid="testuser_resultMap"type="net.hasor.db.example.quick.dao3.TestUser"><idcolumn="id"property="id"/><resultcolumn="name"property="name"/><resultcolumn="age"property="age"/><resultcolumn="create_time"property="createTime"/>resultMap><sqlid="testuser_columns">name,age,create_timesql><insertid="insertUser">insertinto`test_user`(<includerefid="testuser_columns"/>)values(#{name},#{age},now())insert><updateid="updateAge">update`test_user`setage=#{age}whereid=#{id}update><deleteid="deleteByAge">deletefrom`test_user`whereage>#{age}]]>delete><selectid="queryByAge"resultMap="testuser_resultMap">selectid,<includerefid="testuser_columns"/>from`test_user`where#{beginAge}<ageandage<#{endAge}select>mapper>快速条件拼接​快速条件拼接包含快速'与'条件和快速'或'条件它们是两个规则用于取代简单的if标签和简单的foreach标签。如下语句,当参数不为空时候才拼接sql

<selectid="queryUser">select*from`test_user`where1=1<iftest="age!=null">andage=#{age}if>select>可以简化为快速规则写法,其中:age为属性名。

<selectid="queryUser">select*from`test_user`@{and,age=:age}select>例如如下foreach操作:

<selectid="queryUser">select*from`test_user`whereidin<foreachitem="item"index="index"collection="list"open="("separator=","close=")">#{item}foreach>select>可以简化为快速规则写法,其中:list为集合属性名。

<selectid="queryUser">select*from`test_user`@{and,idin(:list)}select>如果多个简单条件,快速写法将会极大的减少Mapper的工作量。

<select
声明:本文仅代表作者观点,不代表本站立场。如果侵犯到您的合法权益,请联系我们删除侵权资源!如果遇到资源链接失效,请您通过评论或工单的方式通知管理员。未经允许,不得转载,本站所有资源文章禁止商业使用运营!
下载安装【程序员客栈】APP
实时对接需求、及时收发消息、丰富的开放项目需求、随时随地查看项目状态

评论