首页 > 其他分享 >mybatis 基本使用

mybatis 基本使用

时间:2023-02-20 16:44:07浏览次数:44  
标签:基本 语句 username MyBatis 使用 mybatis 默认值 where id

本文为笔者参考官方文档的简单学习笔记,更详细和权威信息请参考官方文档:MyBatis中文网

环境配置

springboot 框架下

参考:SpringBoot整合MyBatis - 临安剑客 - 博客园 (cnblogs.com)

XML 映射器

select

映射查询语句

<select id="selectPerson" parameterType="int" resultType="hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>

select 的元素属性

属性 描述
id 命名空间中唯一的标识符,可以被用来引用这条语句(相当于封装了 sql 语句的函数名
parameterType 传入这条语句的参数的类全限定名或别名。这个属性是可选的。因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
resultType 期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。
resultMap 对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。 resultType 和 resultMap 之间只能同时使用一个。
flushCache 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。
useCache 将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true。
timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
fetchSize 这是一个给驱动的建议值,尝试让驱动程序每次批量返回的结果行数等于这个设置值。 默认值为未设置(unset)(依赖驱动)。
statementType 可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
resultSetType FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖数据库驱动)。
databaseId 如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。
resultOrdered 这个设置仅针对嵌套结果 select 语句:如果为 true,将会假设包含了嵌套结果集或是分组,当返回一个主结果行时,就不会产生对前面结果集的引用。 这就使得在获取嵌套结果集的时候不至于内存不够用。默认值:false
resultSets 这个设置仅适用于多结果集的情况。它将列出语句执行后返回的结果集并赋予每个结果集一个名称,多个名称之间以逗号分隔。

insert, update 和 delete

数据变更语句 insert,update 和 delete 的实现非常接近

