MyBatis学习二:Mapper代理开发、配置文件完成增删改查、注解开发

news2025/9/20 16:01:46

前言

公司要求没办法,前端也要了解一下后端知识,这里记录一下自己的学习

学习教程:黑马mybatis教程全套视频教程,2天Mybatis框架从入门到精通

文档:
https://mybatis.net.cn/index.html

Mapper代理开发

目的

  • 解决原生方式中的硬编码
  • 简化后期执行sql

Mapper代理要求

  • 定义与sql映射文件同名的Mapper接口,并且将Mapper接口和sql映射文件放置在同一目录下
  • 设置sql映射文件的namespace属性未Mapper接口全限定名
  • 在Mapper接口中定义方法,方法名就算sql映射文件中sql语句的id,并保持参数类型和返回值类型一致
  • 编码
    • 通过SqlSessiongetMapper方法获取Mapper接口的代理对象
    • 调用对应方法完成sql的执行

备注: 如果Mapper接口名称和sql映射文件名称相同,并且在同一目录下,则可以使用包扫描的方式简化sql映射文件的加载。

定义Mapper接口,并且将Mapper接口和sql映射文件放置在同一目录下

在这里插入图片描述
1、在java/com/mapper下创建一个UserMapper接口文件
2、在resources下创建相同的目录结构,com/example/mapper,将UserMapper.xml移入到该目录下
3、注意,创建完成后在文件管理器里看一下目录结构是否正确,com.example.mapper是三个文件夹,不是一个文件夹。视频里也说了,这个很重要
在这里插入图片描述
设置sql映射文件的namespace属性未Mapper接口全限定名

修改UserMapper.xml文件里的namespace属性,修改为com.example.mapper.UserMapper
在这里插入图片描述
在Mapper接口中定义方法,方法名就算sql映射文件中sql语句的id,并保持参数类型和返回值类型一致
在这里插入图片描述

更新mybatis-config.xml里映射文件的地址
在这里插入图片描述
修改测试类

// 3、执行sql语句,查询所有数据
// 指定要执行的sql语句,这里传入对应的标识,对应UserMapper.xml文件中<select id="selectAllUser" resultType="User">
// List<User> userList = sqlSession.selectList("test.selectAllUser");
// 3.1 获取UserMapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 3.2 执行查询
List<User> userList = userMapper.selectAllUser();

执行结果
在这里插入图片描述
使用包扫描的方式简化sql映射文件的加载
mybatis-config.xml
在这里插入图片描述

配置文件完成增删改查

基本步骤

  • 编写Mapper接口方法
  • 编写sql语句,在sql映射文件里

实体类属性与表字段不一致
例如:类属性是userName,表里的属性是user_name。这样导致无法正确的查询出结果。

解决方式是设置:resultMap

原代码

<select id="selectAllUser" resultType="com.example.pojo.User">
        select * from user;
</select>

修改后

<resultMap id="userResultMap" type="com.example.pojo.User">
    <!-- property 属性是指对应的 Java 类的属性,column 属性是指对应的数据库表的字段名 -->
    <!-- 主键映射-->
    <id property="id" column="id"/>
    <!--普通列映射-->
    <result property="userName" column="user_name"/>
</resultMap>

<select id="selectAllUser" resultMap="userResultMap">
    select * from user;
</select>

根据id进行数据查询

UserMapper 接口

// 根据id查询
User selectUserById(Integer id);

UserMapper.xml

<select id="selectUserById" parameterType="int" resultType="com.example.pojo.User">
    select * from user where id = #{id};
</select>

测试

// 根据id进行查询
User user = userMapper.selectUserById(1);
System.out.println("用户:" + user);

补充:

  • parameterType 用于指定参数类型,这个也可以省略,因为mapper接口李的函数已经指定了参数类型
  • 参数使用#{参数}进行传递,除了#{} 还存在${}#{} 会将参数替换为?,可以防止sql注入;${} 会显示为实际的值,会存在sql注入问题。
  • 特殊字符,因为是在xml中写sql,所以<<= 会与xml标签冲突,< 可以使用&lt;代替,<=使用&lt;= 代替

条件查询

