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

MyBatis直接执行SQL的工具SqlMapper

今天小编就为大家分享一篇关于MyBatis直接执行SQL的工具SqlMapper,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

可能有些人也有过类似需求,一般都会选择使用其他的方式如Spring-JDBC等方式解决。

能否通过MyBatis实现这样的功能呢?

为了让通用Mapper更彻底的支持多表操作以及更灵活的操作,在2.2.0版本增加了一个可以直接执行SQL的新类SqlMapper。

我们来了解一下SqlMapper。

SqlMapper提供的方法

SqlMapper提供了以下这些公共方法:

  • Map selectOne(String sql)
  • Map selectOne(String sql, Object value)
  • T selectOne(String sql, Class resultType)
  • T selectOne(String sql, Object value, Class resultType)
  • List> selectList(String sql)
  • List> selectList(String sql, Object value)
  • List selectList(String sql, Class resultType)
  • List selectList(String sql, Object value, Class resultType)
  • int insert(String sql)
  • int insert(String sql, Object value)
  • int update(String sql)
  • int update(String sql, Object value)
  • int delete(String sql)
  • int delete(String sql, Object value)

一共14个方法,这些方法的命名和参数和SqlSession接口的很像,只是基本上第一个参数都成了sql。

其中Object value为入参,入参形式和SqlSession中的入参一样,带有入参的方法,在使用时sql可以包含#{param}或${param}形式的参数,这些参数需要通过入参来传值。需要的参数过多的时候,参数可以使用Map类型。另外这种情况下的sql还支持下面这种复杂形式:

String sql = "";

这种情况用的比较少,不多说。

不带有Object value的所有方法,sql中如果有参数需要手动拼接成一个可以直接执行的sql语句。

在selectXXX方法中,使用Class resultType可以指定返回类型,否则就是Map类型。

实例化SqlMapper

SqlMapper构造参数public SqlMapper(SqlSession sqlSession),需要一个入参SqlSession sqlSession,在一般系统中,可以按照下面的方式获取:

SqlSession sqlSession = (...);//通过某些方法获取sqlSession
//创建sqlMapper
SqlMapper sqlMapper = new SqlMapper(sqlSession);

如果使用的Spring,那么可以按照下面的方式配置:


 

在Service中使用的时候可以直接使用@Autowired注入。

简单例子

在src/test/java目录的com.github.abel533.sql包中包含这些方法的测试。

下面挑几个看看如何使用。

selectList

//查询,返回List
List> list = sqlMapper.selectList("select * from country where id <11");
//查询,返回指定的实体类
List countryList = sqlMapper.selectList("select * from country where id <11", Country.class);
//查询,带参数
countryList = sqlMapper.selectList("select * from country where id <#{id}", 11, Country.class);
//复杂点的查询,这里参数和上面不同的地方,在于传入了一个对象
Country country = new Country();
country.setId(11);
countryList = sqlMapper.selectList("", country, Country.class);

selectOne

Map map = sqlMapper.selectOne("select * from country where id = 35");
map = sqlMapper.selectOne("select * from country where id = #{id}", 35);
Country country = sqlMapper.selectOne("select * from country where id = 35", Country.class);
country = sqlMapper.selectOne("select * from country where id = #{id}", 35, Country.class);

insert,update,delete

//insert
int result = sqlMapper.insert("insert into country values(1921,'天朝','TC')");
Country tc = new Country();
tc.setId(1921);
tc.setCountryname("天朝");
tc.setCountrycode("TC");
//注意这里的countrycode和countryname故意写反的
result = sqlMapper.insert("insert into country values(#{id},#{countrycode},#{countryname})"
             , tc);
//update
result = sqlMapper.update("update country set countryname = '天朝' where id = 35");
tc = new Country();
tc.setId(35);
tc.setCountryname("天朝");
int result = sqlMapper.update("update country set countryname = #{countryname}" + 
      " where id in(select id from country where countryname like 'A%')", tc);
//delete
result = sqlMapper.delete("delete from country where id = 35");
result = sqlMapper.delete("delete from country where id = #{id}", 35);

注意

通过上面这些例子应该能对此有个基本的了解,但是如果你使用参数方式,建议阅读下面的文章:

深入了解MyBatis参数

实现原理

