【Mybatis】mybatis使用与理解

news2024/11/25 12:57:08

1. mybatis基础环境搭建

        若想使用mybatis,需要有如下两个jar包:①mybatis的核心jar包。②数据库驱动包。

(想使用别人提供的服务就必须要有别人的jar包;mybatis是和数据库打交道的,那么你的程序中,数据库的驱动包也是必不可少的。)

        Maven依赖如下:

<!-- mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.20</version>
</dependency>

2.  mybatis核心配置文件

        在导入了上面两个jar包之后,我们需要为程序提供必要的信息才能使mybatis正常执行,以及如果我们需要使用mybatis提供的一些功能也需要进行相关的配置,而这些信息就写在核心配置文件中。

        mybatis的配置文件为xml文件。核心配置文件基本内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置环境信息 -->
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="数据库url"/>
                <property name="username" value="用户名"/>
                <property name="password" value="密码"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 配置映射文件 -->
    <mappers>
        <mapper resource="mappers"></mapper>
    </mappers>
</configuration>

        这是mybatis最基本的配置信息,其中包含:①事务处理方式。②数据源。③映射文件位置。

对于要使用mybatis的程序,一定要考虑如下问题:

①事务是怎么处理的。②数据源是什么。③映射文件在哪。

3. mapper和映射文件

        mapper是java接口,就是DAO,不过我们不需要提供实现类,mybatis会在程序执行时根据映射文件的内容来为mapper接口生成动态代理类,这些动态代理类的方法就是我们在接口中的方法的实现。

mapper接口:

public interface UserMapper {
    public int create(String name);
    public int remove(int id);
}

映射文件:

