最近项目使用了SpringBoot+TKMytis框架,期间遇到一些问题,顺便记一下。

一、框架配置

配置的话非常简单,我用的是SpringBoot,直接引入:

<dependency><groupId>tk.mybatis</groupId><artifactId>mapper-spring-boot-starter</artifactId><version>2.0.3-beta1</version>
</dependency><dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId><version>4.0.0</version>
</dependency>

Mybatis的以及分页插件等就不写了。

创建一个BaseMapper

public interface BaseMapper<T> extends tk.mybatis.mapper.common.BaseMapper<T>, MySqlMapper<T>, IdsMapper<T>, ConditionMapper<T>,ExampleMapper<T> {}

这5个Mapper待会我会详细讲解。

创建BaseService<T>继承自BaseMapper<T>

public interface BaseService<T> extends BaseMapper<T> {
}

以及BaseService的实现类BaseServiceImpl<T> implements BaseService<T>

public abstract class BaseServiceImpl<T> implements BaseService<T> {
}

Service里需实现部分方法,详细代码在后边。

这样我们就基本完成了配置。

二、类配置方法

1、实体类

创建一个实体类与数据库进行映射,此时我们使用JPA的注解:

package com.capol.entity;import java.sql.Timestamp;import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;import com.capol.base.BaseEntity;import lombok.Data;
import lombok.EqualsAndHashCode;
/*** @author lizihao* @version 2018年07月31日* 用户角色*/
@Data
@EqualsAndHashCode(callSuper=false)
@Table(name="t_sys_user_role")//设置数据库中表名字
public class UserRole extends BaseEntity{/*** 主键*/@Column(name = "f_id")@Idprivate String fId;/*** 用户ID*/@Column(name = "f_user_id")private String fUserId;/*** 用户名*/@Transientprivate String fUserName;}

其中@Table即数据表表名,@Column即列名,@Id作为主键,需要注意,@Id注解不可有多个,@Transient即冗余字段,不与数据库任何字段对应。

分享一个小技巧,实际项目中我们可能存在多数据源的情况,如果使用的是sqlserver,且多个数据库均在同一台服务器下且配置的账号均拥有权限,

则@Table注解中可以写成“{数据库名}.{架构名}.{表名}”,如:@Table(name="db.dbo.tableName")

而不需要再额外配置数据源

2、Service类

这里主要是实现了上边BaseMapper中继承的5个Mapper的方法,

tk.mybatis.mapper.common.BaseMapper<T>中有较多方法,均需要继承实现:

        /*** 保存一个实体,null属性也会保存* * @param record* @return*/int insert(T record);/*** 保存一个实体,null属性不会保存* * @param record* @return*/int insertSelective(T record);/*** 根据实体属性作为条件进行删除,查询条件使用等号*/int delete(T record);/*** 根据主键更新属性不为null的值*/int updateByPrimaryKeySelective(T record);/*** 根据实体中的属性值进行查询,查询条件使用等号*/List<T> select(T record);/*** 查询全部结果,select(null)方法能达到同样的效果*/List<T> selectAll();/*** 根据实体中的属性进行查询,只能有一个返回值,有多个结果是抛出异常,查询条件使用等号*/T selectOne(T record);/*** 根据实体中的属性查询总数,查询条件使用等号*/int selectCount(T record);

以上所有方法的查询条件均为实体类record中的非空属性。

MySqlMapper<T>中的方法如下:

 /*** 批量插入,支持批量插入的数据库可以使用,例如MySQL,H2等,另外该接口限制实体包含`id`属性并且必须为自增列*/public int insertList(List<T> recordList);/*** 插入数据,限制为实体包含`id`属性并且必须为自增列,实体配置的主键策略无效*/public int insertUseGeneratedKeys(T record);

这两个方法就比较坑了,限制了主键必须为自增列,如果是自己生成主键则不能使用该方法。

IdsMapper<T>中的方法如下:

        /*** 根据主键@Id进行查询,多个Id以逗号,分割* @param id* @return*/List<T> selectByIds(String ids);/*** 根据主键@Id进行删除,多个Id以逗号,分割* @param id* @return*/int deleteByIds(String ids);

