SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第五天)MyBatis的注解开发

SSM框架的学习与应用(Spring + Spring MVC + MyBatis)-Java EE企业级应用开发学习记录(第五天)MyBatis的注解开发

​ 昨天我们深入学习了MyBatis多表之间的关联映射,了解掌握了一对一关联映射,一对多关联映射,嵌套查询方式以及嵌套结果方式,掌握了缓存机制的一级缓存,二级缓存等概念,也使用了代码进行复现理解。但是都是基于XML配置文件的方式来实现的,现在我们要学习一下Mybatis提供的更加简便的注解配置方式。


那么今天我们要掌握的是MyBatis的注解开发:

  • 掌握基于注解的单表增删改查
  • 掌握基于注解的关联查询

一、基于注解的单表增删改查

什么是注解?

Annotation(注解)就是Java提供了一种为程序元素关联任何信息或任何元数据(metadata)的途径和方法Annotion(注解)是一个接口程序可以通过反射来获取指定程序元素的Annotion对象,然后通过Annotion对象来获取注解里面的元数据

注解不会影响程序代码的执行,Annotation能被用来为某个程序元素(类、方法、成员变量等)关联任何的信息。需要注意的是,这里存在着一个基本的规则:Annotation不能影响程序代码的执行,无论增加、删除 Annotation,代码都始终如一的执行。


什么是MyBatis的注解开发?

MyBatis 支持通过注解来进行数据库操作,这种方式被称为 MyBatis 的注解开发。通过注解可以更直观地在 Java 代码中定义 SQL 语句,省去了繁琐的 XML 配置

MyBatis的注解开发通常需要使用接口来进行。

在我们项目的根目录java下,新建一个dao包。

DAO(Data Access Object)层是在软件架构中用于封装与数据库或其他持久化机制的交互的一种设计模式在典型的三层架构(或多层架构)中,DAO 层通常是位于持久化层的组成部分,它负责执行数据库操作,提供数据的增、删、改、查等基本操作,同时也可以包含一些复杂的查询逻辑它提供了一种抽象层,将应用程序的业务逻辑与底层的数据访问细节分离开来,使代码更加清晰、可维护和可测试。

②dao包中新建一个接口(interface):Bookmapper(如下图)

在这里插入图片描述

③BookMapper接口中编写上SQL放在方法的上方。
package dao;

import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import pojo.Book;

import java.util.List;

public interface BookMapper {
    @Select("select * from book")
    List<Book> selectBook();

    @Select("select * from book where id =#{id}")
    Book getOneBookById(Integer id);

    @Update("update book set id=#{id},bookName=#{bookName},price=#{price},author=#{author}")
    Boolean updateALlItem(Book book);
}

我们之前有学过,SQl语句,那么就很简单能够理解了,抽出一小块理解一下

 @Select("select * from book")//相当于sql语句,用于访问数据库
    List<Book> selectBook();//相当于java里面的方法,返回值是List<Book>
  1. @Select("select * from book"): 这是一个用于查询的注解,表示执行了一个查询操作。括号中的内容是执行的SQL语句,这里查询语句的意思是查询整个 book 表的所有数据。
  2. List<Book>: 这是查询的返回类型,表示查询的结果将会被映射到一个 List 集合中,集合中的每个元素都是一个 Book 对象。
  3. selectBook(): 这是方法的名称,可以根据需要命名。当调用这个方法时,MyBatis会执行对应的SQL查询,并将结果映射到返回类型指定的集合中。记得使用了注解的话,就得对应写入方法,不然会报错。

这样的注解方式可以直接在接口中定义SQL查询语句,非常方便。MyBatis会在运行时根据这些注解执行对应的数据库操作。


④往mybatis-config.xml中注册注解。
    <mappers>
        <mapper resource="mapper/PasswordMSMapper.xml"/>
        <mapper resource="mapper/IdCardMapper.xml"/>
        <mapper resource="mapper/PersonMapper.xml"/>
        <mapper resource="mapper/UserMapper.xml"/>
        <mapper resource="mapper/BookMapper.xml"/>
        <mapper class="dao.BookMapper" />

    </mappers>

注意和以前的xml不同的是,这里是class,不是resource

<mapper class="dao.BookMapper" /> 是 MyBatis 配置文件中的一个元素,用于指定一个 DAO 接口对应的 Mapper 类。这个元素告诉 MyBatis 哪个接口的方法应该与 XML 映射文件中的 SQL 语句进行关联。

​ 在这里,<mapper class="dao.BookMapper" />作用是将名为 BookMapper 的 DAO 接口与 XML 映射文件关联起来,使得该接口的方法可以与 XML 文件中的 SQL 语句进行匹配,从而实现数据库的操作


