// Mapper
@SelectProvider(type = IssueProvider.class, method = "list")
Page<IssueVO> list(IssueVO issue);
// Provider
// Issue是对应的Bean,字段调整后,在Issue中添加对应的字段即可(可以生成,可以手动添加)
public String list(Issue issue) {
SQL sql = new SQL();
sql.SELECT("*");
sql.FROM("issue");
BeanMap beanMap = BeanMap.create(issue);
for (Object key : beanMap.keySet()) {
Object val = beanMap.get(key);
if (val != null) {
if (val instanceof String && ((String) val).contains("%")) {
sql.WHERE("`" + FieldUtils.camelToLine(key + "") + "`" + "like #{" + key + "}");
} else {
sql.WHERE("`" + FieldUtils.camelToLine(key + "") + "`" + "=#{" + key + "}");
}
}
}
return sql.toString();
}
- 优势:
- 改动量比较小
- 劣势:
- 反射对性能的影响
- 基于注解的方式,习惯性问题
- IDEA对Provider的方式的支持没有XML高,XML支持自动完成,Provider中不支持
- Mybatis生成的Mapper和XML文件分别为独立的目录
- 自定义的Mapper继承生成的Mapper,在自定义Mapper中新增自定义接口方法,对应的sql添加到对应的自定义XML文件中
- 自定义XML文件可以基于NameSpace来使用生成的XML文件的Result
- 当表结构调整后,重新生成对应的Mapper和XML即可
- 优势:
- 符合习惯
- 劣势:
- 改动量相对多一点,不过是生成的,所以基本可以忽略
- 主表+子表的关联关系
- 表中冗余其它表的字段
主表+子表的关联关系此种方式适用于主表和子表需要单独修改的场景 。如果主表和子表是聚合关系,即子表依赖于主表存在,且需要一起调整,甚至子表不需要调整,实际可以简化此种关联关系 。
因为此种关联关系涉及到了联表查询,联表查询是无法基于工具生成的 。通过简化此种关系,可以基于工具来提高开发效率 。
表中冗余其它表的字段有些情况下,可能会将两个逻辑上分离的对象整合为一个对象来处理,简化操作负责度 。例如订单中可能直接就包含购买的应用信息 。此种情况实际是为了操作的便利性,同时兼顾数据库特性,将结构化的数据扁平化了 。
数据扁平化本身问题不大,不过弱化了代码语义 。在正常理解里,订单包含订单明细,订单明细中是商品信息 。
可以通过下面的方法来解决上面提到的两个问题 。
解决方案MySQL5.7开始支持Json 。上述两种情况,都可以基于Json的方式来处理 。即数据库字段可以使用json类型 。
// 支持基于json的查询,请自行google在Mybatis层面,通过TypeHandler来处理Json与对象之间的自动转换 。
create table order
(
......
item_info_json json not null comment 'json',
);
public class Order {
private ItemInfo itemInfoJson;
}
public interface OrderDao {
// 配置转换handler
@Results(id = "jsonResult", value = https://www.isolves.com/it/cxkf/kj/2020-11-16/{
@Result(property = "itemInfoJson", column = "item_info_json", typeHandler = JsonTypeHandler.class)
})
@Select("select * from order where rec_id = #{recId}")
Order selectByPrimaryKey(@Param("recId") String recId);
@InsertProvider(type = OrderProvider.class, method = "insert")
void insert(Order model);
......
}
public class OrderProvider {
public String insert(Order order) {
SQL sql = new SQL();
sql.INSERT_INTO("order");
BeanMap beanMap = BeanMap.create(order);
for (Object key : beanMap.keySet()) {
Object val = beanMap.get(key);
if (val != null) {
if ((key + "").endsWith("Json")) { // 根据后缀判定是否需要转换
sql.VALUES("`" + FieldUtils.camelToLine(key + "") + "`", "#{" + key + ", typeHandler=com.iwhalecloud.common.mybatis.JsonTypeHandler}");
} else {
sql.VALUES("`" + FieldUtils.camelToLine(key + "") + "`", "#{" + key + "}");
推荐阅读
- App开发之客户端框架搭建
- 企业知识库的搭建步骤
- 教你本地k8s集群搭建云原生 Tekton CICD 流水线
- 10个对web开发人员有用的HTML文件上传技巧
- 12种Flutter开发工具推荐
- 手把手搭建RTSP流媒体服务器
- 软件开发人员应该了解的2021年技术趋势
- 开发者应知道的方法论:JavaScript中的DILOS原则
- 一代深度学习框架研究
- 轻量级H5 app开发实践之总结