当前位置: 首页 > news >正文

Mybatis 注解(详细版)

前言

随着对mybatis 框架的学习和理解,我们发现真正需要频繁改动的是 mapper映射文件。

在mapper 映射文件中,我们时常 会根据具体的场景,写操作数据库的sql 语句以及操作数据库需要的环境【描述表与表之间的关联关系,参数类型,结果集类型等】。并且发现,每一个实体类都有一个对应的mapper 映射文件。

缺点:在实际开发中,发现,在编写mapper 映射文件,需要写大量的xml 配置。这是非常麻烦的!因此为了更加简单,简洁,才使用 注解的方式逐渐取代mapper 映射文件


基于注解的单表增删改查

使用注解描述增删改查操作,可以点击下面的博客链接,联合起来思考,方便理解

使用mybatis -基本的增删改查-CSDN博客


列举 @Select ,@insert ,@Update ,@Delete ,@Param 注解

任何demo(案例)准备工作

项目准备

1 tb_worker 数据表, 实体类 Worker 类

  • tb_worker 数据表

  •  实体类 Worker 类

2 使用log4j日志依赖 观察运行情况

   <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
  • 添加关于日志的配置文件:log4j.properties
# Set root logger level
log4j.rootLogger=DEBUG, stdout

# Set the log output format
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
  • 在 mybatis-config 配置文件 启用日志
<settings>
<!--    启用日志-->
    <setting name="logImpl" value="LOG4J"/>
</settings>
  • 注意:<settings> 标签应该放在 <properties>标签下

3 加载 WorkMapper接口 在mybatis-config 配置文件

   <mapper class="fs.mapper.WorkMapper"></mapper>

列举 @Select ,@insert ,@Update ,@Delete ,@Param 注解

@Select 注解

提示:@Select 注解 用于映射查询语句,其作用等同于xml 配置文件 中的<select> 元素

demo(案例)

WorkMapper 接口

  @Select("select * from tb_worker where id = #{id}")
    // 查询所有员工信息
    public Worker selectWorker(int id);

运行截图


@insert 注解

提示:@insert 注解 用于映射插入语句,其作用等同于xml 配置文件 中的<insert> 元素 

demo(案例)

WorkMapper 接口

  // 插入员工信息
    @Insert("insert into tb_worker(worker_id,name,sex,age) values(#{worker_id},#{name},#{sex},#{age})")
    public int insertWorker(Worker worker);

运行截图


@Update 注解

提示:@Update 注解 用于映射更新语句,其作用等同于xml 配置文件 中的<update> 元素 

demo(案例)

WorkMapper 接口

 // 更新 员工信息
    @Update("update tb_worker set name = #{name},age = #{age} where id = #{id}")
    int updateWorker(Worker worker);

运行截图


@Delete 注解

提示:@Delete 注解 用于映射删除语句,其作用等同于xml 配置文件 中的<delete> 元素 

demo(案例)

WorkMapper 接口

  // 删除员工信息
    @Delete("delete from tb_worker where id = #{id}")
    int deleteWorker( int id);

运行截图


@Param 注解

功能:@Param 注解是指定sql 语句中的参数,通常用于sql 语句中参数比较多的情况

demo(案例)

WorkMapper 接口

 //通过员工 id 和员工姓名查询员工信息
    @Select("select * from tb_worker where id = #{param01} and name = #{param02}")
    Worker selectWorkerByIdAndName(@Param("param01") int id,@Param("param02" ) String name);

具体步骤:给方法中的参数 起别名,并且别名一般是在参数的左边。如上图的代码, id 的别名是 param01 , name 的别名是 param02。同时还要id,name两个 参数的 别名,需要与@Select 注解的中的 “ #{ }” 中的名称 一一对应。这样 @Param 注解 用于将参数id,name 的值映射到#{param01} 和 #{param02) 中

运行截图


总结

1 在进行增删改操作时,最后记得提交事物,否则你修改的数据,不会保存到数据库中

sqlSession.commit();

2 理解 怎么调用WorkMapper 接口的方法

  WorkMapper mapper = sqlSession.getMapper(WorkMapper.class);

查看底层代码,使用 动态代理技术,创建代理类 在某种程度上,实现了 WorkMapper 接口

下一步

进入MapperProxy 底层代码


基于注解的关联查询

可以点击下面这篇博客,相互学习          Mybatis 的关联映射(一对一,一对多,多对多)-CSDN博客​​​​​​


如何 学习注解的关联查询?

1 使用注解进行关联查询是 单表操作增删改查操作的延申,使用注解进行单表查询

2 学会关联查询中几个常用的注解

  • @One:表示 表与表是一对一的关系 相当于在<resultMap>标签中的<association>元素
  • @Many:表示 表与表是 一对多的关系,相当于<resultMap>标签中的<collection>元素
  • @Results:在该注解中存在很多个@Result

@Result 注解相当于<resultMap>标签

  • property 属性:用于指定关联的实体类属性
  • column 属性:用于指定关联的数据库中表的字段

一对一查询

样图

 Person 实体类

在WorkMapper 接口中,表之间是一对一关系,使用注解

注意:这两段代码,虽然表示的内容不同,但都是 一对一关系 表之间的查询,嵌套查询方式【多步到位】

在mapper 映射文件 表之间是 一对一关系,嵌套查询方式【多步到位】