⑤编写测试类查看效果
 @Test
    void findBookById() {
        //Annotation mode test注解方式查询数据库
        //1.创建SqlSession实例,用于连接数据库
        SqlSession session=MyBatisUtil.createSqlSession();

        //2.调用查询语句,传入参数查询
        List<Book> books=session.selectList("selectBook");
        //3.输出结果
        for(Book book:books){
             logger.info("ID:"+book.getId()+", 书名:"+book.getBookName()+",价格 :"+book.getPrice()+",作者:"+book.getAuthor());
        }
        session.close();//关闭连接,若是增删改这些业务操作需要先提交一下事务session.commit();
    }

在这里插入图片描述

可以发现能够正常的调用sql语句,并且访问数据库获取结果,但是呢红色圈标注的那里,一般我们要做修改成这样:表示调用BookMapper接口中的selectBook方法,这样更符合接口的调用习惯

 //2.调用查询语句,传入参数查询
        List<Book> books=session.getMapper(BookMapper.class).selectBook();

在这里插入图片描述

那么自行补充其他的注解语句,增删改查等,或者可以下载我的资源文件,里面全都写好了


二、掌握基于注解的关联查询

还是我们之前的场景一对一关联映射,一对多关联映射

①一对一关联映射Person和IdCard,先编写俩个类的Mapper接口文件,因为pojo类之前已经生成过了,前面几天中就用过了。

PersonMapper接口如下:

package dao;

import org.apache.ibatis.annotations.*;
import pojo.IdCard;
import pojo.Person;

@Mapper
public interface PersonMapper {

    // 根据id查询人员信息,并关联查询身份证信息
    @Select("SELECT * FROM person WHERE id = #{id}")
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "name", column = "name"),
            @Result(property = "age", column = "age"),
            @Result(property = "sex", column = "sex"),
            @Result(property = "cardId", column = "id", javaType = IdCard.class, one = @One(select = "dao.IdCardMapper.getIdCardById"))
    })//这里就是经典的一对一关联映射了 javaType,One,
    Person getPersonWithIdCard(Integer id);

    // 插入人员信息
      @Insert("INSERT INTO person (name, age, sex, card_id) VALUES (#{name}, #{age}, #{sex}, #{cardId.id})")
    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    void insertPerson(Person person);

    // 更新人员信息
    @Update("UPDATE person SET name = #{name}, age = #{age}, sex = #{sex}, card_id = #{cardId.id} WHERE id = #{id}")
    int updatePerson(Person person);

    // 删除人员信息
    @Delete("DELETE FROM person WHERE id = #{id}")
    int deletePerson(Integer id);
}

IdCardMapper接口如下:

package dao;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import pojo.IdCard;

@Mapper
public interface IdCardMapper {

    @Select("SELECT * FROM idcard WHERE id = #{id}")
    IdCard getIdCardById(@Param("id") Integer id);
    
    //插入语句
     @Insert("INSERT INTO idcard (code) VALUES (#{code})")
    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    void insertIdCard(IdCard idCard);
}

②mybatis-config.xml中写入注解注册
<mappers>
    <mapper resource="mapper/PasswordMSMapper.xml"/>
    <mapper resource="mapper/IdCardMapper.xml"/>
    <mapper resource="mapper/PersonMapper.xml"/>
    <mapper resource="mapper/UserMapper.xml"/>
    <mapper resource="mapper/BookMapper.xml"/>
    <mapper class="dao.BookMapper" />
    <mapper class="dao.PersonMapper" />
    <mapper class="dao.IdCardMapper" />

</mappers>

记得是使用class元素不是resource了

③编写测试类查看一对一关联映射查询的情况

在这里插入图片描述

可以看到生成了俩个sql语句去进行数据库访问,这是因为我们使用了嵌套查询的方式

查看PersonMapper中的设定:

    @Result(property = "cardId", column = "id", javaType = IdCard.class, one = @One(select = "dao.IdCardMapper.getIdCardById"))
④稍微解释一下代码:

当使用 MyBatis 进行一对一关联查询时,我们需要告诉 MyBatis 如何将查询结果映射到 Java 对象中。这时我们会使用 @Result 注解来指定映射关系

  • property:表示 Java 对象中的属性,即要映射的属性名。
  • column:表示数据库中的列名,即查询结果中对应的列。
  • javaType:表示要映射到的 Java 类型,这里是 IdCard.class,表示要将查询结果映射为 IdCard 类型的对象。
  • one:表示一对一关系,这里使用了 @One 注解来指定关联查询的方法。

