引言

在上一篇文章中,我们介绍了Mybatis的基础使用。

如有需要请移步查看:

MyBatis入门:快速掌握用户查询实战https://blog.csdn.net/qq_52331401/article/details/149270402?spm=1001.2014.3001.5502

今天,我将通过一个完整的用户管理系统示例,深入讲解Mybatis的CRUD操作、参数传递、模糊查询以及聚合函数等高级功能。

项目升级概览

相比基础版本,本次项目增加了以下功能:

  1. 完整的CRUD操作(增删改查)
  2. 多种查询方式(ID查询、模糊查询)
  3. 聚合函数使用
  4. 数据库连接信息外部化配置
  5. 更规范的测试类结构

核心代码解析

实体类(User.java)

实体类保持不变,作为数据载体:

public class User implements Serializable {private Integer id;private String username;private Date birthday;private String sex;private String address;// 省略getter/setter和toString方法
}

Mapper接口(UserMapper.java)

接口中定义了完整的CRUD操作方法:

public interface UserMapper {List<User> findAll();          // 查询所有用户User findById(Integer userId); // 根据ID查询void insert(User user);        // 新增用户void update(User user);        // 修改用户void delete(Integer userId);   // 删除用户List<User> findByName(String username); // 模糊查询Integer findByCount();         // 查询总数
}

Mapper XML配置(UserMapper.xml)

对应接口的SQL实现:

<mapper namespace="cn.tx.mapper.UserMapper"><!-- 查询所有 --><select id="findAll" resultType="cn.tx.domain.User">select * from user</select><!-- ID查询 --><select id="findById" resultType="cn.tx.domain.User" parameterType="int">select * from user where id = #{id}</select><!-- 新增用户(返回自增ID) --><insert id="insert" parameterType="cn.tx.domain.User"><selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">select last_insert_id()</selectKey>insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})</insert><!-- 更新用户 --><update id="update" parameterType="cn.tx.domain.User">update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}</update><!-- 删除用户 --><delete id="delete" parameterType="Integer">delete from user where id=#{id}</delete><!-- 模糊查询(两种方式) --><select id="findByName" resultType="cn.tx.domain.User" parameterType="string"><!-- select * from user where username like #{username} -->select * from user where username like '%${value}%'</select><!-- 查询总数 --><select id="findByCount" resultType="int">select count(*) from user</select>
</mapper>

配置文件优化

数据库连接信息向上提取到jdbc.properties:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis_db
jdbc.username=root
jdbc.password=123456

SqlMapConfig.xml引用外部配置:

<configuration><properties resource="jdbc.properties"/><!-- 其他配置 --><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource>
</configuration>

测试类详解

测试类采用JUnit4,使用@Before和@After优化:

public class UserTest {private InputStream in;private SqlSession session;private UserMapper mapper;@Beforepublic void init() throws Exception {in = Resources.getResourceAsStream("SqlMapConfig.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);session = factory.openSession();mapper = session.getMapper(UserMapper.class);}@Afterpublic void destory() throws IOException {session.close();in.close();}// 测试方法...
}

查询测试

@Test
public void testFindAll() {List<User> list = mapper.findAll();list.forEach(System.out::println);
}@Test
public void testFindById() {User user = mapper.findById(1);System.out.println(user);
}

增删改测试

@Test
public void testInsert() {User user = new User();user.setUsername("测试用户");user.setBirthday(new Date());user.setSex("男");user.setAddress("北京");mapper.insert(user);session.commit(); // 增删改需要提交事务System.out.println("新增ID:" + user.getId());
}@Test
public void testUpdate() {User user = mapper.findById(41);user.setUsername("修改后的名字");mapper.update(user);session.commit();
}@Test
public void testDelete() {mapper.delete(48);session.commit();
}

高级查询测试

// 模糊查询方式一:参数中带%
@Test
public void testFindByName() {List<User> list = mapper.findByName("%王%");list.forEach(System.out::println);
}// 模糊查询方式二:SQL中使用${value}
// 注意:这种方式有SQL注入风险,不推荐@Test
public void testFindByCount() {Integer count = mapper.findByCount();System.out.println("用户总数:" + count);
}

关键技术点解析

参数传递

  • 简单类型:#{参数名}
  • 对象类型:#{属性名}

模糊查询两种方式

