MyBatis 注解开发

news2024/11/25 10:27:59

文章目录

    • 一、单表查询
      • 1. @Select 注解
      • 2. @Insert 注解
      • 3. @Update 注解
      • 4. @Delete 注解
      • 5. @Param 注解
    • 二、多表关联查询
      • 1. 一对一查询
      • 2. 一对多查询
      • 3. 多对多查询

一、单表查询

1. @Select 注解

前面的章节介绍了 MyBatis 的基本用法、关联映射、动态 SQL 和缓存机制等知识,所有的配置都是基于 XML 文件完成的,但在实际开发中,大量的 XML 配置文件的编写是非常繁琐的,为此,MyBatis 提供了更加简便的基于注解的配置方式。本篇将对 MyBatis 的注解开发进行详细讲解。

① 在项目的 com.tyut.pojo 包下创建持久化类 Worker,在 Worker 类中定义 id、员工姓名、年龄、性别、工号等属性以及属性对应的 getter/setter 方法。

② 在 com.tyut.dao 包下创建 WorkerMapper 接口,用于编写 @Select 注解映射的 select 查询方法。

package com.tyut.dao;
import com.tyut.pojo.Worker;
import org.apache.ibatis.annotations.Select;
public interface WorkerMapper {
    @Select("select * from tb_worker where id = #{id}")
    public Worker selectWorker(int id);
}

与之前不同的是,之前我们的 SQL 语句是写在 XML 映射文件中的,现在我们是注解开发不再需要 XML 了,而是去创建一个接口类,编写注解映射的 SQL 方法。

注意接口类的名字是有规范的,表名加 Mapper 的格式!

③ 因为不再是映射文件了,而是一个接口,所以需要在核心配置文件中引入 WorkerMapper 接口,告诉 MyBatis 我们的接口在哪里。

<mapper class="com.tyut.dao.WorkerMapper"/>

注意这里是 class 属性,不是 resource!

④ 编写测试方法,我们通过 MyBatis 的固定 API session.getMapper(WorkerMapper.class) 得到接口对象,然后就可以调用接口的方法了。

public void findWorkerByIdTest() {
    //1.获取SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    WorkerMapper mapper = session.getMapper(WorkerMapper.class);
    //2.查询id为1的员工信息
    Worker worker = mapper.selectWorker(1);
    System.out.println(worker);
    //3.关闭SqlSession
    session.close();
}

为了减少代码量,其实我们可以把公共部分写在 Before 和 After 中,代表每做一次 Test 都会先去执行 Before,并且最后执行一遍 After,而在 Test 中直接调用接口方法即可。

在这里插入图片描述

2. @Insert 注解

① 在 WorkerMapper 接口中添加插入数据的方法 insertWorker(),并在方法中添加 @Insert 注解。

@Insert("insert into tb_worker(name, age, sex, worker_id)"+"values(#{name}, #{age}, #{sex}, #{worker_id})")
public int insertWorker(Worker worker);

② 编写测试类

public void insertWorkerTest() {
    //1.生成SqlSession对象
    SqlSelssion session = MyBatisUtils.getSession();
    Worker worker = new Worker();
    worker.setId(4);
    worker.setName("张三");
    worker.setAge(36);
    worker.setSex("女");
    worker.setWorker_id("1004");
    WorkerMapper mapper = session.getMapper(WorkerMapper.class);
    //2.插入员工信息
    int result = mapper.insertWorker(worker);
    System.out.println(result);
    //3.手动提交修改并关闭SqlSession
    session.commit();
    session.close();
}

3. @Update 注解

① 在 WorkerMapper 接口中添加更新数据的方法,并在方法中添加 @Update 注解。

@Update("update tb_worker set name = #{name}, age = #{age}"+"where id = #{id}")
public int updateWorker(Worker worker);

② 编写测试类

public void updateWorkerTest() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    Worker worker = new Worker();
    worker.setId(4);
    worker.setName("李华");
    worker.setAge(28);
    WorkerMapper mapper = session.getMapper(WorkerMapper.class);
    //2.更新员工信息
    int result = mapper.updateWorker(worker);
    System.out.println(result);
    //3.手动提交修改并关闭SqlSession
    session.commit();
    session.close();
}

4. @Delete 注解

① 同样,在 WorkerMapper 接口中添加删除数据的方法,并在方法上添加 @Delete 注解。

@Delete("delete from tb_worker where id = #{id}")
public int deleteWorker(int id);

② 编写测试类

public void deleteWorkerTest() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    WorkerMapper mapper = session.getMapper(WorkerMapper.class);
    //2.删除员工信息
    int result = mapper.deleteWorker(4);
    if(result > 0) {
        System.out.println("成功删除"+result+"条数据");
    } else {
        System.out.println("删除数据失败");
    }
    //3.手动提交修改并关闭SqlSession
    session.commit();
    session.close();
}