<select id="findPersonById" parameterType="int" resultMap="card">
    select * from tb_person where id = #{id}
</select>
    <resultMap id="card" type="fs.pojo.Person">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="sex" column="sex"/>
        <result property="age" column="age"/>
<!--        嵌套查询方式-->
        <association property="card" column="card_id" javaType="fs.pojo.IdCard"
                     select="fs.mapper.IdCardMapper.findCodeById"/>
    </resultMap>
 

分析

比较两端代码发现,@Result 等于 <resultMap>标签

1 为什么在mapper 映射文件中Person 实体类 的属性,映射的字段都写满了,而使用注解表示,却只映射两表的关联属性 card,其他的却没有?

答:使用 注解时,主体类 person 类的基属性可以自动完成映射,也被称为隐式映射。相较于显示映射而言,更加简洁

2 隐式映射 的应用场景?


答:MyBatis 有一个默认的映射规则,即如果字段名和数据库列名一致,MyBatis 会自动完成映射。例如,tb_person 表中的 id 列会自动映射到 Person 类的 id 属性,name 列会自动映射到 Person 类的 name 属性。


3  隐式映射 和显示映射的区别?

答:所有关系类型都可以使用隐式映射或显式映射,区别在于:

  1. 一对一关系:通常更简单,主表字段较少,隐式映射往往足够满足需求。

  2. 一对多或多对多关系:通常涉及集合字段(如 List<Order>List<Role>),这些字段需要通过 @Many@Collection 注解显式处理,但主表字段仍然可以使用隐式映射。


4  为什么说在列举的代码和图片中都使用了 嵌套查询方式实现映射文件?

嵌套查询方式在 mysql数据库中,可以理解为嵌套子查询

样例

SELECT p.id AS person_id, p.name,
       (SELECT ic.id FROM tb_idcard ic WHERE ic.id = p.card_id) AS card_id,
       (SELECT ic.number FROM tb_idcard ic WHERE ic.id = p.card_id) AS card_number
FROM tb_person p;

对比上面的代码,发现无论是否使用注解 ,都有一个select  属性,属性值为另一个被嵌套sql语句关联的接口的对应的方法的地址

地址一般格式表示为:接口路径+对应的方法名


一对多查询

样图

Orders 实体类

OrderMapper 接口

分析

  • @Result(id = true, property = "id", column = "id")
    表示将数据库表中的 id 列映射到 Orders 类的 id 属性,并且 id 是主键(id = true

  • @Result(property = "number", column = "number")
    表示将数据库表中的 number 列映射到 Orders 类的 number 属性。

  • @Result(property = "productList", column = "id", many = @Many(select = "fs.mapper.ProductMapper.selectProductByOrdersId"))
    表示将订单中的产品列表(productList)与订单 ID 关联,并通过 ProductMapper.selectProductByOrdersId 方法进行查询。many 表示这是一个一对多的关系(一个订单可以包含多个产品)。


关于下面这行代码的解读

 @Result(property = "productList",column = "id")


不使用注解在mapper 映射文件

注意:这两段代码,虽然表示的内容不同,但都是 一对多关系 表之间的查询,嵌套查询方式【多步到位】

样例

 <select id="findOrdersWithProduct1" parameterType="int" resultMap="orders">
        select * from tb_orders where id=#{id};
    </select>
    <resultMap id="orders" type="fs.pojo.Orders">
        <id property="id" column="id"/>
        <result property="number" column="number"/>
        <collection property="productList"  column="id" ofType="fs.pojo.Product" select="fs.mapper.ProductMapper.findProductById">
        </collection>
    </resultMap>

多对多查询

需要构建一张中间表,维持两张表多对多这个关系。其他的和一对多,是一样的!

相关文章:

  • UE小:UE5.5 PixelStreamingInfrastructure 使用时注意事项
  • 15 | 定义简洁架构 Store 层的数据类型
  • Skyvern AI 实现 浏览器爬虫+自动化工具
  • coze ai assistant Task 2
  • Flash Attention 算法简介
  • Math.NET Numerics 库怎么装
  • 【Linux内核系列】:文件系统
  • 治愈系自媒体运营方案
  • Linux 字符设备驱动实例
  • 第二章:Qt常用界面组件
  • Java程序开发之Spring Boot快速入门:5分钟搭建RESTful API
  • angular中下载接口返回文件
  • Qt的QMenu 和 QAction的样式设置
  • 骑士74CMS_v3.34.0SE版uniapp全开源小程序怎么编译admin和member流程一篇文章说清楚
  • 计算机毕业设计:ktv点歌系统
  • 使用arm嵌入式编译器+makefile编译管理keil项目
  • openai agents SDK原理详解
  • golang从入门到做牛马:第十六篇-Go语言`range`:循环遍历的“瑞士军刀”
  • PID控制器的整定的方法
  • Java中的加盐加密:提升密码存储安全性的关键实践
  • 探秘多维魅力,长江经济带、珠三角媒体总编辑岳阳行启动
  • 悬疑剧背后的女编剧:创作的差异不在性别,而在经验
  • 日本一季度实际GDP环比下降0.2%
  • 商务部:长和集团出售港口交易各方不得规避审查
  • 人民日报:从“轻微免罚”看涉企执法方式转变
  • 经济日报评外卖平台被约谈:行业竞争不能背离服务本质