这段代码的作用是在执行一对一关联查询时,将查询结果中的 id 列映射到 Java 对象的 cardId 属性,并且通过 dao.IdCardMapper.getIdCardById 方法来查询与之关联的证件信息。这样,在查询 Person 信息的同时,也会查询并映射对应的 IdCard 信息。


接下来是一对多关联映射,一对多的场景就是我们之前的俩个表User和tb_Order

①一对一关联映射Users和TbOrder,先编写俩个类的Mapper接口文件,因为pojo类之前已经生成过了,前面几天中就用过了。

UserMapper接口如下:

package dao;

import org.apache.ibatis.annotations.*;
import pojo.Users;
import pojo.TbOrder;

import java.util.List;

@Mapper
public interface UserMapper {

    @Select("SELECT * FROM users WHERE uid=#{id}")
    @Results({
            @Result(property = "uid", column = "uid"),
            @Result(property = "uname", column = "uname"),
            @Result(property = "uage", column = "uage"),
            @Result(property = "orderList", column = "uid", javaType = List.class, many = @Many(select = "dao.TbOrderMapper.findTheOrderByUserId"))
    })
    Users findTheOrderWithUserById(Integer id);
}

这里记得一对多是使用many,然后这里的javaType要改成List.class因为订单可能会有多条记录

TbOrderMapper接口如下:

package dao;

import org.apache.ibatis.annotations.Select;
import pojo.TbOrder;

import java.util.List;

public interface TbOrderMapper {

    @Select("SELECT * FROM tb_order WHERE userid=#{id}")
    List<TbOrder> findTheOrderByUserId(Integer id);
}

②mybatis-config.xml中写入注解注册
 <mappers>
        <mapper class="dao.BookMapper" />
        <mapper class="dao.PersonMapper" />
        <mapper class="dao.IdCardMapper" />
        <mapper class="dao.UserMapper" />
        <mapper class="dao.TbOrderMapper" />
        <mapper resource="mapper/PasswordMSMapper.xml"/>
        <mapper resource="mapper/IdCardMapper.xml"/>
        <mapper resource="mapper/PersonMapper.xml"/>
        <mapper resource="mapper/UserMapper.xml"/>
        <mapper resource="mapper/BookMapper.xml"/>
    </mappers>

在这里插入图片描述

这一次要稍作修改,因为mybatis-config.xml文件中的扫描方式是从上往下扫描,所以<mappers>元素下引入UsersMapper和OrdersMapper接口的位置,必须在引入UserMapper.xml和TbOrderMapper.xml文件位置前面,否则程序将会首先读取到引入的UserMapper.xml和TbOrderMapper.xml文件,程序将有可能会报错。

③编写测试类:
//使用注解方式一对多关联查询订单信息通过id
@Test
void findTheOrderWithUserById(){
    SqlSession session = MyBatisUtil.createSqlSession();
  Users users=session.getMapper(dao.UserMapper.class).findTheOrderWithUserById(1);
    List<TbOrder> tbOrders=users.getOrderList();
    for (TbOrder order:tbOrders){
        logger.info("id"+users.getUid()+",姓名:"+users.getUname()+",年龄:"+users.getUage()+",产品名:"+order.getProductname()+",价格:"+order.getPrice()+",库存"+order.getNumber());
    }
    session.close();
}

输出结果如下:

在这里插入图片描述

成功显示一对多数据查询,那么要注意的是一对一一对多的数据插入等操作,记得先对单表进行操作,再去更新有外键的表,这样才不会报错,出现误读。


以下是一些常用的 MyBatis 注解及其用法:

  1. @Select:用于查询操作。

    @Select("SELECT * FROM users WHERE id = #{id}")
    User getUserById(int id);
    
  2. @Insert:用于插入操作。

    @Insert("INSERT INTO users (id, username, email) VALUES (#{id}, #{username}, #{email})")
    int insertUser(User user);
    
  3. @Update:用于更新操作。

    @Update("UPDATE users SET username = #{username}, email = #{email} WHERE id = #{id}")
    int updateUser(User user);
    
  4. @Delete:用于删除操作。

    @Delete("DELETE FROM users WHERE id = #{id}")
    int deleteUser(int id);
    
  5. @Result@Results:用于定义结果映射。

    @Results({
        @Result(column = "id", property = "id"),
        @Result(column = "username", property = "username"),
        @Result(column = "email", property = "email")
    })
    @Select("SELECT * FROM users")
    List<User> getAllUsers();
    
  6. @Param:用于传递参数。

    @Select("SELECT * FROM users WHERE username = #{username} AND email = #{email}")
    User getUserByUsernameAndEmail(@Param("username") String username, @Param("email") String email);
    
  7. @Options:用于设置一些选项,如主键返回,主键自增等

    @Insert("INSERT INTO users (username, email) VALUES (#{username}, #{email})")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insertUser(User user);
    
  8. @ResultMap:引用在 XML 配置文件中定义的 ResultMap。

    @ResultMap("UserResultMap")
    @Select("SELECT * FROM users WHERE id = #{id}")
    User getUserById(int id);
    

