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 语句进行匹配,从而实现数据库的操作


⑤编写测试类查看效果
 @Testvoid 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.hqwc.cn/news/90060.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

excel 分组排序

excel中会遇到对不同分组数据进行排序&#xff0c;比如对于不同班级里的学生按照分数高低进行升序排序&#xff0c;可以采用如下公式 SUMPRODUCT((A$2:A$12A2)*(C$2:C$12>C2))1 如果需要 进行降序排序&#xff0c;将公式中的大于号替换为小于号即可

Leetcode80. 删除有序数组中的重复项 II

给你一个有序数组 nums &#xff0c;请你 原地 删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 class Solu…

Postman中参数区别及使用说明

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

整合SSM:Mybatis层

SSM&#xff08;SpringSpringMVCMyBatis&#xff09;框架集由Spring、MyBatis两个开源框架整合而成.为了加深记忆学习,也为了后续资源方便使用.所以决定就对SSM做一个整合,首先是Mybatis层。 思路&#xff1a; 1.开发环境 基本环境&#xff1a; IDEA MySQL 8.0.22 Tomcat 9…

SpringBoot简单上手

spring boot 是spring快速开发脚手架&#xff0c;通过约定大于配置&#xff0c;优化了混乱的依赖管理&#xff0c;和复杂的配置&#xff0c;让我们用java-jar方式,运行启动java web项目 入门案例 创建工程 先创建一个空的工程 创建一个名为demo_project的项目&#xff0c;并且…

成集云 | 抖店客户静默下单催付数据同步钉钉 | 解决方案

源系统成集云目标系统 方案介绍 随着各品牌全渠道铺货&#xff0c;主播在平台上直播时客户下了订单后不能及时付款&#xff0c;第一时间客户收不到提醒&#xff0c;不仅造成了客户付款率下降&#xff0c;更大量消耗了企业的人力成本和经济。而成集云与钉钉深度合作&#xff0…

vue中实现echarts三维散点图

需要安装 echarts 同时引入 echarts-gl 我安装的版本&#xff1a; "echarts": "^5.3.2", "echarts-gl": "^2.0.9", import Vue from "vue"; import * as echarts from "echarts"; Vue.prototype.$echarts echa…

YOLO目标检测——蔬菜检测数据集下载分享

YOLO蔬菜检测数据集&#xff0c;真实场景的高质量图片数据&#xff0c;数据场景丰富&#xff0c;图片格式为jpg&#xff0c;共21000张图片。 数据集点击下载&#xff1a;YOLO蔬菜检测数据集21000图片数据说明.rar

Java自定义捕获异常

需求分析 ElectricalCustomerVO electricalCustomerVO new ElectricalCustomerVO(); electricalCustomerVO.setElcNumber(chatRecordsLog.getDeviceNumber()); List<ElectricalCustomerVO> electricalCustomerlist electricalCustomerMapper.selectElectricalCustomer…

11.物联网lwip,网卡原理

一。LWIP协议栈内存管理 1.LWIP内存管理方案 &#xff08;1&#xff09;堆heap 1.灰色为已使用内存 2.黑色为未使用内存 3.紫色为使用后内存 按照某种算法&#xff0c;把数据放在内存块中 &#xff08;2&#xff09;池pool 设置内存池&#xff0c;设置成大小相同的内存块。 2…

MyBatisx代码生成

MyBatisx代码生成 1.创建数据库表 CREATE TABLE sys_good (good_id int(11) NOT NULL,good_name varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,good_desc varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,PRIMARY KEY (good_id) ) ENGINEInnoDB DEFAULT CHA…

信息化发展10

消费互联网基本属性 消费互联网具有的属性包括&#xff1a; 1 &#xff09; 媒体属性&#xff1a; 由自媒体、社会媒体以及资讯为主的门户网站。 2&#xff09; 产业属性&#xff1a; 由在线旅行和为消费者提供生活服务的电子商务等其他组成。 数字中国概览示意图 在党的十九…