最初想要设计这个功能的时候,感觉会很复杂,想的也复杂,需要很多个类,因此当时没有实现。

突发奇想,设计了现在的这种方式。并且有种强烈的感觉就是幸好昨天没有尝试去实现,因为昨天晚上思考这个问题的时候是晚上10点多,而今天晚上7点开始思考。我很庆幸在一个更清醒的状态下去写这段代码。

下面简单说思路和实现方式。

在写MyBatis分页插件的时候熟悉了MappedStatement类。

在写通用Mapper的时候熟悉了xml转SqlNode结构。

如果我根据SQL动态的创建一个MappedStatement,然后使用MappedStatement的id在sqlSession中执行不就可以了吗?

想到这一点,一切就简单了。

看看下面select查询创建MappedStatement的代码:

/**
 * 创建一个查询的MS
 * @param msId
 * @param sqlSource 执行的sqlSource
 * @param resultType 返回的结果类型
 */
private void newSelectMappedStatement(String msId, SqlSource sqlSource, final Class<&#63;> resultType) {
  MappedStatement ms = new MappedStatement.Builder(
      configuration, msId, sqlSource, SqlCommandType.SELECT)
    .resultMaps(new ArrayList() {
      {
        add(new ResultMap.Builder(configuration,
            "defaultResultMap",
            resultType,
            new ArrayList(0)).build());
      }
    })
    .build();
  //缓存
  configuration.addMappedStatement(ms);
}

代码是不是很简单,这段代码的关键是参数sqlSource,下面是创建SqlSource的方法,分为两种。

一种是一个完整的sql,不需要参数的,可以直接执行的:

StaticSqlSource sqlSource = new StaticSqlSource(configuration, sql);

其中configuration从sqlSession中获取,sql就是用户传入到sql语句,是不是也很简单?

另一种是支持动态sql的,支持参数的SqlSource:

SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, parameterType);

是不是也很简单?这个方法其实可以兼容上面的StaticSqlSource,这里比上面多了一个parameterType,因为这儿是可以传递参数的,另外languageDriver是从configuration中获取的。

是不是很简单?

我一开始也没想到MyBatis直接执行sql实现起来会这么的容易。

insert,delete,update方法的创建更容易,因为他们的返回值都是int,所以处理起来更简单,有兴趣的可以查看SqlMapper的源码。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对的支持。如果你想了解更多相关内容请查看下面相关链接


推荐阅读
  • 本章详细介绍SP框架中的数据操作方法,包括数据查找、记录查询、新增、删除、更新、计数及字段增减等核心功能。通过具体示例和详细解析,帮助开发者更好地理解和使用这些方法。 ... [详细]
  • PHP 5.2.5 安装与配置指南
    本文详细介绍了 PHP 5.2.5 的安装和配置步骤,帮助开发者解决常见的环境配置问题,特别是上传图片时遇到的错误。通过本教程,您可以顺利搭建并优化 PHP 运行环境。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 本文详细介绍了如何在 Spring Boot 应用中通过 @PropertySource 注解读取非默认配置文件,包括配置文件的创建、映射类的设计以及确保 Spring 容器能够正确加载这些配置的方法。 ... [详细]
  • 本文详细介绍了 Java 中 org.apache.xmlbeans.SchemaType 类的 getBaseEnumType() 方法,提供了多个代码示例,并解释了其在不同场景下的使用方法。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 本文探讨了在Windows Server 2008环境下配置Tomcat使用80端口时遇到的问题,包括端口被占用、多项目访问失败等,并提供详细的解决方法和配置建议。 ... [详细]
  • 科研单位信息系统中的DevOps实践与优化
    本文探讨了某科研单位通过引入云原生平台实现DevOps开发和运维一体化,显著提升了项目交付效率和产品质量。详细介绍了如何在实际项目中应用DevOps理念,解决了传统开发模式下的诸多痛点。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 配置PHPStudy环境并使用DVWA进行Web安全测试
    本文详细介绍了如何在PHPStudy环境下配置DVWA( Damn Vulnerable Web Application ),并利用该平台进行SQL注入和XSS攻击的练习。通过此过程,读者可以熟悉常见的Web漏洞及其利用方法。 ... [详细]
author-avatar
mobiledu2502909783
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有