mybatis注解的详解和开发(增、删、改、查以及一对一、一对多/多对一、多对多的关系联查)

news2024/10/7 2:20:06

mybatis注解的基本理解和开发(增、删、改、查以及一对一、一对多/多对一、多对多的关系联查)

使用mybatis注解开发的原因?

注解提供了一种简单的方式来实现简单映射语句,而不会引入大量的开销。能够读懂别人写的代码,特别是框架相关的代码。本来可能需要很多配置文件,需要很多逻辑才能实现的内容,就可以使用一个或者多个注解的方式来代替,这样就使得编程更加的简洁,代码更加清晰。

由于开发越来越流行,mybatis也可以使用注解开发方式,这样我们可以减少编程时编写的mapper映射文件。此次是围绕着一些基本的CRUD来学习,再学习复杂的映射关系和延迟加载。

基本常用的注解有:

@Insert: 实现新增

@Update:实现更新

@Select:实现查询

@Result:实现结果集封装

@Results:可以与@Result一起使用,封装多个结果的集合(其内使用@Result处理当前对象的基本属性,再处理返回值)

@ResultMap:实现引用@Results定义的封装

@One:实现一对一结果集 封装

@Many:实现一对多结果集封装

@SelectProvider:实现动态SQL映射

@CacheNamespace:实现注解二级缓存的使用

注意:复杂的注解不好编写的情况下可以使用Mapper文件配合使用

1、基本的增、删、改、查(单表操作)

在StudentMapper接口中使用注解的方式操作数据库数据

package com.etime.mapper;

import com.etime.pojo.Student;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface StudentMapper {
    //使用@Select注解查询所有学生信息
    @Select("select * from student")
    List<Student> getAllStudent();

    //使用@Insert注解向学生表中插入数据
    @Insert("insert student(sname,cid) values(#{sname},#{cid})")
    int addStudent(Student student);
    
    //使用@Delete注解根据学生id删除学生信息
    @Delete("delete from student where sid=#{sid}")
    int delStudent(int sid);
    
    //使用@Update注解根据学生id更新学生数据库信息
    @Update("update student set sname=#{sname} where sid=#{sid}")
    int updateStudent(Student student);
}

测试:

//通过@Select注解方式查询学生的所有信息
    @Test
    public void t04(){
        SqlSession sqlSession = sqlSessionUtil.getSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> studentList = studentMapper.getAllStudent();
        studentList.forEach(System.out::println);
    }

    //通过@Insert注解向学生表中插入数据
    @Test
    public void t05(){
        SqlSession sqlSession = sqlSessionUtil.getSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        int row = studentMapper.addStudent(new Student(0,"王小二",2));
        System.out.println("数据库影响行数:"+row);
    }

    //通过@Delete注解根据学生id删除学生信息
    @Test
    public void t06(){
        SqlSession sqlSession = sqlSessionUtil.getSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        int row = studentMapper.delStudent(7);
        System.out.println("数据库受影响行数:"+row);
    }

    //通过@Update注解根据学生id更改学生信息
    @Test
    public void t07(){
        SqlSession sqlSession = sqlSessionUtil.getSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        //注意这里的学生对象不能够使用匿名对象,因为需要设置学生更新条件id
        Student student = new Student(3,"缓缓",2);
        int row = studentMapper.updateStudent(student);
        System.out.println("数据库影响行数:"+row);
    }

运行结果:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2、复杂关系的注解(一对一、一对多/多对一、多对多关系)

相关注解介绍 :

@Results注解:

@Results代替了标签< resultMap> 该注解中可以使用单个@Result注解,也可以使用@Result集合

格式:

@Results ({@Result () , @Result ()}) 或者@Result (@Result())

@Result 注解:

@Result注解代替了< id> 标签和< result>标签

@Result 中 的 属性介绍:

id 是否是主键字段

column 数据库中列的名

property 需要装配的属性名

one 需要使用 @One 注解 (@Result (one = @One) ())

many 需要使用的@Many 注解 (@Result (many = @many) ())

@One 注解(一对一):

代替了< association>标签,是多表查询的关键,在注解中用来制定子查询返回单一对象

@One 注解属性介绍:

select 指定用来多表查询 的 sqlmapper

fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。

语法格式:

@Result(column = " “,property=” ",one=@Onet(select = " "))