这两个方法就很好理解了,不再解释。

ConditionMapper<T>中的方法如下:

        /*** 根据Condition条件进行查询*/public List<T> selectByCondition(Object condition);/*** 根据Condition条件进行查询*/public int selectCountByCondition(Object condition);/*** 根据Condition条件删除数据,返回删除的条数*/public int deleteByCondition(Object condition);/*** 根据Condition条件更新实体`record`包含的全部属性,null值会被更新,返回更新的条数*/public int updateByCondition(T record, Object condition);/*** 根据Condition条件更新实体`record`包含的全部属性,null值会被更新,返回更新的条数*/public int updateByConditionSelective(T record, Object condition);

传入的Object condition应为tk.mybatis.mapper.entity.Condition,具体使用方法后续会说明。

ExampleMapper<T>中的方法如下:

        /*** 根据Example条件进行查询*/public List<T> selectByExample(Object example);/*** 根据Example条件进行查询,若有多条数据则抛出异常*/public T selectOneByExample(Object example);/*** 根据Example条件进行查询总数*/public int selectCountByExample(Object example);/*** 根据Example条件删除数据,返回删除的条数*/public int deleteByExample(Object example);/*** 根据Example条件更新实体`record`包含的全部属性,null值会被更新,返回更新的条数*/public int updateByExample(T record, Object example);/*** 根据Example条件更新实体`record`包含的不是null的属性值,返回更新的条数*/public int updateByExampleSelective(T record, Object example);

同上,传入的Object example应为tk.mybatis.mapper.entity.Example,具体使用方法后续会说明。

3、实现类

各个方法的实现大同小异,此处以一个为例:

public abstract class BaseServiceImpl<T> implements BaseService<T> {protected abstract BaseMapper<T> getMapper();@Overridepublic int insert(T record) {return getMapper().insert(record);}
}

getMapper()方法需要在具体的业务代码中实现,其余不再赘述。

三、使用方法

1、tk.mybatis.mapper.common.BaseMapper<T>, IdsMapper<T>, MySqlMapper<T>内方法使用说明:

从接口中我们可以看到传入的方法基本均为T record,即实体类,查询时会根据实体类中的属性值进行where语句构建,查询条件为等号,这里没有什么特殊的。

不过需要注意,若传入实例化的实体类,且其中包含int属性,则构建sql语句中会将该属性包含进去,如下代码:

@Data
@EqualsAndHashCode(callSuper=false)
@Table(name="t_sys_user_role")//设置数据库中表名字
public class UserRole extends BaseEntity{/*** 主键*/@Column(name = "f_id")@Idprivate String fId;/*** 类型(1.系统管理员)*/@Column(name = "f_type")private int fType;
}@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=StartApp.class)
@WebAppConfiguration
public class TestService {@Autowiredprivate IUserRoleService userRoleService;@Testpublic void testUserRole() throws Exception{UserRole userRole = new UserRole();List<UserRole> userRoleList = userRoleService.select(userRole);System.out.println(userRoleList);}
}

从日志中我们可以看到:

2018-08-12 17:31:10.768 DEBUG 12172 --- [           main] com.capol.mapper.UserRoleMapper.select   : ==>  Preparing: SELECT f_id,f_user_id,f_type,f_status,f_description,f_creator_id,f_create_time,f_last_updator_id,f_last_update_time FROM t_sys_user_role WHERE f_type = ?
2018-08-12 17:31:10.776 DEBUG 12172 --- [           main] com.capol.mapper.UserRoleMapper.select   : ==> Parameters: 0(Integer)
2018-08-12 17:31:10.787 DEBUG 12172 --- [           main] com.capol.mapper.UserRoleMapper.select   : <==      Total: 0

很明显,这不是我们要的结果。将int类型改为Integer类型即可,或使用Condition、Example方法进行查询。

2、ExampleMapper<T>内方法使用说明:

所有方法均需要传入tk.mybatis.mapper.entity.Example,

首先进行实例化:

Example example = new Example(UserRole.class);//实例化
Example.Criteria criteria = example.createCriteria();