增删改操作需要手动去提交!

5. @Param 注解

下面通过一个案例来演示 @Param 注解的使用,该案例要求根据员工的 id 和姓名查询员工信息,具体步骤如下:

① 添加注解,在 WorkerMapper 接口中添加多条件查询的方法。

@Select("select * from tb_worker where id = #{param01} and name = #{param02}")
public Worker selectWorkerByIdAndName(@Param("param01") int id, @Param("param02") String name); 

param01 和 param02 是我们给这两个参数分别起的别名!

② 编写测试类

public void selectWorkerByIdAndNameTest() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    WorkerMapper mapper = session.getMapper(WorkerMapper.class);
    //2.查询id为3姓名为王五的员工的信息
    Worker worker = mapper.selectWorkerByIdAndName(3,"王五");
    System.out.println(worker);
    session.close();
}

二、多表关联查询

1. 一对一查询

根据 person 的 id 查询人的信息,以及 IdCard 的信息。
Mybatis 注解式开发多表查询的前提是,将一条多表查询的 SQL,拆分成多条单表查询的 SQL!

① 创建 Person 和 IdCard 的两个实体类

//Person.java
package com.tyut.pojo;

public class Person {
    private int id;
    private String name;
    private int age;
    private String sex;
    //一对一的映射
    private IdCard card;

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex='" + sex + '\'' +
                ", card=" + card +
                '}';
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public IdCard getCard() {
        return card;
    }
    public void setName(IdCard card) {
        this.card = card;
    }
}

//IdCard.java
package com.tyut.pojo;

public class IdCard {
    private int id;
    private String code;

    @Override
    public String toString() {
        return "IdCard{" +
                "id=" + id +
                ", code='" + code + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

}

② 在 com.tyut.dao 包下创建 IdCardMapper 接口 和 PersonMapper 接口,关键在于第二个接口的编写

//IdCardMapper.java
package com.tyut.dao;
import com.tyut.pojo.IdCard;
import org.apache.ibatis.annotations.Select;
public interface IdCardMapper {
    @Select("select * from tb_idcard where id = #{id}")
    public IdCard selectIdCardById(int id);
}
//PersonMapper.java
package com.tyut.dao;
import com.tyut.pojo.Person;
import org.apache.ibatis.annotations.Select;
public interface PersonMapper {
    @Select("select * from tb_person where id = #{id}")
    @Results(@Result(column = "card_id", property = "card",
        one = @One(select = "com.tyut.dao.IdCardMapper.selectIdCardById")
    ))
    public Person selectPersonById(int id);
}

@Result 注解的三个属性及含义:
(1)property 属性用来指定关联属性,这里为 card;
(2)column 属性用来指定关联的数据库表中的字段,这里为 card_id;
(3)one 属性用来指定数据表之间属于哪种关联关系,通过 @One 注解表明数据表 tb_idcard 和 tb_person 之间是一对一关联关系。

③ 在核心配置文件中引入接口

<mapper class="com.tyut.dao.IdCardMapper"/>
<mapper class="com.tyut.dao.PersonMapper"/>

要注意接口的引入顺序,由于 MybatisConfig.xml 文件的扫描方式是从上往下扫描,所以先引入 IdCardmapper,后引入 PersonMapper!

④ 编写测试类

public void selectPersonByIdTest() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    PersonMapper mapper = session.getMapper(PersonMapper.class);
    //2.查询id为1的人员信息
    Person person = mapper.selectPersonById(1);
    System.out.println(person);
    session.close();
}

2. 一对多查询

基于用户与订单的关系演示一对多查询,这里实体类我仅展示部分代码,完整代码可参考我前面的文章 —— MyBatis 关联映射,实体类完全一致,不再重复。

① 在 com.tyut.dao 包下创建 OrdersMapper 接口 和 UsersMapper 接口

//OrdersMapper.java
public interface OrdersMapper {
    @Select("select * from tb_orders where user_id = #{id}")
    @Results(@Result(id = true, column = "id", property = "id"),
        @Result(column = "number", property = "number")
    )
    public List<Orders> selectOrdersByUserId(int user_id);
}

id = true 代表此处是主键映射,当实体的属性名与数据表的列名一致时,映射这一步骤可以省略!

//UsersMapper.java
public interface UsersMapper {
    @Select("select * from tb_user where id = #{id}")
    @Results(@Result(id = true, column = "id", property = "id"),
        @Result(column = "username", property = "username"),
        @Result(column = "address", property = "address"),
        @Result(column = "id", property = "ordersList",
            many = @Many(select = "com.tyut.dao.OrdersMapper.selectOrdersByUserId"))
    )
    public Users selectUserById(int id);
}