@Many 注解(多对一)

代替了< Collection>标签,是多表查询的关键,在注解中用来指定子查询返回对象集合。

注意:聚集元素用来处理"一对多"的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList)但是注解中可以不定义;

语法格式:

@Result(property=" “,column=” “,many=@Many(select=” "))

一对一关系注解方式查询数据

在HusbandMapper.java接口中使用注解进行查询注入数据

HusbandMapper.java

package com.etime.mapper;

import com.etime.pojo.Husband;
import com.etime.pojo.Wife;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface HusbandMapper {
    //使用一对一关系注解实现查询
    @Select("select * from husband")//查询所有丈夫的信息
    //将信息放入结果集合中
    @Results({
            @Result(property = "hid",column = "hid"),//设置字段属性对应的数据库列名
            @Result(property = "hname",column = "hname"),
            @Result(property = "wid",column = "wid"),
            //对根据丈夫表内的对应妻子wid到妻子表中查找妻子的信息
            @Result(property = "wife",javaType = Wife.class,column = "wid",
                    one=@One(select = "com.etime.mapper.WifeMapper.getWifeByWid"))
    })
    List<Husband> getAllHusband();
}

在WifeMapper.java中进行注解的使用,对妻子的基本数据进行数据查取

package com.etime.mapper;

import com.etime.pojo.Wife;
import org.apache.ibatis.annotations.Select;

public interface WifeMapper {
    //通过@Select查询注解的方方式获取到妻子的基本数据
    @Select("select * from wife where wid=#{wid}")
    Wife getWifeByWid(int wid);
}

对妻子和丈夫的一对一的关系进行测试:

//使用一对一关系注解查询丈夫和妻子的基本信息
    @Test
    public void t07(){
        SqlSession sqlSession =sqlSessionUtil.getSqlSession();
        HusbandMapper husbandMapper = sqlSession.getMapper(HusbandMapper.class);
        List<Husband> list = husbandMapper.getAllHusband();
        list.forEach(System.out::println);
        sqlSession.close();
    }

最终得到的测试结果为:

在这里插入图片描述

多对一使用注解的方式对数据进行查询

这里即将的测试的关系是多个学生属于同一班的关系

创建学生实体类:

package com.etime.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student {
    private int sid;
    private String sname;
    private int cid;
    //创建一个班级类的属性给到学生实体类,不同的学生来自不同的班,多个学生属于同一个班级
    private Classes classes;
}

创建班级实体类:

package com.etime.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;


@NoArgsConstructor
@AllArgsConstructor
@Data
public class Classes {
    private int cid;
    private String cname;
}

在StudentMapper.java接口中使用注解的方式处理查询语句一查查询到的数据 问题,并处理 查询到的班级classes返回的值

package com.etime.mapper;

import com.etime.pojo.Classes;
import com.etime.pojo.Student;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface StudentMapper {
    //使用@Select查询所有学生信息
    @Select("select * from student")
    //使用@Results注解处理查询到的学生实体类中的基本属性以及对应的班级信息
    //并通过one = @One 的方式把查询到接收到的返回班级实体类进行处理
    @Results({
            @Result(property = "sid",column = "sid"),
            @Result(property = "sname",column = "sname"),
            @Result(property = "cid",column = "cid"),
            @Result(property = "classes",javaType = Classes.class,column = "cid",
            one = @One(select = "com.etime.mapper.ClassesMapper.getClassesByCid"))
    })
    List<Student> getAllStudent();
}

在ClassesMapper.java中使用注解的方式根据班级id查询班级的相关信息

ClassesMapper.java

package com.etime.mapper;

import com.etime.pojo.Classes;
import org.apache.ibatis.annotations.Select;

public interface ClassesMapper {
    //使用@Select注解的方式通过查询返回值为班级对象给到学生实体类做数据处理的StudentMapper接口的one = @One处理
    @Select("select * from classes where cid=#{cid}")
    Classes getClassesByCid(int cid);
}

编写测试:

@Test
    public void t08(){
        SqlSession sqlSession = sqlSessionUtil.getSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> list = studentMapper.getAllStudent();
        list.forEach(System.out::println);
        sqlSession.close();
    }

由上面的准备我们将测试多对一查询的情况:

在这里插入图片描述

反过来进行一对多情况

对代码进行修改测试查看是否书写更简便些

