Mybatis笔记一
创始人
2025-05-29 07:49:48
0

SSM开发框架

  • Spring 对象容器框架
  • Spring MVC web程序分支接耦
  • MyBatis 简化数据交互

MyBatis使用XML将SQL与程序接耦,便于维护。

前言 MyBatis开发流程

  • 引入MyBatis依赖
  • 创建核心配置文件
  • 创建实体(Entity)类
  • 创建Mapper映射文件
  • 初始化SessionFactory(读取配置文件、加载映射)
  • 利用sqlSession对象操作数据

一、引入依赖

可在pom.xml作为依赖引入

org.mybatis mybatis 3.5.1

二、环境配置

1、/src/main/resource新建xxx.xml文件

三、SqlSessionFactory

  • 用于初始化Mybatis,创建SqlSession对象,需要保证sqlSession在全局应用中唯一
  • sqlSession使用JDBC方式与数据库交互
  • sqlSession对象提供了数据表CRUD对应方法

文件目录/src/test/java/com.gu.mybatis/MybatisTest.java

package com.gu.mybatis; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.Reader; public class MybatisTest { @Test public void testSqlSessionFactory() { SqlSession sqlSession = null; try { // 利用Reader加载classpath下的mybaits-config.xml核心配置文件 Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); // 初始化sqlSessionFactour对象,同时解析mybaits-config.xml文件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); // 创建sqlSession对象,sqlsession是JDBC的扩展类,用于数据库交互 sqlSession = sqlSessionFactory.openSession(); System.out.println("SqlSession加载成功"); } catch (IOException e) { e.printStackTrace(); } finally { if(sqlSession!=null) { // 如果type是"POOLED",代表使用连接池,close则是将连接回收到连接池中 // 如果type是"UNPOOLEED",代表直连,cloes则会调用Connection.close方法关闭 sqlSession.close(); } } } }

创建mybatis的工具类

package com.gu; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.Reader; public class MybatisUtils { private static SqlSessionFactory sqlSessionFactory = null; static { Reader reader = null; try { reader = Resources.getResourceAsReader("mybatis-config.xml"); } catch (IOException e) { e.printStackTrace(); throw new ExceptionInInitializerError(e); } sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); } public static SqlSession openSession() { return sqlSessionFactory.openSession(); } public static void closeSession(SqlSession sqlSession) { if(sqlSession!=null){ sqlSession = null; } } public static void main(String[] args) { } }

四、创建mapper映射文件

文件路径/src/main/resource/mappers/goods.xml

mapper的dtd可在https://mybatis.net.cn/getting-started.html复制

在pom.xml中配置映射文件

测试文件查看

@Test public void testSqlsctAll() { SqlSession sqlSession = null; try { sqlSession = MybatisUtils.openSession(); List list = sqlSession.selectList("goods.selectAll"); for(Goods goods: list) { System.out.println(goods.getTitle()); } } catch (Exception e) { throw e; } finally { MybatisUtils.closeSession(sqlSession); } }

实体类属性名称(驼峰命名)和数据库名称(下划线)不一样,需要做转换设置

/src/main/resource/Mybatis-config.xml

五、SQL传参

5.1 单个参数传参

映射文件

测试调用

sqlSession = MybatisUtils.openSession(); Goods goods = sqlSession.selectOne("goods.selectId", 1603);

5.2 多个参数传参

测试调用

sqlSession = MybatisUtils.openSession(); Map params = new HashMap(); params.put("min", 100); params.put("max", 500); params.put("limit", 10); List goods = sqlSession.selectList("goods.selectByPriceRange", params); for(Goods good: goods){ System.out.println(good.getTitle()); }

六、多表关联查询

6.1 多表关联查询

map不保证数据顺序,可食用LinkedHashMap

@Test public void selectGoodsMap() { SqlSession sqlSession = null; try { sqlSession = MybatisUtils.openSession(); List List = sqlSession.selectList("goods.selectGoodsMap"); for(Map map: List){ System.out.println(map); } } finally { MybatisUtils.closeSession(sqlSession); } }

利用Map保存多表关联结果

  • Mybatis会将每一条记录包装为LinkedHashMap对象
  • key是字段名 value是字段对应的值,字段类型根据表结构进行自动判断
  • 优点 易于拓展,易于使用
  • 缺点 太过灵活,无法进行编译时检查

6.2 ResultMap结果映射

  • ResultMap可以将查询结果为复杂类型的Java对象
  • 适用于Java对象保存多表关联结果
  • 支持对象关联查询等高级特性

扩展实体类/src/main/java/com/gu/dto/GoodsDTO

package com.gu.dto; import com.gu.entity.Goods; public class GoodsDTO { private Goods goods = new Goods(); private String categoryName; private String test; public Goods getGoods() { return goods; } public void setGoods(Goods goods) { this.goods = goods; } public String getCategoryName() { return categoryName; } public void setCategoryName(String categoryName) { this.categoryName = categoryName; } public String getTest() { return test; } public void setTest(String test) { this.test = test; } }

配置查询语句

测试查询

sqlSession = MybatisUtils.openSession(); List List = sqlSession.selectList("goods.selectGoodsMapDTO"); for(GoodsDTO goodsDTO: List){ System.out.println(goodsDTO.getGoods().getTitle()); }

七、MyBatis的数据插入修改和删除

前置知识:数据库事务

  • 数据库事务是保证数据操作完整性的基础
  • 客户端写操作时,事务日志会记录该操作,全部成功后commit到数据表中,commit才是真正写入
  • 数据成功写入数据表后,事务日志记录会清除。
  • 数据部分执行不成功,客户端会发送rollback命令,清除当前事务日志的数据。

7.1 新增 insert

映射文件配置

insert into t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id) values (#{title}, #{subTitle}, #{originalCost }, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId}) -- 主键回填 last_insert_id获取连接最后产生的id select last_insert_id();

测试插入

@Test public void insert() { SqlSession sqlSession = null; try { sqlSession = MybatisUtils.openSession(); Goods goods = new Goods(); goods.setTitle("测试商品01"); goods.setSubTitle("测试子标题"); goods.setOriginalCost(200f); goods.setCurrentPrice(100f); goods.setIsFreeDelivery(1); goods.setDiscount(0.5f); goods.setCategoryId(43); int num = sqlSession.insert("goods.insertGoods", goods); sqlSession.commit(); // 提交事物数据 System.out.println("num" + num); System.out.println(goods.getTitle()); } catch (Exception e) { System.out.println(e); if(sqlSession!=null) { sqlSession.rollback(); } } finally { MybatisUtils.closeSession(sqlSession); } }

7.1.1 selectKey和useGeneratedKey的区别

insert into t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id) values (#{title}, #{subTitle}, #{originalCost }, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId})

  • selectKey标签需要明确编写获取最新组建的SQL语句
  • useGeneratedKey属性会自动根据驱动生成对应SQL语句
  • selectKey使用所有关系数据库
  • useGeneratedKey只支持“自增主键”类型的数据库

7.2 更新和删除

update t_goods set title=#{title}, sub_title=#{subTitle}, original_cost=#{originalCost }, current_price=#{currentPrice}, discount=#{discount}, is_free_delivery=#{isFreeDelivery}, category_id=#{categoryId} where goods_id=#{goodsId} delete from t_goods where goods_id=#{value}

八、MyBatis注入攻击

  • ${}文本替换,未经任何处理对SQL文本替换
  • #{}预编译传旨,使用预编译传旨可以预防SQL注入

原义传值必须程序输入,不能由用户输入

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
JAVA多线程知识整理 Java多线程基础 线程的创建和启动 继承Thread类来创建并启动 自定义Thread类的子类&#...
【洛谷 P1090】[NOIP... [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G ...
国民技术LPUART介绍 低功耗通用异步接收器(LPUART) 简介 低功耗通用异步收发器...
城乡供水一体化平台-助力乡村振... 城乡供水一体化管理系统建设方案 城乡供水一体化管理系统是运用云计算、大数据等信息化手段࿰...
程序的循环结构和random库...   第三个参数就是步长     引入文件时记得指明字符格式,否则读入不了 ...
中国版ChatGPT在哪些方面... 目录 一、中国巨大的市场需求 二、中国企业加速创新 三、中国的人工智能发展 四、企业愿景的推进 五、...
报名开启 | 共赴一场 Flu... 2023 年 1 月 25 日,Flutter Forward 大会在肯尼亚首都内罗毕...
汇编00-MASM 和 Vis... Qt源码解析 索引 汇编逆向--- MASM 和 Visual Studio入门 前提知识ÿ...
【简陋Web应用3】实现人脸比... 文章目录🍉 前情提要🌷 效果演示🥝 实现过程1. u...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
windows安装JDK步骤 一、 下载JDK安装包 下载地址:https://www.oracle.com/jav...
分治法实现合并排序(归并排序)... 🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨...
在linux上安装配置node... 目录前言1,关于nodejs2,配置环境变量3,总结 前言...
Linux学习之端口、网络协议... 端口:设备与外界通讯交流的出口 网络协议:   网络协议是指计算机通信网...
Linux内核进程管理并发同步... 并发同步并发 是指在某一时间段内能够处理多个任务的能力,而 并行 是指同一时间能够处理...
opencv学习-HOG LO... 目录1. HOG(Histogram of Oriented Gradients,方向梯度直方图)1...
EEG微状态的功能意义 导读大脑的瞬时全局功能状态反映在其电场结构上。聚类分析方法一致地提取了四种头表面脑电场结构ÿ...
【Unity 手写PBR】Bu... 写在前面 前期积累: GAMES101作业7提高-实现微表面模型你需要了解的知识 【技...