草庐IT

MyBatis的使用

筑梦小子 2024-01-05 原文

目录

一.Sring项目中关于MyBatis的配置

1.在pom.xml中引入框架依赖

2.配置文件配置相关信息

 3.设置mapper中的xml文件内容

4.根据以上配置实现的查询示例

(1)添加实体类

(2)添加mapper接口

(3)添加UserMapper.xml

(4)server层的调用

(5)controller层的调用

(6)前端访问后端路径

二.有关mybatis中xml对于数据库操作的具体使用

1.插入操作

2.删除操作

3.修改操作

4.查询操作

 三.Mybatis进阶操作

1.参数占位符

2.like查询

3.多表查询

(1)一对一查询

(2)一对多查询 

4.动态查询(if,trim,where,set,foreach的使用)

(1)if

(2)trim

(3)where

(4)set

(5)foreach


一.Sring项目中关于MyBatis的配置

1.在pom.xml中引入框架依赖

这里手动进行添加,通过在已有的spring项目中的pom.xml文件中引入以下依赖

<!-- 添加 MyBatis 框架 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!-- 添加 MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>

2.配置文件配置相关信息

在application.properties中配置以下内容

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/blog?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
#配置mybatis的xml文件路径
mybatis.mapper-locations=classpath:mapper/**Mapper.xml

这里关于xml文件路径配置的匹配规则是在当前mapper下所有文件名以Mapper.xml结尾的文件。

如下所示:

 3.设置mapper中的xml文件内容

 其中mapper中需要配置的内容有如下:

<?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="org.example.mapper.UserMapper">

</mapper>

mapper里面就是对于CRUD操作的一些语句,只不过这些语句头需要遵守一些约束和规定,之后才能转化为java对象,并作为返回值返回给java中调用的方法。

4.根据以上配置实现的查询示例

查询前的配置:

(1)添加实体类

(2)添加mapper接口

(3)添加UserMapper.xml

将查询到的结果集会自动装配到配置的resultMap中

(4)server层的调用

 mapper里面的指定方法被调用后会通过之前配置的xml和对应的路径会执行xml文件中的方法

(5)controller层的调用

 定义service层,然后在该层调用mapper中的方法

(6)前端访问后端路径

 通过postman来通过url来访问该资源下的路径

 上面就是使用mybatis来对数据库操作的整个流程,接下来就是一些有关xml中关于CRUD语句的具体操作和配置。

二.有关mybatis中xml对于数据库操作的具体使用

1.插入操作

seGeneratedKeys: MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键,默认值:false。
keyColumn:设置生成键值在数据库表中的列名;如果生成列不止一个,可以用逗号分隔多个属性名称。
keyProperty:指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)。如果生成列不止一个,可以用逗号分隔多个属性名称。

controller层

 service层

 mapper层

通过接口插入成功的显示

 UserMapper.xml中的sql代码:

    <insert id="insertOne" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
        insert
        into
         user(username, password, nickname)
        values (#{username},#{password},#{nickname})
    </insert>

2.删除操作

基于xml文件配置好的前提下,然后在xml文件中写sql操作

 通过构造前端接口,来调用mybatis中的sql来进行验证,执行顺序如下:

3.修改操作

 

 

4.查询操作

对于查询操作来说,需要在xml中配置结果集映射,因为需要将查找中的数据映射为一个java对象。

首先在xml文件中使用resultMap,然后设置id,之后的查询语句需要根据该id来进行转化为type中的对象,其中type中为model类的位置(类路径),然后里面就是关于映射关系的指定,其中id是数据库中关于主键的映射,如果不是主键,就使用result,对于属性中的参数,如column是数据库中的字段名,而property是类的成员变量。

<!--    这里是配置有关查询到的结果集转化为哪一个-->
<!--    column代表数据库中的字段-->
    <resultMap id="ResultBaseMap" type="org.example.model.User">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="password" property="password"></result>
        <result column="nickname" property="nickname"></result>
        <result column="github" property="github"></result>
        <result column="head" property="head"></result>
    </resultMap>

 三.Mybatis进阶操作

1.参数占位符

#{}是预编译占位符,在处理是,会将该位置的数据先转化为?,然后在执行PreparedStament中的set方法时,将?替换变量值。如果是字符串,会添加""。

${}是直接进行替换为变量的值,存在sql注入问题。

假如传递的数据是sort ,对于#{},最终会处理成"sort",而${}就是sort。

2.like查询

在使用like的时候,一般是模糊查询,在mybatis中需要使用concat函数来将%与#{变量值}来进行拼接。

concat(str1, str2, str3...)是将str1和str2和str3等全部进行拼接起来。

<!--    like查询-->
    <select id="selectLike" resultMap="ResultBaseMap">
        select
        id,
        username,
        password
        from
        user
        where password like concat('%',#{password},'%');
    </select>

 

3.多表查询

(1)一对一查询

对于多表查询时,都需要使用resultMap来进行配置,在配置前还需要给对象中添加新的属性。例如一个用户登录表和用户信息表之间的关系是一对一,在进行关联查询的时候首先需要给User类中添加一个Message类型的成员变量,然后再在resultMap中除了配置有关User信息的属性外,还需要添加一个<association property=""  resultMap="" columnPrefix="">属性.

property是在User中新添加的成员message,  resultMap是需要关联的结果集的映射,而columnPrefix是对于查询的结果字段添加前缀,如果两个表中右重复字段,可以通过该字段进行区分,之后在associate中配置的resultMap中会去除掉前缀进行匹配。

<!--    一对一关联自己的message信息-->
    <resultMap id="ResultBaseMap2" type="org.example.model.User">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="password" property="password"></result>
        <result column="nickname" property="nickname"></result>
        <result column="github" property="github"></result>
        <result column="head" property="head"></result>
        <association property="message" resultMap="org.example.mapper.UMMapper.BaseResultMap"
                     columnPrefix="m_"></association>
    </resultMap>
<!--    一对一关联查询-->
    <select id="onebyone" resultMap="ResultBaseMap2">
        select
        u.id,
        u.username,
        m.id_card m_id_card,
        m.id m_id,
        m.user_id m_user_id
        from user u left join message m on u.id=m.user_id;
    </select>

 查询和配置关系

 

(2)一对多查询 

对于一个用户表和文章表的关系是一对多,一个用户可以有多篇文章,Mybatis中也是通过resultMap来对查询结果集进行配置,然后再对查询结果中映射的对象中添加一个新的集合属性(因为是一对多关系),和一对一不同的是resultMap中设置的是collection属性,其他的配置规则基本不变。

<!--    这里是配置有关查询到的结果集转化为哪一个-->
<!--    column代表数据库中的字段-->
    <resultMap id="ResultBaseMap" type="org.example.model.User">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="password" property="password"></result>
        <result column="nickname" property="nickname"></result>
        <result column="github" property="github"></result>
        <result column="head" property="head"></result>
        <collection property="articles" resultMap="org.example.mapper.ArticleMapper.ResultBaseMap"
                    columnPrefix="a_"></collection>
    </resultMap>


<!--关联查询,一个用户对应多篇文章-->
<select id="selectUserAndArticle" resultMap="ResultBaseMap">
        select
        u.id,
        u.username,
        u.password,
        u.nickname,
        u.github,
        u.head,
        a.id a_id,
        a.title a_title,
        a.date a_date,
        a.content a_content
         from user u join article a on u.id=a.user_id
</select>

 

 

4.动态查询(if,trim,where,set,foreach的使用)

(1)if

标签为:<if test="属性值不为空"> </if>

如果对于一个参数是否传递是不确定的(可能为空或不为空),我们可以使用if来进行判断,如果传了就在sql中显示,没有传就不显示。

如注册用户时,有些信息可以不用传递,如头像等,这时候就可以在mybatis中使用if来进行过滤该参数。

    <insert id="insertSelective">
        insert into user(
        username,
        nickname,
        password
        <if test="head!=null"> ,head </if>
        <if test="github!=null"> ,github </if>
    )
        values (
        #{username},
        #{nickname},
        #{password}
        <if test="head!=null"> ,#{head} </if>
        <if test="github!=null"> ,#{github} </if>
        )
    </insert>

 

(2)trim

首先trim标签中有多个参数,分别为:

prefix=“”  表示整个语句块以prefix中的内容作为前缀

suffix=“”   表示整个语句块以suffix中的内容作为后缀

prefixOverrides=“”  表示整个语句块要去掉的前缀

suffixOverrides=“”  表示整个语句块要去掉的后缀

以之前的选择插入语句为例,来使用上面的参数:

    <insert id="insertParam">
        insert into user
         <trim prefix="(" suffix=")" suffixOverrides=",">
             <if test="username!=null">
                 username,
             </if>
             <if test="nickname!=null">
                 nickname,
             </if>
             <if test="password!=null">
                 password,
             </if>
             <if test="github!=null">github</if>
         </trim>
        <trim prefix="values(" suffix=")" suffixOverrides=",">
            <if test="username!=null">
                #{username},
            </if>
            <if test="nickname">
                #{nickname},
            </if>
            <if test="password!=null">
                #{password},
            </if>
            <if test="github!=null">
                #{github},
            </if>
        </trim>
    </insert>

(3)where

<where></where>是用在条件查询中(也可以使用上面的trim),对于where中的<if></if>里面的内容,写成and 属性名=属性值,之后会自动去掉第一个and。

如下所示,如果传递的password和username不为空,就根据这两个条件进行过滤:

    <select id="selectByWhere" resultMap="BaseResultMap">
        select * from user
        <where>
            <if test="password!=null">
                and password=#{password}
            </if>
            <if test="username!=null">
                and username=#{username}
            </if>
        </where>
    </select>

(4)set

用于sql修改中,会自动去除掉set中的if属性中的.

    <update id="updateSet">
        update user
        <set>
            <if test="username!=null">
                username=#{username},
            </if>
            <if test="nickname!=null">
                nickname=#{nickname},
            </if>
            <if test="password!=null">
                password=#{password},
            </if>
        </set>
        where id=#{id}
    </update>

(5)foreach

可以对于传入的集合进行遍历,里面的参数如下所示:

collection:用于绑定方法参数中的集合

item:遍历时的每一个对象

open:语句块开头的字符串

close:语句块结束的字符串

separator:每次遍历之间的分隔符

示例,根据list中的id号来进行批量删除:

   
 <delete id="deleteByIds">
        delete from user where id in <foreach collection="list" open="(" close=")" separator="," item="item">
        #{item}
    </foreach>
    </delete>

 

有关MyBatis的使用的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  9. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  10. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

随机推荐