修改学生实体类:

Student.java

package com.etime.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student {
    private int sid;
    private String sname;
    private int cid;
}

对班级实体类进行修改

Classes.java

package com.etime.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;


@NoArgsConstructor
@AllArgsConstructor
@Data
public class Classes {
    private int cid;
    private String cname;
    List<Student> stuList;
}

对学生类的数据获取接口做修改

public interface StudentMapper {
    //使用@Select查询所有学生信息
    @Select("select * from student where cid=#{cid}")
    Student getStudentByCid(int cid);
}

对班级类进行数据获取进行数据处理

package com.etime.mapper;

import com.etime.pojo.Classes;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface ClassesMapper {
    //使用@Select注解的方式通过查询返回值为学生对象给到班级实体类做数据处理的ClassesMapper接口的many = @Many多条数据处理
    //其实由这里可以看出来多对一和一对多是差不多的看是哪一个为主体
    //这里返回来处理的是集合所以javaType给到的是List.call 数据做处理的也是@Many注解(注意many=@Many别误解为多对多)
    @Select("select * from classes")
    @Results({
            @Result(property = "cid",column = "cid"),
            @Result(property = "cname",column = "cname"),
            @Result(property = "stuList",javaType = List.class,column = "cid",
                    many = @Many(select = "com.etime.mapper.StudentMapper.getStudentByCid"))
    })
     List<Classes> getAllClasses();
}

由上可知的一对多的方式进行的数据查询可以看出,其实两种方式都差不多,只是看是怎么看他们之间的关系型,以谁为主体

运行结果:

在这里插入图片描述

由上面的关系可知在开发中常见的还属是多对多的关系,接下来进行注解的测试对多对多关系的测试

多对多关系注解方式的查询数据:

众所周知的学生和课程之间是常见的多对多的关系,接下来就以学生关系来测试多对多的关系

创建课程实体类:

package com.etime.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@Data
@NoArgsConstructor
public class Course {
    private int courseid;
    private String coursename;
}

创建学生实体类对象:

Student.java

package com.etime.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.List;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class Student implements Serializable {
    private int sid;
    private String sname;
    private int cid;
    private List<StudentCourse> studentCourseList;
}

创建学生和课程的关系表的实体类:

StudentCourse.java

package com.etime.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Data
public class StudentCourse {
    private int scid;
    private int sid;
    private int courseid;
    private Course course;
}

创建课程CourseMapper.java接口查询数据:

package com.etime.mapper;

import com.etime.pojo.Course;
import org.apache.ibatis.annotations.Select;

public interface CourseMapper {
    //由课程id到课程表中进行查询课程信息
    @Select("select * from course where courseid=#{courseid}")
    Course getCourseByCourseid(int courseid);
}

创建学生StudentMapper.java接口查询数据处理:

package com.etime.mapper;

import com.etime.pojo.Classes;
import com.etime.pojo.Student;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface StudentMapper {
    //使用@Select查询所有学生信息
    //通过@Result注解中的属性many = @Many进行数据处理,将得到的课程对象返回到学生实体类对象studentCourseList中
    @Select("select * from student")
    @Results({
            @Result(property = "sid",column = "sid"),
            @Result(property = "sname",column = "sname"),
            @Result(property = "cid",column = "cid"),
            @Result(property = "studentCourseList",javaType = List.class,column = "sid",
            many = @Many(select = "com.etime.mapper.StudentCourseMapper.getStudentCourseBySid"))
    })
    List<Student> getStudentAndCourse();
}

创建学生课程接口StudentCourseMapper.java查询数据,对数据进行处理:

package com.etime.mapper;

import com.etime.pojo.Course;
import com.etime.pojo.StudentCourse;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface StudentCourseMapper {
    //@Select同样的通过注解的方式对数据进行全部查询,处理的通过id查询到的课程单个实体类
    @Select("select * from studentcourse where sid=#{sid}")
    @Results({
           @Result(property = "scid",column = "scid"),
            @Result(property = "sid",column = "sid"),
            @Result(property = "courseid",column = "courseid"),
            @Result(property = "course",javaType = Course.class,column = "courseid",
            one = @One(select = "com.etime.mapper.CourseMapper.getCourseByCourseid"))
    })
    //根据学生id查找所有课程对应的id
    List<StudentCourse> getStudentCourseBySid(int sid);
}