<insert id="insertAuthor">
  insert into Author (id,username,password,email,bio)
  values (#{id},#{username},#{password},#{email},#{bio})
</insert>

<update id="updateAuthor">
  update Author set
    username = #{username},
    password = #{password},
    email = #{email},
    bio = #{bio}
  where id = #{id}
</update>

<delete id="deleteAuthor">
  delete from Author where id = #{id}
</delete>

insert, update 和 delete 的元素属性

属性 描述
id 命名空间中唯一的标识符,可以被用来引用这条语句(相当于封装了 sql 语句的函数名
parameterType 传入这条语句的参数的类全限定名或别名。这个属性是可选的。因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
flushCache 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:(对 insert、update 和 delete 语句)true。
timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
statementType 可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
useGeneratedKeys (仅适用于 insert 和 update)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。
keyProperty (仅适用于 insert 和 update)指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)。如果生成列不止一个,可以用逗号分隔多个属性名称。
keyColumn (仅适用于 insert 和 update)设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第一列的时候,是必须设置的。如果生成列不止一个,可以用逗号分隔多个属性名称。
databaseId 如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。

sql

这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值。

<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>

这个 SQL 片段可以在其它语句中使用:

<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/></include>,
    <include refid="userColumns"><property name="alias" value="t2"/></include>
  from some_table t1
    cross join some_table t2
</select>

也可以在 include 元素的 refid 属性或内部语句中使用属性值(相当于嵌套)

<sql id="sometable">
  ${prefix}Table
</sql>

<sql id="someinclude">
  from
    <include refid="${include_target}"/>
</sql>

<select id="select" resultType="map">
  select
    field1, field2, field3
  <include refid="someinclude">
    <property name="prefix" value="Some"/>
    <property name="include_target" value="sometable"/>
  </include>
</select>

参数

参数类型(parameterType)会被自动设置为 int

<select id="selectUsers" resultType="User">
  select id, username, password
  from users
  where id = #{id}
</select>

传入一个复杂的对象。指定参数类型后,自动查找该类型的属性用于 sql 中的变量。

<insert id="insertUser" parameterType="User">
  insert into users (id, username, password)
  values (#{id}, #{username}, #{password})
</insert>

给参数指定一个特殊的数据类型。

#{property,javaType=int,jdbcType=NUMERIC}

JDBC 要求,如果一个列允许使用 null 值,并且会使用值为 null 的参数,就必须要指定 JDBC 类型(jdbcType)。

自定义类型处理方式,可以指定一个特殊的类型处理器类(或别名)。

#{age,javaType=int,jdbcType=NUMERIC,typeHandler=MyTypeHandler}

对于数值类型,还可以设置 numericScale 指定小数点后保留的位数。

#{height,javaType=double,jdbcType=NUMERIC,numericScale=2}

字符串替换

使用 ${} 而不是 #{} 即可。

例如:

@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);

用这种方式接受用户的输入,并用作语句参数是不安全的,会导致潜在的 SQL 注入攻击。因此,要么不允许用户输入这些字段,要么自行转义并检验这些参数。

结果映射

resultMap 元素是 MyBatis 中最重要最强大的元素。

ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

简单映射语句的示例,它们没有显式指定 resultMap

<select id="selectUsers" resultType="map">
  select id, username, hashedPassword
  from some_table
  where id = #{id}
</select>

上述语句只是简单地将所有的列映射到 HashMap 的键上,这由 resultType 属性指定。

JavaBean 可以被映射到 ResultSet,就像映射到 HashMap 一样简单。

<select id="selectUsers" resultType="com.someapp.model.User">
  select id, username, hashedPassword
  from some_table
  where id = #{id}
</select>

类型别名。

<!-- mybatis-config.xml 中 -->
<typeAlias type="com.someapp.model.User" alias="User"/>

<!-- SQL 映射 XML 中 -->
<select id="selectUsers" resultType="User">
  select id, username, hashedPassword
  from some_table
  where id = #{id}
</select>

注:springboot 中不使用 mybatis-config.xml 文件时,只需要在 yml 文件中作如下配置。

mybatis:
     type-aliases-package: com.someapp.model

这些情况下,MyBatis 会在幕后自动创建一个 ResultMap,再根据属性名来映射列到 JavaBean 的属性上。如果列名和属性名不能匹配上,可以在 SELECT 语句中设置列别名(这是一个基本的 SQL 特性)来完成匹配。

<select id="selectUsers" resultType="User">
  select
    user_id             as "id",
    user_name           as "userName",
    hashed_password     as "hashedPassword"
  from some_table
  where id = #{id}
</select>

显式使用外部的 resultMap 会怎样,这是解决列名不匹配的另外一种方式。

<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>

高级结果映射 等请参考官方文档:XML 映射器_MyBatis中文网

动态 SQL

if

使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分。比如:

<select id="findActiveBlogWithTitleLike" resultType="Blog">
  SELECT * FROM BLOG
  WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
</select>

choose、when、otherwise

从多个条件中选择一个使用。

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

trim、where、set

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>

也可以通过自定义 trim 元素来定制 where 元素的功能。比如,和 where 元素等价的自定义 trim 元素为:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

用于动态更新语句的类似解决方案叫做 setset 元素可以用于动态包含需要更新的列,忽略其它不更新的列。比如:

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>

这个例子中,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

set 元素等价的自定义 trim 元素。

<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

foreach

对集合进行遍历(尤其是在构建 IN 条件语句的时候)。

<select id="selectPostIn" resultType="domain.blog.Post">
  SELECT *
  FROM POST P
  WHERE ID in
  <foreach item="item" index="index" collection="list" open="(" separator="," close=")">
        #{item}
  </foreach>
</select>

script

要在带注解的映射器接口类中使用动态 SQL,可以使用 script 元素。

@Update({"<script>",
  "update Author",
  "  <set>",
  "    <if test='username != null'>username=#{username},</if>",
  "    <if test='password != null'>password=#{password},</if>",
  "    <if test='email != null'>email=#{email},</if>",
  "    <if test='bio != null'>bio=#{bio}</if>",
  "  </set>",
  "where id=#{id}",
  "</script>"})
void updateAuthorValues(Author author);

更多请参考官方文档:动态 SQL_MyBatis中文网

使用

主要为 springboot 框架中使用

mapper 包下的接口:

@Mapper
public interface ExpertMapper {
}

xml 映射文件写法

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.cloud.mapper.ExpertMapper">
    
</mapper>

注解开发:

@Select("select * from `role` where `name`=#{name}")
Role findByName(String name);

其它注解:(常用)

注解 使用对象 XML等价形式 描述
@Param 参数 N/A 如果你的映射方法接受多个参数,就可以使用这个注解自定义每个参数的名字。否则在默认情况下,除 RowBounds 以外的参数会以 "param" 加参数位置被命名。例如 #{param1}, #{param2}。如果使用了 @Param("person"),参数就会被命名为 #{person}
@Insert @Update @Delete @Select 方法 <insert> <update> <delete> <select> 每个注解分别代表将会被执行的 SQL 语句。它们用字符串数组(或单个字符串)作为参数。如果传递的是字符串数组,字符串数组会被连接成单个完整的字符串,每个字符串之间加入一个空格。这有效地避免了用 Java 代码构建 SQL 语句时产生的“丢失空格”问题。当然,你也可以提前手动连接好字符串。属性:value,指定用来组成单个 SQL 语句的字符串数组。
@ResultMap 方法 N/A 指定结果映射
@ResultType 方法 N/A 指定结果类型

更多请参考官网:Java API_MyBatis中文网

标签:基本,语句,username,MyBatis,使用,mybatis,默认值,where,id
From: https://www.cnblogs.com/huang-guosheng/p/17137971.html

相关文章

  • Spring boot中使用aop详解
    aop是spring的两大功能模块之一,功能非常强大,为解耦提供了非常优秀的解决方案。现在就以springboot中aop的使用来了解一下aop。一:使用aop来完成全局请求日志处理创建一个spri......
  • 使用独立服务器有啥好处呢
    使用独立服务器有啥好处呢1、独立服务器,在运用上,愈加的安全,由于所用的资源全部是本人一个人运用,完全可控,而不会受别人运用的影响,扫除未知的安全隐患。2、关于优化来说,更有......
  • [Linux] 使用管道进行进程间通信
    什么是管道父进程向子进程发送消息#include<stdio.h>#include<unistd.h>#include<string.h>#include<errno.h>intmain(){ intfd[2]; intret=pipe(fd);......
  • Miniconda安装及使用
    一、Miniconda安装首先使用下面的地址安装Miniconda,我使用的是windows环境,python3.10Miniconda—condadocumentation安装完使用"AnacondaPowershellPrompt(minic......
  • TypeScript 学习笔记 — 类的基本用法(五)
    目录TS中定义类类中实例属性、方法+修饰符publicprotectedprivatereadonly实例方法类中原型属性、方法+访问器原型属性+访问器原型方法类中静态属性、方法子类重写......
  • Python之装饰器的使用
    1.装饰器的使用场景函数执行时间的统计输出日志信息2.装饰器实现已有函数执行时间的统计importtime#装饰器函数defget_time(func):definner():begin=ti......
  • 商法的基本概念和特征
    商法总论一、基础概念商在我国商法中,”商“在限定法律关系主体时,是指商人和企业等商事主体。在限定事业和行为时,是指盈利事业和商行为。商事商人从事的以盈利为目的的各种......
  • [MFC] 1. TeeChart的安装与使用
    环境:VS2017+TeeChart5由于毕设被迫需要使用MFC来设计程序(这显然是个很糟糕的选择),在安装与使用TeeChart插件时出现了许多问题。在2023年间我们尝试去使用1992年的技术时......
  • MongoDB和Elasticsearch的各使用场景对比
    MongoDBvsElasticsearchMongoDBElasticSearch备注定位(文档型)数据库(文档型)搜索引擎一个管理数据,一个检索数据资源占用一般高mongo使用c++,es......
  • C++ getline整行读入以及使用stringstream 按分隔字符split出单词
    问题:直接通过while(cin>>str),遇到空格就会停止。比如,输入dfahadfjdjfak只能输入前两个单词。解决:要读入一整行,需通过getline(cin,inputLine)读入。按分隔符split字......