news 2026/2/18 11:48:38

MyBatis实战教程:使用Map与POJO类实现CRUD操作详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MyBatis实战教程:使用Map与POJO类实现CRUD操作详解

MyBatis实战教程:使用Map与POJO类实现CRUD操作详解

本文将通过实际案例,详细讲解在MyBatis中如何使用Map集合和POJO类两种方式实现数据库的增删改查操作,解决常见映射问题,提高开发效率。

一、MyBatis简介与CRUD基础

MyBatis是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集的工作。

1.1 传统JDBC的问题

在传统JDBC编程中,我们经常遇到以下问题:

java

// JDBC中繁琐的结果集处理 while(rs.next()) { User user = new User(); user.setId(rs.getString("id")); user.setIdCard(rs.getString("idCard")); user.setUsername(rs.getString("username")); // ... 需要为每个属性手动赋值 userList.add(user); }

这种方式存在以下缺点:

  1. 代码冗余,每个字段都需要手动映射

  2. 容易出错,字段名写错会导致运行时错误

  3. 维护困难,表结构变化时需要修改大量代码

二、MyBatis中使用Map实现CRUD

2.1 使用Map进行数据插入

Map集合提供了灵活的键值对存储方式,适合不确定参数数量或临时性的数据操作。

2.1.1 基础Map传参

java