Criteria是Example中的一个内部类,在最终sql构建时以括号呈现,Criteria里带了较多构建查询条件的方法,如

andEqualTo(String property, Object value),

orEqualTo(String property, Object value),

andGreaterThan(String property, Object value),

orGreaterThan(String property, Object value)

传入的property为实体类中的属性名,非数据度字段名。

举例说明,如orEqualTo(String property, Object value),代码如下:

Example example = new Example(UserRole.class);//实例化
Example.Criteria criteria = example.createCriteria();
criteria.orEqualTo("fUserId", "15693a6e509ee4819fcf0884ea4a7c9b");
criteria.orEqualTo("fUserId", "15ccaf3e89376f7b109eec94d10b7988");
List<UserRole> userRoleList = userRoleService.selectByExample(example);

最终的where语句则为:

( f_user_id = "15693a6e509ee4819fcf0884ea4a7c9b" or f_user_id = "15ccaf3e89376f7b109eec94d10b7988" )

其余方法同理。

其中andCondition(String condition)方法支持手写条件,传入的字符串为最终的查询条件,如:length(f_user_id)<5

以及likeTo()的方法是不带百分号%的,需要自己对传入参数进行构建(加左like或者右like等)。

其余方法自行见源码,不再赘述。

3、ConditionMapper<T>内方法使用说明:

所有方法均需要传入tk.mybatis.mapper.entity.Condition,Condition实际上继承自tk.mybatis.mapper.entity.Example,

源码中只有三个方法:

public Condition(Class<?> entityClass) {super(entityClass);
}public Condition(Class<?> entityClass, boolean exists) {super(entityClass, exists);
}public Condition(Class<?> entityClass, boolean exists, boolean notNull) {super(entityClass, exists, notNull);
}

说实话我也不知道这样做有什么意义,望哪位大神指教一下。

boolean exists, boolean notNull这两个参数的含义为:

若exists为true时,如果字段不存在就抛出异常,false时,如果不存在就不使用该字段的条件,

若notNull为true时,如果值为空,就会抛出异常,false时,如果为空就不使用该字段的条件

其使用方法与Example类似:

Condition condition = new Condition(UserRole.class);
Criteria criteria = condition.createCriteria();
criteria.orEqualTo("fUserId", "15693a6e509ee4819fcf0884ea4a7c9b");
criteria.orEqualTo("fUserId", "15ccaf3e89376f7b109eec94d10b7988");
List<UserRole> userRoleList = userRoleService.selectByCondition(condition);

毕竟是继承自Example。

4、Example.and()/or()和Condition.and()/or()方法说明:

两个都一样,我就挑一个说吧。

实例化方法跟上边略有不同:

Condition condition = new Condition(UserRole.class);
//Criteria criteria1 = condition.createCriteria();
Criteria criteria1 = condition.and();

上边说了,每个Criteria在最终结果中以括号形式展现,此时and()方法则表示 and (Criteria中的条件),or()方法则表示 or (Criteria中的条件),默认createCriteria()等同于and(),测试结果如下:

2018-08-12 18:23:11.805 DEBUG 13760 --- [           main] c.c.m.UserRoleMapper.selectByCondition   : ==>  Preparing: SELECT f_id,f_user_id,f_type,f_status,f_description,f_creator_id,f_create_time,f_last_updator_id,f_last_update_time FROM t_sys_user_role WHERE ( f_user_id = ? and f_user_id = ? ) or ( f_description = ? or f_description = ? )