使用注解开发可以更紧凑地定义数据库操作,但对于复杂的动态 SQL 或多表关联查询,通常 XML 配置更为灵活和可读。在实际项目中,你可以根据场景选择使用注解还是 XML 配置,甚至两者结合使用。


总结

今天是Mybatis学习的第五天,今天学的Mybatis的注解开发。其实需要详细理解一下,然后自己去完成一下注解方式单表的增删改,还有注解方式的多表关联查询,嵌套条件方式和嵌套结果方式。看似简单,实则需要自己动手操作才能彻底掌握,理解清楚多表之间的关系,哪个表必须先处理,然后怎么样去嵌套获取信息等。还有今天了解一些注解关键字,虽然看着熟悉,实际上使用的话,还是会有一些坑要踩的,需要慢慢理解。

​ 想要跟着学习的可以去我的资源里面找对应的文件下载,我的md文件也会发上去,项目文件会上传可以自己跟着学习一下。

PS:还可以自己学着掌握使用Mybatis和Xml联合开发的方式,或者我后面单独放一章出来讲

作者:Stevedash

发表于:2023年8月27日 14点40分

注:本文内容基于个人学习理解,如有错误或疏漏,欢迎指正。感谢阅读!如果觉得有帮助,请点赞和分享。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/96700.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】每日一题(除自身以外数组的乘积)

添加链接描述&#xff0c;链接奉上 方法&#xff1a; 暴力循环:前缀积后缀积&#xff08;分组&#xff09;: 暴力循环: 暴力循换真的是差生法宝&#xff0c;简单好懂&#xff0c;就是不实用&#xff0c;大多数的题目都会超过时间限制&#xff08;无奈&#xff09; 思路&…

postgresql-字符函数

postgresql-字符函数 字符串连接字符与编码字符串长度大小写转换子串查找与替换截断与填充字符串格式化MD5 值字符串拆分字符串反转 字符串连接 concat(str, …)函数用于连接字符串&#xff0c;并且忽略其中的 NULL 参数&#xff1b;concat_ws(sep, str, …) 函数使用指定分隔…

【JS案例】JS实现图片放大镜功能

JS案例图片放大镜 &#x1f31f;效果展示 &#x1f31f;HTML结构 &#x1f31f;CSS样式 &#x1f31f;实现思路 &#x1f31f;具体实现 1.初始化数据图片 2.获取所需DOM元素 3.初始化页面 初始化缩略图 绑定事件 &#x1f31f;完整代码 &#x1f31f;写在最后 &…

Centos7安装ZK-UI管理界面安装|Maven|Git|

一: JDK1.8安装 参考: Centos7卸载|安装JDK1.8|Xshell7批量控制多个终端 二&#xff1a;Maven安装 2.1&#xff1a;下载maven安装包 maven 下载地址&#xff1a;https://mirror.bit.edu.cn/apache/maven/maven-3/ [rootwww ~]# mkdir -p /usr/local/maven [rootwww ~]# …

STM32+RTThread配置以太网无法ping通,无法获取动态ip的问题

记录一个非常蠢的问题&#xff0c;今天在移植rtthread的以太网驱动的时候出现无法获取动态ip的问题&#xff0c;问题如下&#xff1a; 设置为动态ip时不管是连接路由器还是电脑主机都无法ping通&#xff0c;也无法获取dns地址。 设置为静态ip时无法ping通主机。 使用wireshark…

Docker笔记

学习了神光大佬的《Nest 通关秘籍》后&#xff0c;对docker做了个笔记&#xff0c;并实操部署了一下个人项目&#xff0c;在此记录一下 是什么 Docker是一种开源的容器化平台&#xff0c;它可以将应用程序及其依赖项打包到一个可移植的容器中&#xff0c;使得应用程序能够在任…

java八股文面试[JVM]——JVM调优

知识来源&#xff1a; 【2023年面试】JVM性能调优实战_哔哩哔哩_bilibili

测试平台metersphere

metersphere可以做接口测试、UI测试、性能测试。 metersphere接口测试底层是jmeter&#xff0c;可以做API管理&#xff0c;快捷调试&#xff0c;接口用例管理&#xff0c;接口自动化场景执行一键选取用例范围&#xff0c;生成测试报告。 会用jmeter&#xff0c;metersphere会…

