MyBatis02——mybatis基础使用|缓存机制|sqlMapper文件|单参数和多参数传递|Statement和PreparedStatement

article/2025/6/9 0:41:32

目录

一、搭建环境

二、核心配置文件

三、核心类 (测试类)

四、缓存机制

一级缓存

二级缓存

清理缓存

五、sqlMapper文件

六、单参数和多参数的传递

6.1取别名

 6.2 测试新增返回自增主键

七、mybatis中Statement和PreparedStatement

作业

1、掌握环境搭建

2、掌握单个参数、多个参数的增删改查

3、缓存机制 (一级、二级缓存特点)

4、mybatis核心配置文件 常见的配置项

5、#和$的区别?(重点)

6、sqlMapper文件新增返回自增主键

7、预习 动态sql和多表关联映射

动态sql

高级结果映射


一、搭建环境

1、引入jar包

mysql.jar
mybatis.jar

2、补全结构

com.hl.pojo
com.hl.mapper
mybatis-config.xml
sqlMapper.xml

3、测试类

加载myabtis核心配置文件,得到IO流  Resources
创建sqlSessionFactory   SqlsessionFactoryBuilder
SqlSession session = sqlSessionFactory.openSession()
//获取mapper接口
调用mapper方法
//关闭流

二、核心配置文件

mybatis-config.xml

<Configuration>//1、<properties resource="db.properties"></properties>//2、<environments default="test"><environment><transactionManager  type="jdbc"/><dataSource type="POOLED"><property  name="url" value="" ></property>usernamepassworddriver</dataSource></environment></environments>//3、<mappers><mapper resource="com/hl/mybatis01/mapper/AccountMapper.xml"/></mappers></Configuration>

 补充完整代码

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--配置-->
<configuration><!--引入外部配置文件--><properties resource="db.properties"></properties>
​<!--设置--><settings><!--下划线到驼峰式命名法自动映射--><setting name="mapUnderscoreToCamelCase" value="true"/></settings>
​<!--类型起别名--><typeAliases><!--type="类型" alias="别名"--><!--针对每一个javabean分别起别名-->
<!--        <typeAlias type="com.hl.mybatis02.pojo.Student" alias="student"></typeAlias>--><!--统一起别名   别名默认为类名  不区分大小写--><package name="com.hl.mybatis02.pojo" /></typeAliases><!--数据库环境--><environments default="dev"><environment id="dev"><transactionManager type="jdbc"></transactionManager><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments><!--mappers映射器--><mappers><!--sqlMapper文件位置-->
<!--        <mapper resource="com/hl/mybatis02/mapper/GoodsMapper.xml"></mapper>--><!--指向mapper接口位置-->
<!--        <mapper class="com.hl.mybatis02.mapper.GoodsMapper"></mapper>-->
<!--        <mapper class="com.hl.mybatis02.mapper.ItemMapper"></mapper>--><!--指向mapper包的位置,统一扫描该包下所有接口--><package name="com.hl.mybatis02.mapper"/></mappers>
</configuration>

三、核心类 (测试类)

package com.hl.mybatis02;
​
import com.hl.mybatis02.mapper.StudentMapper;
import com.hl.mybatis02.pojo.Student;
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.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
​
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
​
class Mybatis02ApplicationTests {
​@Testvoid contextLoads() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession session = factory.openSession();StudentMapper studentMapper = session.getMapper(StudentMapper.class);
​Student student = new Student(0,"admin","男","2020-1-5",1001,null,null,null);int num = studentMapper.insertStudent(student);System.out.println("受影响的数据行数:"+num);System.out.println("自增主键值为:"+student.getStudentId());session.commit();session.close();}
​@Testvoid query() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession session = factory.openSession();StudentMapper studentMapper = session.getMapper(StudentMapper.class);List<Student> list = studentMapper.listAll();System.out.println(list);
​session.commit();session.close();}
​
}

四、缓存机制

缓存:多次执行相同dql,第一次走数据库表查询,第二次不再执行sql语句,直接从缓存区中获取数据。

一级缓存

默认已开启,可以直接使用,属于sqlSession级别的缓存。

二级缓存

默认没有开启,需要手动在mybatis配置文件中开启,属于sqlSessionFactory级别的缓存。

<!--开启当前命名空间的二级缓存-->
<cache></cache>

清理缓存

java代码清理缓存

session.clearCache();

