热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

详解mybatis@SelectProvider注解

这篇文章主要介绍了mybatis@SelectProvider注解的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

01、前言

为什么会写这篇文章, 因为在看到 MapperAnnotationBuilder 构造方法初始化时, 发现了四个从未见过的注解

public MapperAnnotationBuilder(Configuration configuration, Class<&#63;> type) {
  ...
  sqlAnnotationTypes.add(Select.class);
  sqlAnnotationTypes.add(Insert.class);
  sqlAnnotationTypes.add(Update.class);
  sqlAnnotationTypes.add(Delete.class);
  // 这四个注解眼生的很
  sqlProviderAnnotationTypes.add(SelectProvider.class);
  sqlProviderAnnotationTypes.add(InsertProvider.class);
  sqlProviderAnnotationTypes.add(UpdateProvider.class);
  sqlProviderAnnotationTypes.add(DeleteProvider.class);
}

@SelectProvider、@InsertProvider、@UpdateProvider、@DeleteProvider

分别是 mybatis 定义的 另类增删改查注解

02、介绍篇

四个注解中分别都有两个属性, 这里以 @SelectProvider举例

可以看到, 两个属性并没有默认值, 证明定义注解的话, 这两个属性必须组合使用

没有看到这一块的具体解析源码, 不过也能猜出来, 根据反射调用方法获取的返回值

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface InsertProvider {
  // 用于指定获取 sql 语句的指定类
  Class<&#63;> type();
  // 指定类中要执行获取 sql 语句的方法
  String method();
}

03、实战篇

如何根据注解定义 sql 语句呢, 首先定义 mapper 接口

public interface AutoConstructorMapper {
  @SelectProvider(type = SubjectSqlProvider.class, method = "getSubjectTestProvider")
  PrimitiveSubject getSubjectTestProvider(@Param("id") int id);
}

@Param() 为必须, 在解析时会将参数定义为 map, 进行调用指定 method

创建 type 对应的存放 sql 语句的类, 以及定义返回 sql 语句的方法

有三点需要注意:

  • 方法入参必须为 Map
  • 方法的权限修饰符 必须是 public
  • 方法返回的必须是拼接好的 sql 字符串
public class SubjectSqlProvider {
  public String getSubjectTestProvider(Map params) {
    return new SQL()
        .SELECT("*")
        .FROM("subject")
        .WHERE("id = " + params.get("id"))
        .toString();
  }
}

SQL 类是 mybatis 提供开发者在代码中灵活编写 sql 语句的工具类

04、思考篇

思考一下, @SelectProvider 注解, 与 @Select 注解解析流程有什么不同&#63;

@Select@SelectProvider 只是在定义注解的方式上有所不同, 一个是直接定义 sql, 一个是在外部定义好 sql 直接引用, 没有质的区别

在 mybatis 初始化定义 MappedStatement 时, 使用了两种不同的逻辑进行组装 SqlSource

Class<&#63; extends Annotation> sqlAnnotatiOnType= getSqlAnnotationType(method);
Class<&#63; extends Annotation> sqlProviderAnnotatiOnType= getSqlProviderAnnotationType(method);
if (sqlAnnotationType != null) {
  if (sqlProviderAnnotationType != null) {
    throw new BindingException("You cannot supply both a static SQL and SqlProvider to method named " + method.getName());
  }
  Annotation sqlAnnotation = method.getAnnotation(sqlAnnotationType);
  final String[] strings = (String[]) sqlAnnotation.getClass().getMethod("value").invoke(sqlAnnotation);
  return buildSqlSourceFromStrings(strings, parameterType, languageDriver);
} else if (sqlProviderAnnotationType != null) {
  Annotation sqlProviderAnnotation = method.getAnnotation(sqlProviderAnnotationType);
  return new ProviderSqlSource(assistant.getConfiguration(), sqlProviderAnnotation, type, method);
}

05、使用篇

这里介绍下 mybatis 具体编写 SQL 的三种形式, 以及介绍不同的方式对应的使用场景

5.1 @Select

这种方式能够定义简单的 sql, 不涉及复杂查询和多参数的场景, 类似下述方式

@Select 定义 sql 的方式是最简单的, 省去了定义 xml文件的繁琐, 也少了定义编写 @SelectProvider 对应类和方法的步骤

SELECT * FROM subject WHERE id = #{id}

5.2 @SelectProvider

这种方式编写sql适合编写中等长度, 简单的查询搭配 join、group、order…

SQL 工具类提供了这种简单的 API 语法, 还是比较方便的

如果不想使用 SQL 工具类, 自己编写 sql 字符串也是可以的

5.3 .xml 文件

这种方式就不多说了, 功能全部具备, 比如计算函数、动态SQL、各种关键字都支持

这几种方式都能够实现我们的 sql 编写需求, 只不过针对不同的场景, 合理的使用即可

06、总结篇

看 mybatis 源码, 对变量、方法的命名加深了感触, 一个好的变量或者方法命名在代码中是多么有必要

getSqlSourceFromAnnotations 是不是要比 getSqlSource 要好理解很多, 看了之后就能让阅读者知道这个方法要做什么功能

到此这篇关于详解mybatis @SelectProvider 注解的文章就介绍到这了,更多相关mybatis @SelectProvider 注解内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文讨论了在Spring 3.1中,数据源未能自动连接到@Configuration类的错误原因,并提供了解决方法。作者发现了错误的原因,并在代码中手动定义了PersistenceAnnotationBeanPostProcessor。作者删除了该定义后,问题得到解决。此外,作者还指出了默认的PersistenceAnnotationBeanPostProcessor的注册方式,并提供了自定义该bean定义的方法。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • 本文介绍了在使用MSXML解析XML文件时出现DTD禁用问题的解决方案。通过代码示例和错误信息获取方法,解释了默认情况下DTD是禁用的,以及如何启用DTD的方法。此外,还提到了网上关于该问题的信息相对较少,因此本文提供了解决方案以供参考。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • 在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板
    本文介绍了在Xamarin XAML语言中如何在页面级别构建ControlTemplate控件模板的方法和步骤,包括将ResourceDictionary添加到页面中以及在ResourceDictionary中实现模板的构建。通过本文的阅读,读者可以了解到在Xamarin XAML语言中构建控件模板的具体操作步骤和语法形式。 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
author-avatar
梦天使悠然
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有