深入浅出AXI协议(3)——握手过程

一、前言 在之前的文章中我们快速地浏览了一下AXI4协议中的接口信号&#xff0c;对此我们建议先有一个简单的认知&#xff0c;接下来在使用到的时候我们还会对各种信号进行一个详细的讲解&#xff0c;在这篇文章中我们将讲述AXI协议的握手协议。 二、握手协议概述 在前面的文章…

VS的调试技巧

Visual Studiohttps://visualstudio.microsoft.com/zh-hans/vs/ 目录 1、什么是调试&#xff1f; 2、debug和release 3、调试 3.1、环境 3.2、 快捷键 3.2.1、F10和F11 3.2.2、ctrlF5 3.2.3、F5与F9 3.2.3.1、条件断点 3.3、监视和内存观察 3.3.1、监视 3.3.2、内存 …

多目标应用:基于多目标向日葵优化算法(MOSFO)的微电网多目标优化调度MATLAB

一、微网系统运行优化模型 参考文献&#xff1a; [1]李兴莘,张靖,何宇,等.基于改进粒子群算法的微电网多目标优化调度[J].电力科学与工程, 2021, 37(3):7 二、多目标向日葵优化算法 多目标向日葵优化算法&#xff08;Multi-objective sunflower optimization&#xff0c;MOS…

JavaScript基础语法01——初识JavaScript

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 最近有项目用到KingFusion软件&#xff0c;由于KingFusion是B/S架构的客户端组态软件&#xff0c;因此在学习KingFusion产品时会涉及许多前端的知识。 像JavaScript语言就是需要用的&#xff0c;俗话说&#xff1a;活到…

Leedcode19. 删除链表的倒数第 N 个结点

给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[] 示例 3&#xff1a; 输入&#xff1…

java八股文面试[数据库]——MySQL索引的数据结构

知识点&#xff1a; 【2023年面试】mysql索引的基本原理_哔哩哔哩_bilibili 【2023年面试】mysql索引结构有哪些&#xff0c;各自的优劣是什么_哔哩哔哩_bilibili

哈希的应用——布隆过滤器

✅<1>主页&#xff1a;&#xff1a;我的代码爱吃辣 &#x1f4c3;<2>知识讲解&#xff1a;数据结构——位图 ☂️<3>开发环境&#xff1a;Visual Studio 2022 &#x1f4ac;<4>前言&#xff1a;布隆过滤器是由布隆&#xff08;Burton Howard Bloom&…

论文解读:Image-Adaptive YOLO for Object Detection in Adverse Weather Conditions

发布时间&#xff1a;2022.4.4 (2021发布&#xff0c;进过多次修订) 论文地址&#xff1a;https://arxiv.org/pdf/2112.08088.pdf 项目地址&#xff1a;https://github.com/wenyyu/Image-Adaptive-YOLO 虽然基于深度学习的目标检测方法在传统数据集上取得了很好的结果&#xf…

Postman中参数区别及使用说明

一、Params与Body 二者区别在于请求参数在http协议中位置不一样。Params 它会将参数放入url中以&#xff1f;区分以&拼接Body则是将请求参数放在请求体中 后端接受数据: 二、body中不同格式 2.1 multipart/form-data key - value 格式输入&#xff0c;主要特点是可以上…

Fei-Fei Li-Lecture 16:3D Vision 【斯坦福大学李飞飞CV课程第16讲:3D Vision】

目录 P1 2D Detection and Segmentation P2 Video 2D time series P3 Focus on Two Problems P4 Many more topics in 3D Vision P5-10 Multi-View CNN P11 Experiments – Classification & Retrieval P12 3D Shape Representations P13--17 3D Shape Represen…

hadoop大数据集群中更换磁盘,balance的速度缓慢问题(解决)

hadoop大数据集群中更换磁盘&#xff0c;balance的速度缓慢问题&#xff08;解决&#xff09; 看现象只有4个bloucks在执行的 调整参数&#xff1a; 增大配置参数&#xff0c;观察重新负载的速度 修改配置文件 hdfs-site.xml dfs.datanode.balance.max.concurrent.moves100 …

多线程应用——单例模式

单例模式 文章目录 单例模式一.什么是单例模式二.如何实现1.口头实现2.利用语法特性 三.实现方式&#xff08;饿汉式懒汉式&#xff09;1.饿汉式2.懒汉式3.线程安全的单例模式4.双重检查锁5.禁止指令重排序 一.什么是单例模式 单例模式&#xff08;Singleton Pattern&#xff…