sqlMapper文件清理缓存

        useCache="false"  禁用当前sql语句的二级缓存
        flushCache="true"  清空缓存区数据  导致一级缓存和二级缓存失效

<!--    //查询 下划线到驼峰式命名法的映射-->
<!--    public List<Student> listAll();useCache="false"  禁用当前sql语句的二级缓存flushCache="true"  清空缓存区数据  导致一级缓存和二级缓存失效
--><select id="listAll" resultType="student"  useCache="false">select * from student</select>

示例:

  @Testvoid firstCache() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession session = factory.openSession();StudentMapper studentMapper = session.getMapper(StudentMapper.class);
​List<Student> list = studentMapper.listAll();System.out.println(list);//清理缓存
//        session.clearCache();List<Student> list2 = studentMapper.listAll();System.out.println(list2);
​session.commit();session.close();}@Testvoid secondCache() throws IOException {InputStream in = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);SqlSession session = factory.openSession();StudentMapper studentMapper = session.getMapper(StudentMapper.class);List<Student> list = studentMapper.listAll();System.out.println(list);session.close();
​
​SqlSession session2 = factory.openSession();StudentMapper studentMapper2 = session2.getMapper(StudentMapper.class);List<Student> list2 = studentMapper2.listAll();System.out.println(list2);session2.close();
​SqlSession session3 = factory.openSession();StudentMapper studentMapper3 = session3.getMapper(StudentMapper.class);List<Student> list3 = studentMapper3.listAll();System.out.println(list3);session3.close();}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--命名空间 唯一标识-->
<mapper namespace="com.hl.mybatis02.mapper.StudentMapper">
​<!--开启当前命名空间的二级缓存--><cache></cache>