多条件查询

  • 参数同属于一个对象时

UserMapper接口里的函数

List<User> selectUserById(User user);

测试的代码

// 根据id和年龄进行查询
User userParam = new User();
userParam.setId(2);
userParam.setAge(30);
List<User> user = userMapper.selectUserById(userParam);
System.out.println("用户:" + user.size());

UserMapper.xml里的sql

<select id="selectUserById"  resultType="com.example.pojo.User">
   select * from user where id &lt;#{id} and age &lt; #{age};
</select>

使用对象的这种方式要注意:当你调用这个方法时,将会把 user.getId() 的值传递给SQL语句中的#{id}参数。但是要确保 User 类中有一个名为 id 的属性,并且提供了对应的getter方法。

  • 参数不属于一个对象时

UserMapper接口里的函数,需要使用@Param指定参数名称

List<User> selectUserById(@Param("id") int id, @Param("age") int age);

测试的代码

List<User> user = userMapper.selectUserById(3,10);

UserMapper.xml里的sql#{}里的变量要与@Param定义的保持一致

<select id="selectUserById"  resultType="com.example.pojo.User">
    select * from user where id &lt;#{id} and age &lt; #{age};
</select>
  • 参数是一个map对象
    这里只需要注意map对象的key要与sql里的参数保持一致

动态条件查询
if 条件判断

<select id="selectUserById" resultType="com.example.pojo.User">
    select * from user where id &lt;#{id}
    <if test="age !=-1 and age &lt;100">
        and age &lt; #{age}
    </if>
</select>

如果idage都需要判断时可以采用下面的方式

 <select id="selectUserById" resultType="com.example.pojo.User">
     select * from user
     <where>
         <if test="id!=-1">
             and id = #{id}
         </if>
         <if test="age!=-1">
             and age = #{age}
         </if>
     </where>
 </select>

但条件动态查询
使用choose,when,otherwise,类似于switch,case,default

select * from user where
<choose>
    <when test="id!=-1">
        id = #{id}
    </when>
    <when test="age!=-1">
        age = #{age}
    </when>
    <otherwise>
        1=1
    </otherwise>
</choose>

或者

select * from user
<where>
    <choose>
        <when test="id!=-1">
            id = #{id}
        </when>
        <when test="age!=-1">
            age = #{age}
        </when>
    </choose>
</where>

添加、修改

添加

UserMapper接口

 // 添加用户
 void addUser(User user);

UserMapper.xml