通过上述的以系列操作,咱们是能够通过注解的方式查询到多对多的关系数据的:

运行结果如图:

在这里插入图片描述

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

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

相关文章

Java——反转链表

题目链接 牛客在线oj题——反转链表 题目描述 给定一个单链表的头结点pHead(该头节点是有值的&#xff0c;比如在下图&#xff0c;它的val是1)&#xff0c;长度为n&#xff0c;反转该链表后&#xff0c;返回新链表的表头。 数据范围&#xff1a; 0≤n≤1000 要求&#xff1…

OpenAI最新官方ChatGPT聊天插件接口《插件示例demo》全网最详细中英文实用指南和教程,助你零基础快速轻松掌握全新技术(四)(附源码)

Example plugins 插件示例demo 前言Introduction 导言Learn how to build a simple todo list plugin with no auth 了解如何构建一个简单的待办事项列表插件&#xff0c;无需授权Learn how to build a simple todo list plugin with service level auth 了解如何构建一个简单的…

【Unity VR开发】结合VRTK4.0:瞬移点

语录&#xff1a; 如果把童年再放映一遍&#xff0c;我们一定会先大笑&#xff0c;然后放声痛哭&#xff0c;最后挂着泪&#xff0c;微笑着睡去。 前言&#xff1a; 移动的限制除了设置移动区域&#xff0c;也可以使用瞬移点&#xff1a;Locomotors.TeleportTargets.Point。 正…

HQChart报价列表高级应用教程7-创建走势图列

HQChart报价列表高级应用教程7-创建走势图列 走势图列效果图步骤1. 走势图列数据截图数据结构HQChart代码地址走势图列 在行情报价里面,使用单独的一列显示每一个股票的价格走势的缩略图。 效果图 步骤 1. 走势图列 REPORT_COLUMN_ID.CLOSE_LINE_ID 走势图列在创建报价列…

ChatGPT: 人工智能对话模型的前沿技术与应用探析

ChatGPT: 人工智能对话模型的前沿技术与应用探析 引言 ChatGPT作为一种人工智能对话模型&#xff0c;在近年来引起了广泛的关注和研究。随着人工智能技术的不断发展&#xff0c;ChatGPT作为一种前沿技术在人机对话领域具有重要地位和广泛的应用价值。本文将介绍ChatGPT的背景和…

【CocosCreator入门】CocosCreator组件 | ProgressBar(进度条)组件

Cocos Creator 是一款流行的游戏开发引擎&#xff0c;具有丰富的组件和工具&#xff0c;其中的ProgressBar组件是一种用于实现进度条效果的重要组件。它可以让我们在游戏中展示各种进度条效果&#xff0c;例如加载进度条、血条等。 目录 一、组件介绍 二、组件属性 三、脚本…

如何删除docker镜像与容器

目录 删除示例&#xff1a; 1.查看docker中要删除的镜像 2.删除镜像&#xff0c;使用命令“docker rmi image id” 3.查看docker中正在运行的容器 4.停止容器 5.删除容器 6.查看容器 7.删除镜像 8.最后查看所有镜像 删除示例&#xff1a; 1.查看docker中要删除的镜像 …

(二)Jhipster 快速搭建微服务

&#xff08;一&#xff09;Jhipster 的简介与安装https://blog.csdn.net/weixin_46085718/article/details/130282249 目录 &#xff08;一&#xff09;Jhipster 的简介与安装 1、搭建注册中心 jhipster registry jhipster registry是一个基于spring cloud的配置中心。所有…

跟寻智能色选机,一起探索神秘的色彩世界

色选机&#xff0c;一种基于物料颜色、形状或质地差异&#xff0c;再通过光电检测、图像处理等手段来实现物料分选和净化的工业化应用终端&#xff0c;可满足特种物料等多种产品的色选要求&#xff0c;如大米、茶叶、豆类、药材、种子、虾皮、坚果、各类干货、塑料、珠宝、矿石…

【Python入门第五十二天】Python丨NumPy 数组过滤

数组过滤 从现有数组中取出一些元素并从中创建新数组称为过滤&#xff08;filtering&#xff09;。 在 NumPy 中&#xff0c;我们使用布尔索引列表来过滤数组。 布尔索引列表是与数组中的索引相对应的布尔值列表。 如果索引处的值为 True&#xff0c;则该元素包含在过滤后的…

随想录Day57--动态规划: 647. 回文子串 , 516.最长回文子序列

回文串和最长回文子串&#xff0c;关键在于dp数组的定义&#xff0c;以及中间的关系式和递推公式怎么表达。代码其实很简单&#xff0c;但最重要的是思路&#xff01;&#xff01;&#xff01; 回文子串dp是布尔型&#xff0c;遍历所有情况找到所有的true&#xff0c;最长回文…

蓝奥声核心技术分享——基于物联网的能源监测数据采集技术

1.技术背景 基于物联网的能源监测数据采集技术主要解决物联网能源监测节点面向目标对象以协同方式进行能源监测数据采集的问题&#xff0c;属于蓝奥声核心技术--边缘协同感知(EICS&#xff09;技术的关键支撑性技术之一。该项技术涉及无线物联网边缘智能与测控的技术领域&…

【CocosCreator入门】CocosCreator组件 | EditBox(文本输入)组件

Cocos Creator 是一款流行的游戏开发引擎&#xff0c;具有丰富的组件和工具&#xff0c;其中的EditBox组件是一种用于实现用户输入交互的重要组件。它可以让用户在游戏中输入文字、数字等内容&#xff0c;并且可以对输入内容进行格式校验和处理。 目录 一、组件介绍 二、组件…

【Unity渲染】URP透明物体自身渲染穿插异常问题

背景&#xff1a; 对于URP中的某个物体&#xff0c;我们如果希望他正反面都可以被渲染。 通常会有两种解决方案&#xff1a; 1.将网格设置为双面网格。&#xff08;此种情况Mesh.RecalculateNormals计算结果可能会异常&#xff0c;解决可参考网格法线生成异常解决&#xff0…

震惊!为了4680锂电池溯源,竟然做出这种事情

电池溯源&#xff0c;一直都是国家尤为重视的话题。 中国电子技术标准化研究院更是一再强调了&#xff1a;锂电编码标准编制和溯源平台初步建设方案。参会代表围绕锂电编码溯源体系建设有关问题开展了研讨&#xff0c;表示依托行业通用编码标准&#xff0c;建立完善的锂电全生…

【Linux学习】多线程——页表详解 | 线程概念 | 线程理解

&#x1f431;作者&#xff1a;一只大喵咪1201 &#x1f431;专栏&#xff1a;《Linux学习》 &#x1f525;格言&#xff1a;你只管努力&#xff0c;剩下的交给时间&#xff01; 线程概念 &#x1f95e; 页表详解&#x1f35e;页目录和页表项 &#x1f95e;线程&#x1f35e;轻…

2023/4/18往日题目总结

搜索路径状态记录 1076. 迷宫问题 - AcWing题库 //以最简单的迷宫问题为例&#xff0c;如何记录走迷宫的路径&#xff0c;其实只需要记录一下状态即可 //也就是记录一下这个点是从哪个点来的&#xff0c;最后从终点开始输出即可&#xff08;此时输出的是逆序&#xff09; #in…

PHP+python+nodejs+springboot+vue 大学生提问论坛系统

在各学校的教学过程中&#xff0c;大学生提问论坛是一项非常重要的事情。随着计算机多媒体技术的发展和网络的普及。 本文首先介绍了大学生提问论坛的发展背景与发展现状&#xff0c;然后遵循软件常规开发流程&#xff0c;首先针对系统选取适用的语言和开发平台&#xff0c;根…

微信小程序的生命周期函数有哪些,以及执行过程?

目录 1、应用的生命周期 2、页面的生命周期 3、组件的生命周期 4、执行顺序 小程序中&#xff0c;生命周期主要分成了三部分&#xff1a; ① 应用的生命周期 ② 页面的生命周期 ③ 组件的生命周期 1、应用的生命周期 在 app.js 里面调用&#xff0c;通过…

【hello Linux】理解文件系统

目录 创建文件的过程&#xff1a; 删除文件的过程&#xff1a; 创建目录的过程&#xff1a; 查看inode编号&#xff1a; 硬链接 软链接 Linux&#x1f337; 我们知道文件所有数据 文件内容 文件属性信息&#xff1b; 未打开的文件是被存放到磁盘/固态硬盘中的&#xff1b; …