  • 安全方式:like #{参数}(需要在参数中包含%)
  • 拼接方式:like ‘%${value}%’(有SQL注入风险)

返回自增ID

<selectKey keyProperty="id" order="AFTER" resultType="int">select last_insert_id()
</selectKey>

事务控制

  • 增删改操作需要手动commit()
  • 可以再openSession时设置自动提交:openSession(true)

总结

MyBatis的灵活性和强大功能使其成为Java持久层开发的优秀选择。希望这篇博客能帮助你深入理解MyBatis的核心用法!

完整代码已提供,建议读者实际运行测试类体会不同操作的效果。如有任何问题,欢迎留言讨论。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Flink DataStream API详解(二)

一、引言 咱两书接上回&#xff0c;上一篇文章主要介绍了DataStream API一些基本的使用&#xff0c;主要是针对单数据流的场景下&#xff0c;但是在实际的流处理场景中&#xff0c;常常需要对多个数据流进行合并、拆分等操作&#xff0c;以满足复杂的业务需求。Flink 的 DataS…

Unity3D游戏线上崩溃排查指南

前言 排查Unity3D线上游戏崩溃是个系统工程&#xff0c;需要结合工具链、日志分析和版本管理。以下是详细的排查指南和关键步骤&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&#xff0c;希望大家可以点击进来一起交流一下开发经验呀&#xff01; 一、崩溃信息收…

DPDK性能优化实践:系统级性能调优的方法论与实战(一套通用的方法论)

性能优化的挑战与现实困境 在高性能网络处理领域&#xff0c;性能优化往往被视为一门“玄学”而非科学。许多开发者在面对性能瓶颈时&#xff0c;要么盲目追求单一指标的极致优化&#xff0c;要么采用"试错法"进行零散的局部调优&#xff0c;结果往往是投入大量精力却…

Docker的/var/lib/docker/目录占用100%的处理方法

文章目录 一、问题描述 二、解决措施 三、可能遇到的问题 问题1、问题描述&#xff1a;执行 sudo systemctl stop docker 命令时&#xff0c;提示 Warning: Stopping docker.service, but it can still be activated by: docker.socket 问题2、问题描述&#xff1a;执行 s…

【UE教程/进阶】Slate链式编辑原理

目录链式编辑操作" . "操作" "操作" [ ] "链式编辑 SNew().&#xfeff;[] 操作" . " SLATE_ARGUMENT(ArgType, ArgName) 宏 调用宏 SLATE_PRIVATE_ARGUMENT_VARIABLE(ArgType, ArgName) &#xff0c;在FArgument结构体中添加了变量…

将手工建模模型(fbx、obj)转换为3dtiles的免费工具!

文章目录1、工具下载2、使用说明3、详细说明命令行格式示例命令参数说明4、源码地址1、工具下载 百度网盘下载链接 选择最新版本下载即可&#xff0c;支持Linux和Windows系统 2、使用说明 1&#xff09;按住键盘winr键&#xff0c;在弹出的窗口中输入cmd 2&#xff09;点击…

FreeRTOS源码学习之内核初始化

目录 前言 一、主函数内容 二、osKernelInitialize ()内核初始化函数内容 三、IS_IRQ()宏定义中断检测函数内容 四、如果这篇文章能帮助到你&#xff0c;请点个赞鼓励一下吧ξ( ✿&#xff1e;◡❛)~ 前言 使用STM32CubeMX添加FreeRTOS进入工程之后&#xff0c;会自动在ma…

Docker—— 镜像构建原因

在现代软件开发和运维中&#xff0c;Docker已成为一种非常流行的工具&#xff0c;它通过容器化应用程序来简化部署过程。然而&#xff0c;默认的官方镜像往往只能满足基础需求&#xff0c;无法涵盖所有特定项目的具体要求。原因说明系统级改动无法通过 volume 实现修改用户、删…

锂电池自动化生产线的现状与发展

锂电池自动化生产线的概述锂电池自动化生产线是指采用自动化设备和控制系统&#xff0c;实现锂电池从原材料到成品的全流程自动化生产过程。随着新能源产业的快速发展&#xff0c;锂电池作为重要的储能元件&#xff0c;其生产制造技术也在不断进步。自动化生产线通过减少人工干…

java底层的native和沙箱安全机制

沙箱安全机制沙箱&#xff08;Sandbox&#xff09;安全机制是一种将程序或代码运行在隔离环境中的安全技术&#xff0c;旨在限制其对系统资源&#xff08;如文件系统、网络、内存、其他进程等&#xff09;的访问权限&#xff0c;从而降低潜在恶意代码带来的风险。其核心思想是“…

【分享】文件摆渡系统适配医疗场景:安全与效率兼得

根据国家信息安全相关法规要求&#xff0c;医院为了网络安全&#xff0c;大多会采用网闸等隔离手段&#xff0c;将网络隔离为内网和外网&#xff0c;但网络隔离后&#xff0c;医院的内外网间仍存在较为频繁的文件摆渡需求。文件摆渡系统则是可以解决跨网络或跨安全域文件传输中…

vscode 中的 mermaid

一、安装软件 Mermaid preview Mermaid support 二、运行命令 创建.md 文件右键选择 ​Open Preview​&#xff08;或按 CtrlShiftV&#xff09; 三、流程图 注意&#xff1a; 要md 文件要保留 mermaid 1. #mermaid-svg-nchqbvlWePe5KCwJ {font-family:"trebuchet ms"…

微服务引擎 MSE 及云原生 API 网关 2025 年 6 月产品动态

点击此处&#xff0c;了解微服务引擎 MSE 产品详情。

【TCP/IP】7. IP 路由

7. IP 路由7. IP 路由概述7.1 直接传递与间接传递7.2 IP 路由核心机制7.3 路由表7.3.1 路由表的构成7.3.2 信宿地址采用网络地址的好处7.3.3 下一跳地址的优势7.3.4 特殊路由表项7.3.5 路由算法7.4 静态路由7.4.1 特点7.4.2 自治系统&#xff08;AS&#xff09;7.4.3 配置命令7…

xFile:高性能虚拟分布式加密存储系统——Go

xFile&#xff1a;高性能虚拟分布式加密存储系统 目录xFile&#xff1a;高性能虚拟分布式加密存储系统1 背景介绍2 设计初衷与目标3 项目简介4 系统架构5 核心优势1. 真正的分布式块存储2. 块级加密与压缩&#xff0c;安全高效3. 灵活的索引与元数据管理4. 多用户与权限体系5. …

时序数据库:高效处理时间序列数据的核心技术

时序数据库概述时序数据库&#xff08;Time Series Database&#xff0c;TSDB&#xff09;是一种专门为存储、处理和查询时间序列数据而优化的数据库系统。随着物联网、金融科技、工业互联网等领域的快速发展&#xff0c;时序数据呈现出爆炸式增长&#xff0c;传统的关系型数据…

面试官:你再问TCP三次握手,我就要报警了!

CP三次握手和四次挥手&#xff0c;是面试官最爱问的“开场白”之一 别看它基础&#xff0c;真要讲清楚细节&#xff0c;分分钟让你冷汗直流&#xff01; 这玩意儿就跟程序员相亲一样&#xff1a; 表面上问的是“你老家哪的” 实际上是在试探你有没有房、有没有车、能不能落…

RuoYi+Uniapp(uni-ui)开发商城系统

如果你正在考虑用 RuoYi 和 UniApp&#xff08;uni-ui&#xff09;搭建一套商城系统&#xff0c;那这套组合确实值得好好研究。它整合了 RuoYi 的快速开发能力和 UniApp 的跨平台特性&#xff0c;在高效开发的同时还能兼顾多端适配的需求。下面从技术架构、功能模块、开发实践到…

面试150 二叉树的最大高度

思路 考虑从递归出发&#xff0c;联想递归三部曲&#xff1a;返回什么、传入的参数是什么、遍历的方式是什么。此题现在需要我们整个树&#xff0c;并且需要从根节点出发&#xff0c;因此我们选择先序遍历即可。另一张办法&#xff0c;则是选择通过队列实现层次遍历&#xff0c…

从零实现一个GPT 【React + Express】--- 【2】实现对话流和停止生成

摘要 这是本系列文章的第二篇&#xff0c;开始之前我们先回顾一下上一篇文章的内容&#xff1a; 从零实现一个GPT 【React Express】— 【1】初始化前后端项目&#xff0c;实现模型接入SSE 在这一篇中&#xff0c;我们主要创建了前端工程和后端工程&#xff0c;这里贴一下我…