@Test public void testInsertCarByMap() { SqlSession sqlSession = SqlSessionUtil.openSession(); // 使用Map封装前端传递的数据 Map<String, Object> map = new HashMap<>(); map.put("carNum", "11111"); map.put("brand", "比亚迪汉"); map.put("guidePrice", 10.0); map.put("produceTime", "2020-11-11"); map.put("carType", "电车"); // 执行SQL插入操作 int count = sqlSession.insert("insertCar", map); System.out.println("插入记录数:" + count); sqlSession.commit(); sqlSession.close(); }

2.1.2 Mapper XML配置

xml

<!-- CarMapper.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.mapper.CarMapper"> <insert id="insertCar"> insert into t_car(id, car_num, brand, guide_price, produce_time, car_type) values(null, #{carNum}, #{brand}, #{guidePrice}, #{produceTime}, #{carType}) </insert> </mapper>
2.1.3 注意事项
  1. 键名匹配原则#{}中的名称必须与Map中的key完全一致

  2. 空值处理:如果key不存在,对应的值将为null

  3. 命名规范:建议使用有意义的key名称,提高代码可读性

2.2 使用Map进行数据查询

java

@Test public void testSelectByMap() { SqlSession sqlSession = SqlSessionUtil.openSession(); Map<String, Object> paramMap = new HashMap<>(); paramMap.put("minPrice", 10.0); paramMap.put("brand", "宝马"); List<Map<String, Object>> result = sqlSession.selectList("selectCarByCondition", paramMap); for (Map<String, Object> car : result) { System.out.println(car); } sqlSession.close(); }

三、MyBatis中使用POJO类实现CRUD

3.1 POJO类定义

java

// Car.java public class Car { private Long id; private String carNum; private String brand; private Double guidePrice; private String produceTime; private String carType; // 构造方法 public Car() {} public Car(Long id, String carNum, String brand, Double guidePrice, String produceTime, String carType) { this.id = id; this.carNum = carNum; this.brand = brand; this.guidePrice = guidePrice; this.produceTime = produceTime; this.carType = carType; } // Getter和Setter方法 public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getCarNum() { return carNum; } public void setCarNum(String carNum) { this.carNum = carNum; } // ... 其他getter和setter }

3.2 使用POJO进行数据插入

java

@Test public void testInsertCarByPOJO() { SqlSession sqlSession = SqlSessionUtil.openSession(); // 使用POJO对象封装数据 Car car = new Car(null, "3333", "比亚迪秦", 30.0, "2020-11-11", "新能源"); // 执行SQL int count = sqlSession.insert("insertCar", car); System.out.println("插入记录数:" + count); sqlSession.commit(); sqlSession.close(); }

3.3 POJO传参原理

重要规则#{}占位符中的名称对应的是POJO类的getter方法名去掉"get"并将首字母小写后的名称。

例如:

  • getCarNum()#{carNum}

  • getGuidePrice()#{guidePrice}

  • getUsername()#{username}

3.4 使用POJO进行数据查询

3.4.1 查询单个对象

xml

<!-- 根据id查询汽车信息 --> <select id="selectById" resultType="com.example.pojo.Car"> select * from t_car where id = #{id} </select>

java

@Test public void testSelectById() { SqlSession sqlSession = SqlSessionUtil.openSession(); // 查询单个对象 Car car = sqlSession.selectOne("selectById", 1); System.out.println(car); sqlSession.close(); }

3.4.2 查询所有记录

xml

<!-- 查询所有汽车信息 --> <select id="selectAll" resultType="com.example.pojo.Car"> select id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType from t_car </select>

java

@Test public void testSelectAll() { SqlSession sqlSession = SqlSessionUtil.openSession(); // 查询所有记录,返回List集合 List<Car> carList = sqlSession.selectList("selectAll"); for (Car car : carList) { System.out.println(car); } sqlSession.close(); }

四、解决字段名与属性名映射问题

4.1 问题现象

当数据库字段名与Java类属性名不一致时,会出现属性值为null的情况:

sql

-- 数据库表结构 +----+----------+------------+--------------+---------------+----------+ | id | car_num | brand | guide_price | produce_time | car_type | +----+----------+------------+--------------+---------------+----------+ | 1 | 1001 | 宝马520Li | 10.00 | 2020-10-11 | 燃油车 | +----+----------+------------+--------------+---------------+----------+ -- 直接查询会导致Car对象的carNum、guidePrice等属性为null -- 因为数据库字段是car_num,而Java属性是carNum

4.2 解决方案

方案一:SQL中使用AS别名(推荐)

xml

<select id="selectById" resultType="com.example.pojo.Car"> select id, car_num as carNum, -- 起别名 brand, guide_price as guidePrice, -- 起别名 produce_time as produceTime, -- 起别名 car_type as carType -- 起别名 from t_car where id = #{id} </select>
方案二:配置驼峰命名自动映射

在MyBatis配置文件中开启驼峰命名自动映射:

xml

<!-- mybatis-config.xml --> <configuration> <settings> <!-- 开启驼峰命名自动映射 --> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> </configuration>

开启后,MyBatis会自动将下划线命名的数据库字段映射到驼峰命名的Java属性:

  • car_numcarNum

  • guide_priceguidePrice

  • produce_timeproduceTime

方案三:使用resultMap自定义映射

xml

<resultMap id="carResultMap" type="com.example.pojo.Car"> <id property="id" column="id"/> <result property="carNum" column="car_num"/> <result property="brand" column="brand"/> <result property="guidePrice" column="guide_price"/> <result property="produceTime" column="produce_time"/> <result property="carType" column="car_type"/> </resultMap> <select id="selectById" resultMap="carResultMap"> select * from t_car where id = #{id} </select>

五、Map与POJO对比与选择

5.1 使用场景对比

特性Map集合POJO类
灵活性高,适合动态参数低,结构固定
类型安全低,运行时才能发现错误高,编译时检查
代码可读性低,需要查看Map键名高,属性明确
IDE支持有限,无法自动提示好,有代码提示
适合场景临时查询、参数不固定业务实体、固定结构

5.2 最佳实践建议

  1. 业务实体操作使用POJO

    • 用户、订单、商品等核心业务实体

    • 需要频繁操作和传递的数据

    • 有利于代码维护和重构

  2. 临时查询使用Map

    • 动态条件查询,参数不固定

    • 统计报表等临时性数据操作

    • 快速原型开发阶段

  3. 混合使用策略

    java

    // 示例:使用Map封装查询条件,返回POJO列表 public List<Car> findCars(Map<String, Object> params) { return sqlSession.selectList("findCarsByCondition", params); }

六、完整示例与总结

6.1 完整Mapper示例

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.mapper.CarMapper"> <!-- 插入操作 --> <insert id="insertCar"> insert into t_car(id, car_num, brand, guide_price, produce_time, car_type) values(null, #{carNum}, #{brand}, #{guidePrice}, #{produceTime}, #{carType}) </insert> <!-- 根据ID查询 --> <select id="selectById" resultType="com.example.pojo.Car"> select id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType from t_car where id = #{id} </select> <!-- 查询所有 --> <select id="selectAll" resultType="com.example.pojo.Car"> select id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType from t_car </select> <!-- 更新操作 --> <update id="updateCar"> update t_car set car_num = #{carNum}, brand = #{brand}, guide_price = #{guidePrice}, produce_time = #{produceTime}, car_type = #{carType} where id = #{id} </update> <!-- 删除操作 --> <delete id="deleteById"> delete from t_car where id = #{id} </delete> </mapper>

6.2 关键点总结

  1. #{}${}的区别

    • #{}是预编译处理,防止SQL注入

    • ${}是字符串替换,有SQL注入风险

  2. resultType与resultMap

    • resultType:自动映射,要求字段名与属性名一致或配置别名

    • resultMap:自定义映射,处理复杂映射关系

  3. 占位符命名规则

    • Map传参:#{}中写Map的key

    • POJO传参:#{}中写getter方法对应的属性名

  4. 性能优化建议

    • 尽量使用POJO,享受编译时检查的好处

    • 复杂查询考虑使用resultMap提高可读性

    • 批量操作使用批量API提高性能

通过本文的学习,你应该掌握了MyBatis中使用Map和POJO实现CRUD操作的核心技术。在实际开发中,根据具体场景选择合适的方式,既能提高开发效率,又能保证代码质量。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/10 3:43:38

医疗知识问答系统搭建实录——使用Kotaemon全过程

医疗知识问答系统搭建实录——使用Kotaemon全过程 在三甲医院的智能导诊台前&#xff0c;一位老年患者正皱着眉头询问&#xff1a;“我有糖尿病&#xff0c;能吃阿胶吗&#xff1f;”传统客服机器人只能机械回复“请咨询医生”&#xff0c;而新一代系统却能立刻调取《中国2型糖…

作者头像 李华
网站建设 2026/2/13 7:35:43

内网穿透工具新选择:这款免费工具如何让远程访问变得简单高效

官网&#xff1a;财运到免费内网穿透 01 免费服务的基础功能 许多内网穿透工具对核心功能收费&#xff0c;而财运到内网穿透却提供了完全免费的HTTP(S)、TCP和UDP协议支持。这使得个人开发者无需预算就能实现本地服务的远程访问。 02 零成本享受的特色功能 与传统免费工具简…

作者头像 李华
网站建设 2026/2/18 10:08:06

有多少制造企业上了ERP和MES,真正能做到批次管理和质量追溯?

生产制造企业对于管理的要求越来越高&#xff0c;ERP系统和MES系统是企业管理提升必不可少的管理工具&#xff0c;早已成为企业提升管理水平的标配。在客户提出ERP系统和MES系统的需求中&#xff0c;批次管理和追溯功能已经是“必选项”&#xff0c;需求重叠度达到90%以上。从技…

作者头像 李华
网站建设 2026/2/10 9:12:46

EmotiVoice应用于机场/车站广播系统改造

EmotiVoice应用于机场/车站广播系统改造 在大型交通枢纽的嘈杂环境中&#xff0c;一条关键信息能否被旅客准确接收&#xff0c;往往不只取决于内容本身&#xff0c;更与语音的语气、节奏和情感息息相关。你是否曾在机场听到机械感十足的“CA1835航班开始登机”&#xff0c;却几…

作者头像 李华
网站建设 2026/2/11 8:18:20

Kotaemon能否用于图书馆检索?公共文化服务创新

Kotaemon能否用于图书馆检索&#xff1f;公共文化服务创新 在智能问答系统日益普及的今天&#xff0c;图书馆这类传统知识服务机构正面临一个根本性问题&#xff1a;如何让沉睡在书架与数据库中的海量文献资源&#xff0c;真正“活”起来&#xff1f;用户不再满足于输入几个关键…

作者头像 李华
网站建设 2026/2/11 20:42:01

Fun-ASR-Nano深度评测

0. 研究背景 Fun-ASR-Nano-2512 是由阿里巴巴旗下的通义实验室开源的语音识别模型&#xff0c;通义实验室之前还开源了 SenseVoiceSmall 和 Paraformer 模型&#xff0c;这篇文章使用三种模型对多种方言&#xff0c;以及真实电话录音进行对比测试&#xff0c;在开源的数据集中…

作者头像 李华