五、sqlMapper文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--命名空间 唯一标识-->
<mapper namespace="com.hl.mybatis02.mapper.StudentMapper"><!--    测试自增主键的生成useGeneratedKeys="true"  获取自动生成的主键keyProperty="studentId"  主键对应的属性名-->
<!--    public int insertStudent(Student student);--><insert id="insertStudent" useGeneratedKeys="true" keyProperty="studentId">insert into student(name,gender,birth_date,class_id,enrollment_date)values (#{name},#{gender},#{birthDate},#{classId},now())</insert>
​
<!--    //查询 下划线到驼峰式命名法的映射-->
<!--    public List<Student> listAll(); --><select id="listAll" resultType="student">select * from student</select>
</mapper>

六、单参数和多参数的传递

6.1取别名

Mapper接口

测试新增主键的生成,对象也可以取别名
多个参数,给参数起别名,将不再使用系统默认的arg0、arg1等
单个参数,也可以取别名,之后#{里面不能随便写了只能写别名}
 

//测试新增主键的生成,对象也可以取别名public int insertStudent(@Param("stu")Student student);
//    查询 下划线到驼峰式命名法的映射public List<Student> listAll();//    多个参数,给参数起别名,将不再使用系统默认的arg0、arg1等public List<Student> findStudent(@Param("name")String name, @Param("phone")String phone);
//    单个参数,也可以取别名,之后#{里面不能随便写了只能写别名}public Student findStudentById(int id);

 6.2 测试新增返回自增主键

Mapper映射文件里面

测试新增主键的生成:
useGeneratedKeys="true"    获取自动生成的主键
keyProperty="studentId"    主键对应的属性名
对象在接口中取别名之后,调用对象的属性名,应该写成:别名.属性名

<!--命名空间  唯一标识-->
<mapper namespace="com.hl.mybatis02.mapper.StudentMapper"><!--    //测试新增主键的生成
useGeneratedKeys="true"    获取自动生成的主键
keyProperty="studentId"    主键对应的属性名
对象在接口中取别名之后,调用对象的属性名,应该写成:别名.属性名
-->
<!--    public int insertStudent(Student student);--><insert id="insertStudent" useGeneratedKeys="true" keyProperty="studentId">insert into student(name,gender,birth_date,class_id,enrollment_date)values (#{stu.name},#{stu.gender},#{stu.birthDate},#{stu.classId},now())</insert><!--    //    查询 下划线到驼峰式命名法的映射-->
<!--    public List<Student> listAll();--><select id="listAll" resultType="student">select * from student</select><!--    //    多个参数-->
<!--    public List<Student> findStudent(String name,String phone);--><!--    select * from student where name = #{arg0} and phone = #{arg1}--><!--    <select id="findStudent" resultType="student">-->
<!--        select * from student where name = #{name} and phone = #{phone}-->
<!--    </select>-->
<!--    模糊查询--><select id="findStudent" resultType="student">select * from student where name like concat('%',#{name},'%') or phone = #{phone}</select><!--    单个参数-其实识别的不是id是里面的第一个参数-->
<!--    public List<Student> findStudentByName(int id);--><select id="findStudentById" resultType="student">select * from student where student_id = #{iaa}</select></mapper>

七、mybatis中Statement和PreparedStatement

statementType="PREPARED"  默认  使用预编译(防止sql注入)

statementType="STATEMENT" sql 字符串拼接

statementType="CALLABLE"   调用存储过程

<!-- //多个参数
public List<Student> findStudents(String name,String phone);
statementType="PREPARED" 默认 使用预编译STATEMENT sql字符串拼接CALLABLE  调用存储过程
-->
<select id="findStudents" resultType="Student">select * from student where name like concat('%',#{name},'%') or phone=#{phone}
</select>
<!--public Student findStudentById(int id);-->
<select id="findStudentById" resultType="Student" statementType="STATEMENT">select * from student where student_id=${id}
</select>

作业

1、掌握环境搭建

2、掌握单个参数、多个参数的增删改查

3、缓存机制 (一级、二级缓存特点)

4、mybatis核心配置文件 常见的配置项

5、#和$的区别?(重点)

  1. 预处理方式不同

    • #{}:使用预编译(PreparedStatement)方式,参数会被替换为 ?,能有效防止 SQL 注入

    • ${}:使用字符串拼接方式,直接将参数值替换到 SQL 语句中

  2. 安全性

    • #{}:安全,能防止 SQL 注入

    • ${}:不安全,存在 SQL 注入风险

  3. 参数处理

    • #{}:会对传入的参数自动添加引号(字符串类型)

    • ${}:原样替换,不会添加引号

6、sqlMapper文件新增返回自增主键

见6.2

7、预习 动态sql和多表关联映射

动态sql

  • if

  • choose (when, otherwise)

  • trim (where, set)

  • foreach

高级结果映射

MyBatis 创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据库都具备良好的第三范式或 BCNF 范式,可惜它们并不都是那样。 如果能有一种数据库映射模式,完美适配所有的应用程序,那就太好了,但可惜也没有。 而 ResultMap 就是 MyBatis 对这个问题的答案。

比如,我们如何映射下面这个语句?

<!-- 非常复杂的语句 -->
<select id="selectBlogDetails" resultMap="detailedBlogResultMap">selectB.id as blog_id,B.title as blog_title,B.author_id as blog_author_id,A.id as author_id,A.username as author_username,A.password as author_password,A.email as author_email,A.bio as author_bio,A.favourite_section as author_favourite_section,P.id as post_id,P.blog_id as post_blog_id,P.author_id as post_author_id,P.created_on as post_created_on,P.section as post_section,P.subject as post_subject,P.draft as draft,P.body as post_body,C.id as comment_id,C.post_id as comment_post_id,C.name as comment_name,C.comment as comment_text,T.id as tag_id,T.name as tag_namefrom Blog Bleft outer join Author A on B.author_id = A.idleft outer join Post P on B.id = P.blog_idleft outer join Comment C on P.id = C.post_idleft outer join Post_Tag PT on PT.post_id = P.idleft outer join Tag T on PT.tag_id = T.idwhere B.id = #{id}
</select>

你可能想把它映射到一个智能的对象模型,这个对象表示了一篇博客,它由某位作者所写,有很多的博文,每篇博文有零或多条的评论和标签。 我们先来看看下面这个完整的例子,它是一个非常复杂的结果映射(假设作者,博客,博文,评论和标签都是类型别名)。 不用紧张,我们会一步一步地来说明。虽然它看起来令人望而生畏,但其实非常简单。

<!-- 非常复杂的结果映射 -->
<resultMap id="detailedBlogResultMap" type="Blog"><constructor><idArg column="blog_id" javaType="int"/></constructor><result property="title" column="blog_title"/><association property="author" javaType="Author"><id property="id" column="author_id"/><result property="username" column="author_username"/><result property="password" column="author_password"/><result property="email" column="author_email"/><result property="bio" column="author_bio"/><result property="favouriteSection" column="author_favourite_section"/></association><collection property="posts" ofType="Post"><id property="id" column="post_id"/><result property="subject" column="post_subject"/><association property="author" javaType="Author"/><collection property="comments" ofType="Comment"><id property="id" column="comment_id"/></collection><collection property="tags" ofType="Tag" ><id property="id" column="tag_id"/></collection><discriminator javaType="int" column="draft"><case value="1" resultType="DraftPost"/></discriminator></collection>
</resultMap>


http://www.hkcw.cn/article/JlLNveyqEC.shtml

相关文章

Grafana-State timeline状态时间线

显示随时间推移的状态变化 状态区域&#xff1a;即状态时间线上的状态显示的条或带&#xff0c;区域长度表示状态持续时间或频率 数据格式要求&#xff08;可视化效果最佳&#xff09;&#xff1a; 时间戳实体名称&#xff08;即&#xff1a;正在监控的目标对应名称&#xf…

便捷高效能源服务触手可及,能耗监测系统赋能智能建筑与智慧城市

在建筑行业迈向智能化、精细化管理的进程中&#xff0c;传统建筑管理模式因信息割裂、数据利用不足等问题&#xff0c;逐渐难以满足现代建筑复杂的运营需求。楼宇自控系统实现了建筑设备的智能调控&#xff0c;BIM技术则构建了建筑的三维数字化模型&#xff0c;当两者相遇&…

论文阅读:CLIP:Learning Transferable Visual Models From Natural Language Supervision

从自然语言监督中学习可迁移的视觉模型 虽然有点data/gpu is all you need的味道&#xff0c;但是整体实验和谈论丰富度上还是很多的&#xff0c;也是一篇让我多次想放弃的文章&#xff0c;因为真的是非常长的原文和超级多的实验讨论&#xff0c;隔着屏幕感受到了实验的工作量之…

【连接器专题】案例:产品测试顺序表解读与应用

在查看SD卡座连接器的规格书,一些测试报告时,你可能会看到如下一张产品测试顺序表。为什么会出现一张测试顺序表呢? 测试顺序表的使用其实定义测试环节的验证的“路线图”和“游戏规则”,本文就以我人个经验带领大家一起看懂这张表并理解其设计逻辑。 测试顺序表结构 测试…

【MATLAB代码】制导方法介绍与例程——三点法|三维空间,动态目标导引(订阅专栏后可直接查看源代码)

三点法导引是一种导弹制导策略,通过计算导弹、目标和制导站之间的相对位置来确保导弹准确追踪移动目标。该方法利用三角定位和动态调整,实时更新导弹的飞行路径,以提高命中率,广泛应用于军事导弹和无人机等领域。文中有完整的matlab源代码,订阅专栏后即可查看 文章目录 代…

AUTOSAR CP——Can模块

Can模块的主要配置信息 其他相关模块 通讯框图 Can网络唤醒配置&#xff1a;当硬件支持的时候&#xff0c;可以通过Bus唤醒&#xff0c;见《TechnicalReference_Can_ Rscan》 P30 _5.5.1 Wakeup Functionality&#xff1a;RH850芯片时&#xff0c;在不使用SBC时&#xff0c;…

项目执行中缺乏灵活应对机制,如何增强适应性?

项目执行中缺乏灵活应对机制可以通过建立风险预警机制、培养团队快速响应能力、制定动态调整方案、加强团队沟通协作、引入敏捷管理理念来增强适应性。 其中&#xff0c;培养团队快速响应能力尤为重要。这种能力意味着当项目遇到突发状况时&#xff0c;团队能迅速评估问题、确定…

【无刷电机FOC进阶基础准备】【02 常用电磁名词】

目录 磁导率气隙磁感应强度磁通量磁链电感值感应电动势 本节介绍一些高频的电磁名词&#xff0c;大部分在高中阶段出现过&#xff0c;这部分内容不会很严谨&#xff0c;只介绍一些实用的概念。 磁导率 描述一个材料自身的磁性受外部磁场影响的能力&#xff0c;比如磁导率低的材…

接口自动化测试之pytest 运行方式及前置后置封装

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、Pytest 优点认知 1.可以结合所有的自动化测试工具 2.跳过失败用例以及失败重跑 3.结合allure生产美观报告 4.和Jenkins持续集成 5.很多强大的插件 pytest-htm…

PH热榜 | 2025-06-03

1. Knowledge 标语&#xff1a;像认识朋友一样去销售给潜在客户&#xff0c;因为你其实了解他们&#xff01; 介绍&#xff1a;Knowledge 是一个针对个人的销售智能平台&#xff0c;它利用行为数据和心理测评来识别市场上的潜在买家&#xff0c;并指导销售团队以最真实、最有…

【Java】性能调优:利用 jstack 寻找 Java 程序卡顿的真相

前言 当 Java 程序出现给人感觉 “卡顿”、“响应慢”、CPU 风调高、系统给予调用总是延迟时&#xff0c;我们需要采用系统层和虚拟机层的合理工具来分析细节。 本文仅从 JVM 的角度来分析&#xff0c;研究如何利用 jstack 进行 Java 程序性能调优。 Java 程序卡顿的常规原因…

Skyeye 云智能制造办公系统 v3.16.6 发布

Skyeye 云智能制造&#xff0c;采用 Springboot (微服务) Layui UNI-APP Ant Design Vue 的低代码平台。包含 30 多个应用模块、50 多种电子流程&#xff0c;CRM、PM、ERP、MES、ADM、EHR、笔记、知识库、项目、门店、商城、财务、多班次考勤、薪资、招聘、云售后、论坛、公…

Python+requests+pytest+allure自动化测试框架

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 1、核心库 requests request请求 openpyxl excel文件操作 loggin 日志 smtplib 发送邮件 configparser unittest.mock mock服务 2、目录结构 base utils …

06 APP 自动化- H5 元素定位

文章目录 H5 元素定位1、APP 分类2、H5 元素3、H5 元素定位环境的搭建4、代码实现&#xff1a; H5 元素定位 1、APP 分类 1、Android 原生 APP2、混合 APP(Android 原生控件H5页面)3、纯 H5 App 2、H5 元素 H5 元素容器 WebViewWebView 控件实现展示网页 3、H5 元素定位环…

项目计划未与实际情况同步更新,如何保持计划的实时性?

项目计划未与实际情况同步更新&#xff0c;可以通过建立实时更新机制、加强信息共享和沟通、引入敏捷管理工具、实施持续监控流程、明确计划更新责任来保持计划的实时性。 其中&#xff0c;建立实时更新机制至关重要。实时更新机制确保项目计划始终反映最新的进展和问题状况&am…

会议效率低下,应该怎么办

面对会议效率低下的问题&#xff0c;建议从以下几个方面进行优化&#xff1a;明确会议目标、控制会议时长、限定参与人员、使用协作工具、制定会议输出机制。其中&#xff0c;明确会议目标 是提升效率的关键起点。很多无效会议根源在于“为什么开会”这个问题没有回答清楚。只有…

LabVIEW基于 DataSocket从 OPC 服务器读取数据

LabVIEW 中基于 DataSocket 函数从 OPC 服务器读取数据的功能&#xff0c;为工业自动化等场景下的数据交互提供了解决方案。通过特定函数实现 URL 指定、连接建立与管理、数据读取&#xff0c;相比传统 Socket 通信和 RESTful API &#xff0c;在 OPC 服务器数据交互场景有适配…

数据挖掘顶刊《IEEE Transactions on Knowledge and Data Engineering》2025年5月研究热点都有些什么?

本推文对2025年5月出版的数据挖掘领域国际顶级期刊《IEEE Transactions on Knowledge and Data Engineering》进行了分析&#xff0c;对收录的62篇论文的关键词与研究主题进行了汇总&#xff0c;并对其中的研究热点进行了深入分析&#xff0c;希望能为相关领域的研究人员提供有…

结合 AI 生成 mermaid、plantuml 等图表

AI 画图 AI 画图并不是真的让 AI 画一个图片&#xff0c;而是让 AI 根据你的需求&#xff0c;生成对应的需求文本&#xff0c;再根据 “文本画图” 来生成图片。 Mermaid mermaid 支持流程图、时序图、架构图等等多种图片绘制。当然最终生成的效果和样式会根据不同的“文本代…

Java基础(二):八种基本数据类型详解

Java基础系列文章 Java基础(一)&#xff1a;发展史、技术体系与JDK环境配置详解 Java基础(二)&#xff1a;八种基本数据类型详解 目录 一、比特&#xff08;bit&#xff09;和字节&#xff08;Byte&#xff09;1、定义与换算关系2、应用场景差异 二、各类型详解1、整数类型&a…