② 编写测试类

public void selectUserById() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    UsersMapper mapper = session.getMapper(UsersMapper.class);
    //2.查询id为1的用户订单信息
    Users users = mapper.selectUserById(1);
    System.out.println(users);
    session.close();
}

3. 多对多查询

多对多关联关系通常使用一个中间表来维护,我们依然以前面的订单表和商品表为例进行演示,根据订单的 id 查询订单信息以及订单对应的商品信息。

① 在 com.tyut.dao 包下创建 ProductMapper 接口 和 OrdersMapper 接口

//ProductMapper.java
public interface ProductMapper {
    @Select("select * from tb_product where id in (select product_id from tb_ordersitem where orders_id = #{id})")
    public List<Product> selectProductByOrdersId(int orders_id);
}
//OrdersMapper.java
public interface OrdersMapper {
    @Select("select * from tb_orders where id = #{id}")
    @Results(@Result(id = true, column = "id", property = "id"),
        @Result(column = "number", property = "number"),
        @Result(column = "id", property = "productList",
            many = @Many(select = "com.tyut.dao.ProductMapper.selectProductByOrdersId"))
    )
    public Orders selectOrdersById(int id);
}

② 编写测试类

public void selectOrderById() {
    //1.生成SqlSession对象
    SqlSession session = MyBatisUtils.getSession();
    OrdersMapper mapper = session.getMapper(OrdersMapper.class);
    //2.查询id为1的订单信息及订单对应的商品信息
    Orders orders = mapper.selectOrderById(1);
    System.out.println(orders);
    session.close();
}

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

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

相关文章

[附源码]计算机毕业设计房屋租赁系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis MavenVue等等组成&#xff0c;B/S模式…

算法竞赛入门【码蹄集进阶塔335题】(MT2201-2225)

