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

news2024/11/16 16:48:41

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分

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于Milvus Cloud的相似穿搭推荐系统教程——图像分割

作为一个大众眼中的“非典型程序员”,我喜欢拥抱时尚和潮流,比如我经常在演讲时穿粉色裤子,这甚至已经成为一个标志性打扮。某天又逢主题演讲日,我站在衣柜前挑选上衣的时候,忽然灵光乍现:有没有可能借助 Milvus Cloud找到和我穿搭风格最为相似的明星呢? 这个想法在我脑…

不系安全带抓拍自动识别

不系安全带抓拍自动识别系统通过yolo系列算法框架模型利用高清摄像头&#xff0c;不系安全带抓拍自动识别算法对高空作业场景进行监控&#xff0c;当检测到人员未佩戴安全带时会自动抓拍并进行告警记录。YOLO系列算法是一类典型的one-stage目标检测算法&#xff0c;其利用ancho…

Day44|leetcode 518.零钱兑换II、377. 组合总和 Ⅳ

完全背包理论基础 视频链接&#xff1a;带你学透完全背包问题&#xff01; 和 01背包有什么差别&#xff1f;遍历顺序上有什么讲究&#xff1f;_哔哩哔哩_bilibili 完全背包与01背包不同的地方就是&#xff1a;01背包每种物品只能取一次&#xff0c;而完全背包每种物品可以取…

【排序】快速排序(前后指针法)—— 考的最少的一种算法

以从小到大的顺序进行说明。 前后指针法 是指对于一个数组&#xff0c;定义前后各一个指针&#xff08;prev 和 cur&#xff09; prev用于卡一个比基准值大的值进行交换cur用于向前遍历出比基准值小的&#xff0c;和prev进行交换 图解 初始化 选出基准值4 如果cur 所在的值…

重要岗位人员脱岗预警 脱岗监测预警算法

重要岗位人员脱岗预警 脱岗监测预警算法通过yolov8网络模型深度学习算法&#xff0c;重要岗位人员脱岗预警 脱岗监测预警算法对现场人员行为进行实时监测和识别&#xff0c;通过算法识别脱岗、睡岗和玩手机等异常行为&#xff0c;实现对人员行为的预警和告警。YOLOv8是目前YOLO…

java八股文面试[多线程]——什么是守护线程

知识来源&#xff1a; 【2023年面试】什么是守护线程_哔哩哔哩_bilibili

【Linux】DNS系统,ICMP协议,NAPT技术

遏制自己内心的知识优越感&#xff0c;才能让你发自内心的去尊重他人&#xff0c;避免狂妄自大&#xff0c;才能让你不断的丰富自己的内心。 文章目录 一、DNS系统1.DNS服务器返回域名对应的ip2.使用dig工具分析DNS过程3.浏览器中输入url后发生的事情&#xff1f; 二、ICMP协议…

【Springboot】| 从深入自动配置原理到实现 自定义Springboot starter

目录 一. &#x1f981; 前言二. &#x1f981; Spring-boot starter 原理实现分析2.1 自动配置原理 三. &#x1f981; 操作实践3.1 项目场景3.2 搭建项目3.3 添加相关依赖3.4 删除一些不需要的东西3.5 发邮件工具类逻辑编写3.6 创建相关配置类3.7 创建 Spring.factories 文件…

java八股文面试[多线程]——死锁、活锁、饥饿

DCL双重锁&#xff1a;TODO 如何预防死锁&#xff1a; 如何查看线程死锁&#xff1a; 知识来源&#xff1a; 【2023年面试】描述一下线程安全活跃态问题&#xff0c;以及竞态条件_哔哩哔哩_bilibili 【2023年面试】如何预防死锁_哔哩哔哩_bilibili 【并发与线程】阿里一面&…

手把手教你用 ANSYS workbench

ANSYS Workbench ANSYS Workbench是一款基于有限元分析&#xff08;FEA&#xff09;的工程仿真软件。其基本概念包括&#xff1a; 工作区&#xff08;Workspace&#xff09;&#xff1a;工程仿真模块都在此区域内&#xff0c;包括几何建模、网格划分、边界条件设置、分析求解等…