TKmybatis的框架介绍及使用方法相关推荐

  1. 简单介绍.Net性能测试框架Crank的使用方法

    这篇文章介绍了.Net性能测试框架Crank的使用方法.对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 Crank 是微软新出的一个性能测试框架,集成了多种基准测 ...

  2. python爬虫scrapy框架教程_Python爬虫教程-30-Scrapy 爬虫框架介绍

    从本篇开始学习 Scrapy 爬虫框架 Python爬虫教程-30-Scrapy 爬虫框架介绍 框架:框架就是对于相同的相似的部分,代码做到不出错,而我们就可以将注意力放到我们自己的部分了 常见爬虫框 ...

  3. dommel mysql_.Net Core AA.FrameWork应用框架介绍

    开发多年,一直在从社区获取开源的便利,也深感社区力量的重要性,今天开源一个应用基础框架AA.FrameWork,也算是回馈社区,做出一点点贡献,希望能够帮助类似当年入行的我. AA.FrameWork ...

  4. iOS流媒体直播整个框架介绍(HLS、RTSP)

    iOS流媒体直播整个框架介绍(HLS.RTSP) 目录技术文章2016年7月17日 一.HTTP(WebService) 基于HTTP的渐进下载Progressive Download流媒体播放仅是在 ...

  5. fitnesse - 框架介绍

    fitnesse - 框架介绍 2017-09-29 目录: 1 fitnesse是什么? 2 框架介绍 3 与junit.testng比较,fitnesse教其他框架有什么优势 1 fitnesse ...

  6. ESFramework网络通信框架介绍之(3)――消息处理器和处理器工厂

    一.ESFramework网络通信框架与消息处理器 无论是服务端还是客户端,都需要对接收到的消息进行处理,在ESFramework网络通信框架中,处理消息的组件称为消息处理器,所有的消息处理器都实现了 ...

  7. Lind.DDD敏捷领域驱动框架~介绍

    最近觉得自己的框架过于复杂,在实现开发使用中有些不爽,自己的朋友们也经常和我说,框架太麻烦了,要引用的类库太多:之前架构之所以这样设计,完全出于对职责分离和代码附复用的考虑,主要参考了微软的DDD大作 ...

  8. Go gin web框架介绍

    gin框架介绍 一.gin框架介绍 gin是用go语言开发的一个web框架,简单易用,是一个轻量级框架. 二.为什么选择gin 1.运行响应非常快 2.快速开发 3.文档齐全 4.社区活跃 三.特性 ...

  9. java集合框架介绍_Java集合框架介绍

    Java集合框架介绍 发布时间:2020-06-26 17:00:14 来源:亿速云 阅读:85 作者:Leah 这篇文章将为大家详细讲解有关Java集合框架介绍,文章内容质量较高,因此小编分享给大家 ...

最新文章

  1. tap/tun接口是什么?
  2. 我们离得开美国的软件和硬件吗?
  3. XiaoluD的留言板
  4. ifconfig没有命令 kali_新装的Linux系统没有ifconfig命令?教你一键找回
  5. 一起谈.NET技术,Visual Studio与C#编程十个实用技巧
  6. esp8266数据上传到mysql数据库_03-STM32+ESP8266+AIR202/302终端管理篇-把设备温湿度数据存储到MySQL数据库(Windows)...
  7. Diaspora-v1.3.0 素锦WordPress博客主
  8. Spring for Apache Hadoop 1.0 GA
  9. java下载文件名乱码的解决方法
  10. Qt之音频播放(二)
  11. bvp解算器是什么_中科院孙晓明:算法本身并没有善恶,看你想要的目标是什么...
  12. 标签条码打印机开发大纲
  13. 2020最全蓝牙耳机盘点:年会最值得选择的十大优秀蓝牙耳机品牌
  14. 如何高效学习?(个人经验篇)
  15. 小武与python的相遇1 - strip-replace的使用
  16. Axure RP 9母版使用说明【教程二】
  17. matlab程序按哪里运行,脱离matlab运行可执行程序的步骤
  18. 基于jupyter notebook的简单爬虫学习记录
  19. 卡耐基《人性的弱点》精华总结
  20. 求可以统计网络流量的VC代码,就象是金山网镖下面的那样

热门文章

  1. 下划线JSON字符串与驼峰Java Bean相互转换
  2. oracle--2.服务
  3. Oracle各个服务介绍
  4. DOCSIS 3.1 MMM--3.MAP
  5. 重庆已建成4.2万余个5G基站;山西省累计建成5G基站1.2万个
  6. 【10月22日】黑鹰红客基地每日软件更新
  7. H3C防火墙端口开启二层模式,网络不通的解决方法
  8. Linux QT摄像头采集图像
  9. 蓝桥杯-基础练习 查找整数
  10. excel简单操作学习记录1-2021/2/6