<!--values对应的是类里的属性 -->
<!-- 设置useGeneratedKeys和keyProperty后可以在新增成功后返回主键值-->
<insert id="addUser" useGeneratedKeys="true" keyProperty="id">
    insert into user(name, age, email)

    values (#{name}, #{age}, #{email});
</insert>

测试代码

User newUser = new User();
newUser.setName("李四");
newUser.setAge(18);
newUser.setEmail("123@qq.com");
userMapper.addUser(newUser);
// 这里要手动提交一下事务
sqlSession.commit();
System.out.println("新添加的id是:" + newUser.getId());

在这里插入图片描述

动态修改

 <update id="updateUser">
     update user
     <set>
         <if test="name!=null">
             name = #{name},
         </if>
         <if test="age!=null">
             age = #{age},
         </if>
         <if test="email!=null">
             email = #{email}
         </if>
     </set>
     <where>
         id = #{id}
     </where>
 </update>

删除

删除一个

<!--    单条数据的删除-->
<delete id="deleteUserById">
    delete from user
    where id = #{id}
</delete>

批量删除

 void deleteUserByIds(@Param("ids") int[] ids);
<delete id="deleteUserByIds">
    delete from user
    where id in
    <foreach collection="ids" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</delete>

参数传递

当接口的参数是CollectionListArray、多个参数时需要使用@Param注解,来给参数命名,确保sql中可以正确识别,如上面的批量删除。

注解开发

前面开发时sql语句都是写在xml,配置文件里。这里使用注解可以代替配置文件的方式,更加方便。
当然如果sql语句比较复杂还是使用配置文件的方式。

注解

  • 查询:@Select
  • 添加:@insert
  • 修改:@Update
  • 删除:Delete

以查询用户为例

xml配置方式

List<User> selectAllUser();
<!--  查询所有用户-->
<select id="selectAllUser" resultMap="userResultMap">
    select *
    from user;
</select>

注解方式

@Select("select * from user where name = #{name}")
User selectUserByName(String name);

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

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

相关文章

innovus:Patch Wire(补丁线)

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 在修补一些min area的drc时&#xff0c;会有一些danling wire的drc冒出来&#xff0c;为了避免这些假错&#xff0c;可以使用工具patch wire功能。 1&#xff09;选中wire &…

linux centos 添加临时ip

### 1.添加ip ip addr add IP/mask dev 网络设备 例&#xff1a;ip addr add 172.104.210.247/24 dev ens5f1 ### 2.启动网卡 ip link set up 网络设备 例&#xff1a;ip link set up ens3f0 ### 3.设置默认路由 ip route add default via GATEWAY 例&#xff1a;ip route add …

关于MIPS上手应知应会-如何把C语言改写为MIPS!

文章目录 寄存器指令使用技巧翻译C/Cif/else语句switch语句for循环while 循环do...while循环一维数组定义与使用二维数组定义与使用例 &#xff1a;哈密顿回路 注意立即数被符号位扩展 参考链接 寄存器 NameReg. NumUsage z e r o zero zero0constant value 0(恒为0) a t at a…

图的遍历(搜索)算法(深度优先算法DFS和广度优先算法BFS)

一、图的遍历的定义&#xff1a; 从图的某个顶点出发访问遍图中所有顶点&#xff0c;且每个顶点仅被访问一次。&#xff08;连通图与非连通图&#xff09; 二、深度优先遍历&#xff08;DFS&#xff09;&#xff1b; 1、访问指定的起始顶点&#xff1b; 2、若当前访问的顶点…

SoapUI 怎么下载:实用指南

SoapUI Windows 版本下载 今天带大家过一遍 SoapUI 在 Windows 系统下的安装教程吧&#xff01;各位 开发小伙伴 们可以跟着我一起来~ 下载安装包 下载链接&#xff1a;www.soapui.org/downloads/s… 安装 安装非常简单&#xff0c;只需双击它即可启动&#xff0c;安装程序…

CSS效果(工作中常用)

1、css文字溢出省略号 overflow: hidden; // 溢出隐藏 text-overflow: ellipsis; // 溢出用省略号显示 white-space: nowrap; // 规定段落中的文本不进行换行 overflow: hidden; // 溢出隐藏 text-overflow: ellipsis; // 溢出用省略…

深入了解Python中的进程控制和监控技巧,提高系统稳定性

概要 在计算机系统中&#xff0c;进程管理是一个重要的任务&#xff0c;它涉及创建、启动、监控、终止和管理运行中的进程。Python作为一门强大的编程语言&#xff0c;提供了丰富的库和模块&#xff0c;使得进程管理变得相对容易。本文将介绍如何使用Python来实现系统进程管理…

MQTT基础下载使用

1.下载MQTT(MQTT官网) 下载完后在bin目录下启动cmd 控制台输入emqx start&#xff0c;注意&#xff0c;此时控制台是没有反应的&#xff0c;就回你个D&#xff1a;\EMQX。其实已经打开了。 打开桌面上的MQTTX 并新建连接 这是测试的数据 我订阅了一个test1的订阅 并且我发布…

chrome面向服务的架构SOA

chrome 浏览器面向服务的架构 原来的各种模块会被重构成独立的服务&#xff0c;每个服务都可以独在独立的进程中运行&#xff0c;可以在浏览器的任务管理器中看到各种服务。 "面向服务的架构"&#xff08;Service-Oriented Architecture&#xff0c;SOA&#xff09;…

解决mock单元测试中 无法获取实体类xxx对应的表名

错误描述&#xff1a;在执行单元测试时&#xff0c;执行到new Example时抛出异常&#xff0c;提示无法获取实体类xxx对应的表名 Example example new Example(ServeSubscribeRecord.class);Example.Criteria criteria example.createCriteria();criteria.andEqualTo("se…

一步到位:掌握Python中Lambda表达式的5种实用技巧

一步到位&#xff1a;掌握Python中Lambda表达式的5种实用技巧 引言技巧一&#xff1a;单行函数定义技巧二&#xff1a;与内置函数结合技巧三&#xff1a;在数据结构排序中的应用技巧四&#xff1a;作为回调函数技巧五&#xff1a;与函数式编程结合结语 引言 在Python编程的宇宙…

【unity小技巧】Unity音乐和音效管理器

最终效果 前言 在游戏开发中&#xff0c;音乐和音效的管理是一个重要的环节。好的音乐和合适的音效可以为游戏增添氛围并提升玩家的体验。为了更好地管理音乐和音效&#xff0c;我们可以使用一个专门的音乐和音效管理器。 在本文中&#xff0c;我将向大家介绍如何在Unity中创…

气缸功能块(SMART PLC梯形图代码)

有关气缸功能块的更多介绍,可以参考下面链接文章: https://rxxw-control.blog.csdn.net/article/details/125459568https://rxxw-control.blog.csdn.net/article/details/125459568CODESYS平台双通气缸功能块 https://rxxw-control.blog.csdn.net/article/details/12544822…

听GPT 讲Rust源代码--compiler(6)

File: rust/compiler/rustc_index/src/idx.rs 在Rust的源代码中&#xff0c;idx.rs文件位于rust/compiler/rustc_index/src/目录下&#xff0c;它定义了用于索引访问的Idx trait。以下是该文件的详细介绍&#xff1a; Idx是一个基本的整数索引类型&#xff0c;它用于支持Rust编…

C#/.NET/.NET Core优秀项目和框架2023年12月简报

前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架&#xff08;公众号每周至少推荐两个优秀的项目和框架当然节假日除外&#xff09;&#xff0c;公众号推文有项目和框架的介绍、功能特点以及部分功能截图等&#xff08;打不开或者打开GitHub很慢的同学可以优先…

智能分析网关V4智慧港口码头可视化视频智能监管方案

一、需求背景 近年来&#xff0c;水利港口码头正在进行智能化建设&#xff0c;现场管理已经是重中之重。港口作为货物、集装箱堆放及中转机构&#xff0c;具有昼夜不歇、天气多变、环境恶劣等特性&#xff0c;安全保卫工作显得更加重要。港口码头的巡检现场如何高效、快捷地对…

【MySQL·8.0·源码】MySQL 的查询处理

Query processing MySQL 的 Query 处理可以分为 Parse、Prepare(Resolve/Transform)、Optimize 和 Execute 几个阶段 Parse 词法扫描器将 SQL 语句字符串分解为 tokens&#xff0c;语法分析器将 tokens 组装成语法树的子树结构&#xff0c;并 Reduce 为基本查询结构&#xff0…

Centos 磁盘挂载和磁盘扩容(新加硬盘方式)

步骤总结如下 一、对磁盘进行分区 二、对磁盘进行格式化 三、将磁盘挂载到对应目录 四、做开机自动挂载磁盘 磁盘分区 1.使用命令&#xff1a;fdisk -l 查看磁盘&#xff08;注&#xff1a;正常在Centos7中第一块数据盘标识一般是/dev/sda,第二块数据盘标识一般是/dev/sdb&…

小程序一次性订阅消息(消息通知):java服务端实现

文章目录 引言一、消息订阅1.1 小程序订阅消息功能介绍1.2 消息分类1.2.1 新版一次性订阅消息Beta1.2.2 一次性订阅消息&#xff08;用户通过弹窗订阅&#xff09;1.2.3 长期订阅消息&#xff08;用户通过弹窗订阅&#xff09;1.2.4 设备订阅消息 二、获取模板ID1.登录[微信公众…

10款值得推荐的Blazor UI组件库

前言 经常看到有小伙伴在DotNetGuide技术社区交流群里问有什么好用的Blazor UI组件库推荐的&#xff0c;本文将分享一些开源、实用、美观的Blazor UI组件库&#xff0c;提供给广大C#/.NET开发者们学习和使用&#xff08;注意&#xff1a;排名不分先后&#xff0c;都是十分优秀…