锐捷PPP协议原理--尚文网络敏姐

PPP 点对点协议 目录 PPP 点对点协议 PPP 简介 PPP协议层介绍&#xff1a; PPP协议工作原理 第一个阶段&#xff1a;LCP协商 第二阶段&#xff1a;身份认证阶段 第三阶段&#xff1a;NCP协商阶段 PPP配置实验 PAP的单向认证&#xff1a; PAP双向认证 CHAP的单向认证&#…

数组名和函数名是指针?指针和引用底层一样?

在2023/8/26日晚上&#xff0c;我看到一个所谓“典”的视频&#xff0c;一开始还没太在意&#xff0c;后面想了想发现我貌似也一直犯了以下的错误&#xff0c;而错误的原因在于我在新手阶段学习C/C并不是查阅文档扎好脚步学习的&#xff0c;而是被铺天盖地的新手学习基础教程里…

图书管理系统Java书店进销存jsp源代码MySQL

本项目为前几天收费帮学妹做的一个项目&#xff0c;Java EE JSP项目&#xff0c;在工作环境中基本使用不到&#xff0c;但是很多学校把这个当作编程入门的项目来做&#xff0c;故分享出本项目供初学者参考。 一、项目描述 图书管理系统 系统有1权限&#xff1a;管理员 用所技…

5.网络原理之初识

文章目录 1.网络发展史1.1独立模式1.2网络互连1.3局域网LAN1.3.1基于网线直连1.3.2基于集线器组建1.3.3基于交换机组建1.3.4基于交换机和路由器组建1.3.4.1路由器和交换机区别 1.4广域网WAN 2.网络通信基础2.1IP地址2.2端口号2.3认识协议2.4五元组2.5 协议分层2.5.1 分层的作用…

weak_ptr是怎么探知对象生死的

weak_ptr是C智能指针中的一种。它用于解决共享所有权的问题&#xff0c;并且可以避免因循环引用而导致的内存泄漏。 weak_ptr本身并不承担对象的所有权&#xff0c;它指向由shared_ptr管理的对象。与shared_ptr不同&#xff0c;weak_ptr并不会增加计数器来计算对象的引用次数。…

【30天熟悉Go语言】11 数组的全方位使用与解析

作者&#xff1a;秃秃爱健身&#xff0c;多平台博客专家&#xff0c;某大厂后端开发&#xff0c;个人IP起于源码分析文章 &#x1f60b;。 源码系列专栏&#xff1a;Spring MVC源码系列、Spring Boot源码系列、SpringCloud源码系列&#xff08;含&#xff1a;Ribbon、Feign&…

工厂机械臂人员闯入自动预警

工厂机械臂人员闯入自动预警系统通过yolov8系列网络模型深度学习算法&#xff0c;工厂机械臂人员闯入自动预警算法实时监测工作区域内的人员位置和机械臂设备的运行状态&#xff0c;实现对人员闯入的识别和预警。一旦系统检测到人员闯入作业区域&#xff0c;立即发出警报并同步…

java八股文面试[多线程]——什么是线程安全

对线程安全的理解 总结&#xff1a;一个进程内的多个线程同时访问堆内存。 知识来源&#xff1a; 【并发与线程】对线程安全的理解_哔哩哔哩_bilibili

Linux 多线程基础

文章目录 前言一、多线程基础函数1. pthread_create2. pthread_self3. pthread_exit4. pthread_join5. pthread_cancel6. pthread_detach 二、线程间的共享数据三、多线程 &#xff0c;进程对比总结 前言 一、多线程基础函数 1. pthread_create 创建新的线程。 #include <…

第二章 Linux基础命令

目录 一、 Linux的目录结构  1.学习目标  2.Linux的目录结构  3.Linux路径的描述方式  4.本小节的总结  5.课后练习 二、 Linux命令入门  2.1 Linux命令基础  1.学习目标  2.什么是命令、命令行  3.Linux命令基础格式  4.本小节的总结 2.2 ls命令入门  1…