算法竞赛入门【码蹄集进阶塔335题】(MT2201-2225&#xff09; 文章目录算法竞赛入门【码蹄集进阶塔335题】(MT2201-2225&#xff09;前言为什么突然想学算法了&#xff1f;为什么选择码蹄集作为刷题软件&#xff1f;目录1. MT2201 字符串转换2. MT2202 Summer Pockets3. MT2203…

alsa框架与音频芯片移植基础

ALSA音频框架 Alsa是Advanced Linux Sound Architecture的缩写&#xff0c;即高级Linux声音架构&#xff0c;在Linux操作系统上提供了对音频和MIDI的支持。在Linux 2.6的内核版本后&#xff0c;Alsa目前已经成为了linux的主流音频体系结构。 除了 alsa-driver&#xff0c;ALS…

CSS -- 使用纯CSS绘制三角形及常见案例汇总

文章目录1. 绘制原理2. 绘制最简单的三角形3. 绘制对话框4. 绘制两条直角边不等长的三角形1. 绘制原理 网页中常见一些三角形&#xff0c;使用 CSS 直接画出来就可以&#xff0c;不必做成图片或者字体图标 给每个边框不同的颜色可以看到&#xff0c;每个边框其实都是一个小三…

测试(缺陷管理)

目录 1.缺陷管理理论 1.1.定义 1.2缺陷的名称 1.3.产生缺陷的原因 1.4.缺陷管理流程 1.5.缺陷管理生命周期与状态 2.如何提交缺陷 2.1.提交的Bug的目的 2.2.提交Bug的注意事项 2.3.提交Bug报告应遵循的原则 2.4.Bug报告需包含哪些内容 1.缺陷管理理论 1.1.定义 软件…

rust编程-rust所有权理解(chapter 4.3 Slice切片类型)

目录 3. 切片&#xff08;Slice&#xff09;类型 3.1 String slice(字符串切片) 3.2 其它切片 3. 切片&#xff08;Slice&#xff09;类型 切片可以用来获取一个集合中连续的元素序列&#xff0c;且切片是一种引用类型&#xff0c;因此不具有所有权。 如下是一个小的编程示…

day17_面向对象的三大特征之一(多态)

概述 多态是继封装、继承之后&#xff0c;面向对象的第三大特性。 生活中&#xff0c;比如求面积的功能&#xff0c;圆、矩形、三角形实现起来是不一样的。跑的动作&#xff0c;小猫、小狗和大象&#xff0c;跑起来是不一样的。再比如飞的动作&#xff0c;昆虫、鸟类和飞机&a…

【数字IC设计】Design Compiler入门

本博客参考自文章链接 本文以全加器为例&#xff0c;演示DC综合的流程。设计文件如下&#xff1a; module full_adder( input clk, input rstn, input [31:0] a_in, input [31:0] b_in, input c_in, output reg [31:0] sum_out, output reg c_out ); wire c_out_w; wire [31:0…

[vue学习笔记]数组+事件+v-model的使用

1.关于数组的使用以及常见的函数 &#xff08;1&#xff09;在队尾操作函数&#xff1a;push&#xff08;&#xff09;&#xff1a;追加&#xff0c;pop&#xff08;&#xff09;&#xff1a;删除 arr.push(9,8,7,6); 这种批量追加的方式也是被允许的 &#xff08;2&#xf…

Gem5模拟器,关于Adding parameters to SimObjects and more events的一些问题记录(六)

目录 &#xff08;1&#xff09;为什么Gem是Python和C混合使用编程&#xff1f; &#xff08;2&#xff09;关于析构函数 创建类的时候一般都需要写上析构函数吗&#xff1f; &#xff08;3&#xff09;关于HelloObject和GoodbyeObject的先后后创建关系 &#xff08;1&…

C# 类 字段 方法

一 现实中的实物抽象为类 类(class)最基本的要素是 ① 字段(field):变量&#xff1b; ② 方法(method):函数&#xff1b; class Person {public string name;public int age;public void SayHello(){Console.WriteLine("Hello!My name is"name);}public string Ge…

(Python)第2章-12 输出三角形面积和周长 (15 分)

Python解决输入三条边输出面积与周长1.问题2.解决思路代码在孤单的日子里&#xff0c;你单枪匹马奋斗的样子酷毙了。江客&#xff1a;时荒![在这里插入图片描述](https://img-blog.csdnimg.cn/85fc4495dcfc4578a8612a432d8045cd.png#pic_center)1.问题 本题要求编写程序&#…

Arduino Uno零基础入门学习笔记——变量与函数

文章目录一、创建变量二、函数三、delay的例子总结一、创建变量 int currentTemperature;整数型变量 变量名字 分号 使用驼峰命名法对进行命名 有些程序员喜欢全部小写&#xff0c;有些程序员喜欢用下划线&#xff0c;所以如果要写一个my name的变量&#xff0c;他们常用的写…

vue3中的propemit

状态是什么&#xff1a; 页面中要显示的东西&#xff0c;放在一个变量中&#xff0c;每次更改完值&#xff0c;就会被拦截&#xff0c;同时再重新渲染页面&#xff1b; 状态的对立面就是属性&#xff1b; 可以没有状态&#xff0c;那只能用父组件传过来的属性来自己用&#…

Saga 模式

Saga 模式目录概述需求&#xff1a;设计思路实现思路分析1.2.适用场景&#xff1a;3.缺点&#xff1a;4.Saga的实现&#xff1a;参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,ma…

mysql数据恢复,mysql数据备份,详细聊聊mysql数据备份与恢复

文章目录写在前面数据备份与恢复1、全量备份模拟全量备份与恢复全量备份的缺点2、增量备份模拟增量备份与恢复增量备份注意事项总结写在前面 作为互联网开发人员来说&#xff0c;数据安全性一直排在第一位的重中之重。 mysql作为关系型数据库的一个巨头&#xff0c;其备份与恢…

从GNU/Linux看国产操作系统的安全可控性

作者&#xff1a;IT圈黎俊杰 在信创的春风下&#xff0c;做为IT基础软件三驾马车之一的操作系统&#xff0c;自然是国产化替代的重点&#xff0c;再加上一直以来被大家当成”免费RedHat Enterprise Linux“的CentOS因被redhat收购&#xff0c;并宣布于2021年12月31日起在停止维…

SpringBoot+SpringCloud微服务搭建全过程(一)

一&#xff1a;什么是SpringBoot 1. SpringBoot不是一个全新的框架,而是对Spring框架的一个封装。所以&#xff0c;以前Spring可以做的事情&#xff0c;现在用SpringBoot都可以做。 2. SpringBoot整合了很多优秀的框架&#xff0c;用来简化Spring应用搭建和开发过程&#xff…

java项目_第171期ssm房屋租赁系统_计算机毕业设计

java项目_第171期ssm房屋租赁系统_计算机毕业设计 【源码请到下载专栏下载】 今天分享的项目是《ssm房屋租赁系统》 该项目分为2个角色&#xff0c;管理员和用户。 用户可以浏览前台,查看房屋租赁情况&#xff0c;并且进行租赁。 还可以登录到后台&#xff0c;进行租赁订单管理…

【20221212】【每日一题】一和零

给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度&#xff0c;该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素&#xff0c;集合 x 是集合 y 的 子集 。 思路&#xff1a;背包有两个维度&#xff1a;m、n。不…