<?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接口全类名一致 -->
<mapper namespace="com.test.mappers.UserMapper">
<!-- SQL标签id和接口的方法名一致 -->
<!--    public int create(String name);-->
    <insert id="create">
        insert into `user` (`name`) values (#{name,jdbcType=VARCHAR})
    </insert>
<!--    public int remove(int id);-->
    <delete id="remove">
        delete from `user` where `id`=#{id,jdbcType=INTEGER}
    </delete>
</mapper>

        这里我们要问:为什么我们不用写接口的实现却可以在程序中直接使用mapper接口的方法?mybatis怎么知道我们的方法要实现什么功能?

        显然,如果没有任何的信息,mybatis也是不可能知道我们的mapper接口的方法要实现什么功能,所以我们需要给mybatis提供相应的信息,告诉mybatis我们需要实现什么功能。那我们要怎么告诉mybatis呢?核心配置文件是用来写主要的配置信息的,而我们的mapper接口会有很多,显然如果把与接口有关的所有信息都写在核心配置文件中不太合适。但是,我们在配置文件中可以看到有映射文件位置这一配置,那么我们就可以把与接口有关的信息写在映射文件中,mybatis在为接口创建动态代理类时只需要到映射文件中找相关的信息就可以了。这样既把接口相关的信息告诉了mybatis又不会使核心配置文件变的臃肿。而事实上映射文件的作用也就是这样。

        解决了怎么把信息传递给mybatis,接下来是我们要传递什么信息给mybatis呢?

        首先,我们需要告诉mybatis,哪个映射文件保存了哪个mapper接口的信息;其次,我们需要告诉mybatis我们的接口的方法要实现什么功能。

这就有了以下两个规则:

①映射文件的命名空间和mapper接口的全类名必须保持一致。

(用来表示哪个映射文件保存了哪个mapper接口的信息。

②mapper接口的方法名和映射文件中编写SQL的标签的id属性保存一致。

(用来表示编写的SQL标签写的是哪个方法的相关信息。)

4.使用mybatis创建的Mapper接口动态代理类

总体流程如下:

代码如下:

public class Main {
    public static void main(String[] args) throws IOException {
        // 获取核心配置文件的输入流
        InputStream is= Resources.getResourceAsStream("mybatis-config.xml");
        // 创建SqlSessionFactoryBuilder
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();
        // 获取SqlSessionFactory
        SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(is);
        // 获取SqlSession,这里传入的true和false是用来表示是否自动提交
        SqlSession sqlSession=sqlSessionFactory.openSession(true);
        // 获取XxxMapper接口的动态代理类
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
        // 调用相关方法
        userMapper.create("张三");
        userMapper.create("李四");
        userMapper.remove(2);
    }
}

5. mybatis获取参数

        我们在开发中经常需要使用不同的参数来执行同样的代码,如插入数据时每次的代码相同只是参数的数据不同,那么我们要怎么把这些参数设置到我们的SQL语句中呢?

        我们的参数只能靠接口方法的形参传入进来,传进来以后,mybatis提供了两种方式来获取形参中的值:①${}。②#{}。我们可以直接在映射文件中使用上面两个表达式来获取参数的值并将参数的值设置到SQL语句中,实现参数的传递与获取。

        这两种方式的区别在于:#{}相当于占位符,它在把数据设置到SQL语句中时会为数据加上单引号,而${}相当于字符串拼接,它在把数据设置到SQL语句中时不会为数据加上单引号。

        根据接口方法形参的形式不同我们有不同的获取方式:

①如果接口方法形参只有一个参数,我们可以直接#{}或${}中间加任意值来获取传入的参数。

<!-- public void updateName(String name) -->

<update id="updateName">

        update `user` set `name` = #{newName} where `name`="李四"

</update>

②如果接口方法形参是实体类型或map集合,可以使用#{属性名或键名}来获取(${}同理)。

<!-- public void delete(User user) -->

<delete id="delete">

        delete from `user` where  `name`=#{userName} and `id`=#{userId}

</delete>

③如果接口方法有多个形参,这些形参会被放入到一个map集合中,以arg0,arg1...或param1,param2...为键,参数值为值,则转换为②的情况获取参数的值。

<!-- public void delete(String name,Int id) -->

<delete id="delete">

        delete from `user` where `name`=#{arg0} and `id`=#{arg1}

</delete> 

④如果在接口方法的参数上加了@param注解,则我们要用注解中标记的内容为键才能获取参数的值。

<!-- public void delete(@param(value="myName")String name,

                                    @param(value="id")Int myId) -->

<delete id="delete">

        delete from `user` where `name`=#{myName} and `id`=#{myId}

</delete> 

        如果传入的参数是一个实体类对象,我们获取参数值的方式是:#{属性名},这里不是调用方法,但是我们可能是把属性声明为private的,这样不禁问:怎么可以直接使用属性名来获取属性值呢? 所以,我们需要在实体类中为对应的属性声明get()/set()方法。

6. mybatis的查询

        select标签需要设置resultType或resultMap来设置查询的返回值的映射情况。

        使用resultType会按照设置的类型的属性来和查询结果自动匹配。使用resultMap会按照自己设置的匹配规则来匹配。

    <select id="select" resultMap="all">
        select * from `regist_email`
        <where>
            <if test="id!=null">
                and `id`=#{id}
            </if>
            <if test="email!=null">
                and `email`=#{email}
            </if>
            <if test="code!=null">
                and `code`=#{code}
            </if>
            <if test="createTime!=null">
                and `create_time`=#{createTime}
            </if>
        </where>
    </select>

7. resultMap

        resultMap标签的id用来设置当前resultMap标签的唯一标识,type用来设置该resultMap表示的查询结果要映射的实体类。

        result子标签用来设置映射关系,property表示实体类的属性,column表示查询结果的一列。

        id子标签用来设置主键的映射关系,property表示实体类的属性,column表示查询结果的一列。

        association子标签用来设置多对一的关系,其有两种方法:①使用该标签的property表示实体类的属性名,JavaType表示该属性对应的java类,之后用association标签的result和id子标签来继续设置映射关系。②使用association标签的property来表示实体类的属性名,select来设置查询这个属性值的SQL语句和使用column来设置传入给SQL语句的参数。

        collection子标签用来设置一对多的关系,其有两种方法:①使用该标签的property表示要设置的属性,ofType来设置该属性的个体的类型,之后再使用result和id子标签来设置其他对应关系。②使用该标签的property来表示要设置的属性,select来设置查询语句,column来设置要传入的数据。

        这里需要注意的是:MySQL中的DateTime数据类型在java中使用Timestamp类来接收。

    <resultMap id="all" type="com.coward.entity.RegistEmail">
        <id property="id" column="id"></id>
        <result property="email" column="email"></result>
        <result property="code" column="code"></result>
        <result property="createTime" column="create_time"></result>
    </resultMap>

 

8. 查询结果的返回

        查询结果可分两部分:①单条记录的封装。②整个查询结果的封装。

        单条记录的封装可以直接封装到实体类中,只需要在select标签的resultType上设置相对应的映射就可以。也可以封装到一个map中,以列为键,查询结果为值,这时候把resultType设置成map即可。

        整个查询结果,只需要设置方法的返回值即可进行对应的封装。如果是只有一条记录可以直接返回封装的类型。如果是多条记录,可以返回list类型或map类型,mybatis会把一条条封装后的记录放入相对应的list或map中。如果是map则需要在接口方法上使用@MapKey来设置作为键值的属性。

        因为在封装查询结果为对象的过程中需要创建对象,所以要求在实体类中有对应的构造方法用于创建对象。同时对象创建过程中调用的构造方法的形参顺序和查询结果一一对应,所以哪怕数据全部提供也可能会出现形参和实参位置不匹配的情况,所以要写好查询语句和构造方法。

9. 动态SQL

if标签:test属性为true时执行标签中的内容。

where标签:结合if标签使用,如果where内部的if标签的test全为false则不生效;如果不全为false则会在标签内容前面加上where,并且会删掉where后面紧跟的and。

    <select id="select" resultMap="all">
        select * from `regist_email`
        <where>
            <if test="id!=null">
                and `id`=#{id}
            </if>
            <if test="email!=null">
                and `email`=#{email}
            </if>
            <if test="code!=null">
                and `code`=#{code}
            </if>
            <if test="createTime!=null">
                and `create_time`=#{createTime}
            </if>
        </where>
    </select>

choose、when、otherwise: 类似于if...else if...else。

trim:格式化,prefix属性用来为标签体内容加上前置;prefixOverrides属性用来为标签体内容删除指定前缀;suffic属性用来为标签题内容加上后缀;suffixOverrides属性用来为标签贴内容删除指定后缀。

    <insert id="insert">
        INSERT INTO `regist_email` (`id`,`email`,`code`,`create_time`)
        VALUE
        <trim prefix="(" suffix=")">
            <if test="id==null">
                null,<include refid="just3"></include>
            </if>
            <if test="id!=null">
                #{id},<include refid="just3"></include>
            </if>
        </trim>
    </insert>

foreach:collection设置要循环的数组或集合。item设置每次循环的一个数据。separator设置循环体之间的分隔符。open设置开始符。close设置结束符。

注意:在标签的test等属性中,获取参数值只需要直接写参数名即可,不需要写#{}。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/4553.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【MySQL高级】MySQL的锁机制

目录 概述 MyISAM 表锁 InnoDB行锁 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制&#xff08;避免争抢&#xff09;。 在数据库中&#xff0c;除传统的 计算资源&#xff08;如 CPU、RAM、I/O 等&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共…

重装系统后要安装哪些驱动

​重装win10后需要安装驱动吗?win10系统比win7系统高级的地方在于系统内置了很多驱动&#xff0c;这可以省去用户很多安装时间&#xff0c;下面小编来告诉大家重装系统后要安装的驱动有哪些。 工具/原料&#xff1a; 系统版本&#xff1a;windows10系统 品牌型号&#xff1…

mysql8其它新特性

文章目录MySQL8.0新特性新特性1&#xff1a;窗口函数序号函数ROW_NUMBER()函数RANK()函数DENSE_RANK()函数分布函数PERCENT_RANK()CUME_DIST()函数前后函数LAG(expr,n)函数LEAD(expr,n)函数首尾函数FIRST_VALUE(expr)函数LAST_VALUE(expr)函数其它函数NTH_VALUE(expr,n)函数NTI…

Docker 常用命令大全

个人理解 docker中的镜像 就像是咱们java 中的Class &#xff0c;而容器呢 是基于这个镜像构建出的实例 类似于咱java 中 根据Class构造出的一个个实例对象 &#xff0c;本人是初学者 理解有误还请见谅&#xff0c;并麻烦您说说您的看法让彼此相互学习… 按我理解 简言之 doc…

Java-日期类,正则实验

1. 随机产生两个日期时间&#xff0c;输入按时间先后顺序输出 public class RandomDate {SuppressWarnings("deprecation")public static void main(String[] args) throws ParseException {SimpleDateFormat sdf new SimpleDateFormat("yyyy-MM-dd HH:mm:ss&…

二分查找 【模板+中间值问题】

全文目录&#x1f603;前言&#x1f615;二分查找动图演示&#x1f634;代码模板❗️ 使用哪个模板问题 ❗️&#x1f4a2; mid为何1问题 &#x1f4a2;&#x1f603;前言 二分查找也称折半查找&#xff08;Binary Search&#xff09;&#xff0c;它是一种效率较高的查找方法。…

[解决]github上传大文件卡住

0x00 需求 github目前的策略是超过50M的文件不允许上传&#xff0c;推荐使用lfs。 0x01 操作 再把之前提交的commit 回滚&#xff1a; git reset --hard commitId 在配置lfs&#xff1a; git lfs install git lfs track "*.zip" git lfs track "*.jar" git…

【K8S】亲和、反亲和、污点、容忍

文章目录【K8S】亲和、反亲和、污点、容忍K8s调度亲和与反亲和Pod和Node硬亲和和软亲和requiredDuringSchedulingIgnoredDuringExecution&#xff1a;硬策略preferredDuringSchedulingIgnoredDuringExecution&#xff1a;软策略污点与容忍污点&#xff08;Taint&#xff09;污点…

Python学习----基础语法2

布尔类型 布尔本质上是 1 和 0 if 基本语法格式 语法还是比较简单的 , 需要注意的是 , Python是通过空格缩进来判断代码块归属的 ( 不像java这么通过 花括号进行区分 ) , 默认是四个空格 , 你也可以使用两个或者三个等 , 只要全部统一即可 , 但是编辑器会有提示 , 规范是四…

一文带你快速了解ptrdiff_t

简介 ptrdiff_t是C/C标准库中定义的一个与机器相关的数据类型。ptrdiff_t类型变量通常用来保存两个指针减法操作的结果。 ptrdiff_t定义在stddef.h&#xff08;cstddef&#xff09;这个文件内。 ptrdiff_t通常被定义为long int类型。 ptrdiff_t定义在C99标准中。 标准库类…

【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出

文章目录目标代码0.页面结构1.新增按钮和弹出表单&#xff1a;结构2.新增按钮和弹出表单&#xff1a;点击新增弹出表单3.表单样式4.表单验证5.表单的提交和取消功能&#xff1a;接口、mock相关准备6.表单的提交和取消功能提供的数据和接口1-operateFormLabel.js5-user.js效果总…

小程序转App最便捷的方法,附实操

Flutter是谷歌的移动UI框架&#xff0c;可以快速在iOS和Android上构建高质量的原生用户界面。 Flutter可以与现有的代码一起工作。在全世界&#xff0c;Flutter正在被越来越多的开发者和组织使用&#xff0c;并且Flutter是完全免费、开源的。 它也是构建未来的Google Fuchsia应…

计算机网络(一)网络体系结构

layout: post title: 计算机网络&#xff08;一&#xff09;网络体系结构 description: 计算机网络&#xff08;一&#xff09;网络体系结构 tag: 计算机网络 计算机网络计算机网络体系基本概念网络性能指标数据量与数据速率&#xff08;比特率&#xff09;带宽吞吐量时延时延带…

Python入门自学进阶-Web框架——25、DjangoAdmin项目应用-分页与过滤

对于数据很多&#xff0c;就需要将数据进行分页显示&#xff0c;同时还要提供过滤功能。 当配置文件中配置了过滤条件&#xff0c;那就要在显示表信息的时候&#xff0c;显示过滤条件选择项&#xff0c;选择后进行过滤&#xff0c;然后下面显示过滤后的数据&#xff0c;如果数…

数据结构(单链表)

前沿&#xff1a; 在前面总结的顺序表的时候&#xff0c;最后也说出了他的一些缺点&#xff0c;例如头插/中间插的时候的时间复杂度是O(n)&#xff0c;这个效率并不高&#xff0c;而如何提高效率的实现呢&#xff0c;这里我们可以通过单链表来简单的提高这个效率。 思维导图&am…

java计算机毕业设计springboot+vue在线投票系统

项目介绍 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于在线投票系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了在线投票系统的发展&#xff0c;它彻底改变了…

Java初识:类和对象(上)

文章目录学习目标1.面向对象的初步认识1.1认识面向对象1.2 区分面向对象和面向过程2.类当定义与使用2.1认识简单类2.2 类的定义格式2.3 小试身手-定义类的小练习3.类的实例化3.1 什么是实例化3.2 实例化注意事项&#xff1a;3.3 类和对象说明4. this 引用4.1为什么要用this4.2 …

小程序意见反馈界面(简洁版代码)

在开发个人中心页面时&#xff0c;意见反馈功能是必不可少的&#xff0c;下面介绍该功能的具体开发流程 1、首先看一下效果图&#xff1a; 2、WXML代码&#xff0c;分为三个部分&#xff0c;文本域&#xff08;TextArea&#xff09;、输入框&#xff08;Input)、按钮&#xff…

程序员日常|为什么我在开发工作中偏爱这款键盘?

前言 最近一直不断地有粉丝朋友们私信我&#xff0c;问我该如何给自己挑选一款适合程序员工作的键盘&#xff0c;于是今天来给大家介绍下我用的键盘。 文章目录前言我的键盘亲身经历使用体验视频展示我的键盘 程序员作为一个需要长时间敲代码的职业&#xff0c;没有一个趁手的…

html静态网页设计制作 HTML我的家乡沧州网页代码 dw静态网页成品模板素材网页 web前端网页设计与制作 div静态网页设计

家乡旅游景点网页作业制作 网页代码运用了DIV盒子的使用方法&#xff0c;如盒子的嵌套、浮动、margin、border、background等属性的使用&#xff0c;外部大盒子设定居中&#xff0c;内部左中右布局&#xff0c;下方横向浮动排列&#xff0c;大学学习的前端知识点和布局方式都有…