【MyBatis持久层框架】使用Java注解完成CRUD详细解读

news2024/11/17 6:21:25

文章目录

  • 1. 前言
  • 2. 实战案例
    • 2.1 准备工作
    • 2.2 编写接口方法
    • 2.3 映射SQL语句
    • 2.4 编写测试方法
  • 3. SQL语句构建器
  • 4. 总结

1. 前言

之前我们通过 XML 配置文件的方式映射 sql 语句,将 sql 语句与 Java 代码分离,大大的提高了开发的效率并且解决了 JDBC 原生方式中的一些问题。其实,使用 Java 注解的方式来映射简单的 sql 语句也是十分高效且低成本的。

  • 【MyBatis持久层框架】配置文件实现增删改查实战案例
  • 【MyBatis持久层框架】配置文件实现增删改查实战案例(下)

image-20230201133039623

示例:之前在使用 XML 配置来映射 sql 语句实现查询数据表中所有数据的操作。

public interface StudentMapper {
    /*
    查询student表中所有的数据信息
     */
    List<Student> selectALL();
}

在XML中:

<mapper namespace="org.chengzi.mapper.StudentMapper">

    <resultMap id="studentResultMap" type="student">
        <result column="score_english" property="scoreEnglish"/>
        <result column="score_math" property="scoreMath"/>
    </resultMap>

    <select id="selectALL" resultMap="studentResultMap">
        select *
        from student;
    </select>
</mapper>

使用注解来映射简单 sql 语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让本就复杂的 sql 语句更加混乱不堪。因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句(MyBatis官网)。

示例:使用注解映射简单 sql 语句。

public interface StudentMapper {

    /*
    查询student表中所有的数据信息
     */
    @Select("select * from student")
    List<Student> selectAll();
}

虽然 Java 注解提供了一种简单且低成本的方式来实现简单的映射语句,但是其灵活性十分有限,选择何种方式来配置映射,以及是否应该要统一映射语句定义的形式,完全取决于你和你的团队。

永远不要拘泥于一种方式,你可以很轻松地在基于注解和 XML 的语句映射方式间自由移植和切换。

2. 实战案例

需求: 使用注解的方式映射 sql 语句并且实现查找数据表中的全部数据。

MyBatis 针对 CRUD 操作提供了对应的注解,并且遵循见名知意的规则:

  • 查询: @Select
  • 添加: @Insert
  • 修改: @Update
  • 删除: @Delete

2.1 准备工作

首先,我们要创建好数据库表和添加数据,涉及到的 sql 语句如下:

drop table if exists student;

create table student(
	id int primary key auto_increment,
	name varchar(10),
	gender char(1),
	score_english int,
	score_math int
);

insert into student(name,gender,score_english,score_math) values
('张三','男',61,65),
('李四','女',45,38),
('王五','男',85,53),
('小王','男',56,58),
('小樊','女',85,92);

数据表如下图:

image-20230129193400530

接下来在 idea 中 org.chengzi.pojo 包下创建实体类 Student :

public class Student{
    //id 主键
    private int id;
    //学生姓名
    private String name;
    //学生性别
    private String gender;
    //学生英语成绩
    private int scoreEnglish;
    //学生数学成绩
    private int scoreMath;
    
    //这里省略了Getter and Setter方法和重写的Object中的toString方法
}

接下来编写测试用例,这里在 Test 中写单元测试的代码。在测试代码 Java 文件目录下创建 MyBatisTest 类。如图:

image-20230129194459753

2.2 编写接口方法

在 StudentMapper 接口中编写查询所有数据的方法,如下:

List<Student> selectAll();

2.3 映射SQL语句

在 StudentMapper 接口中刚才定义的方法上面一行使用 Java 注解映射 sql 语句,如下:

@Select("select * from student")
List<Student> selectAll();

2.4 编写测试方法

在 MyBatisTest 中编写单元测试的方法,如下:

    @Test
    public void testSelectAll() throws IOException {
        //1. 获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //3. 获取Mapper接口的代理对象
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);

        //4. 执行方法
        List<Student> students = studentMapper.selectAll();
        System.out.println(students);

        //5. 释放资源
        sqlSession.close();
    }

运行程序,数据表中的所有数据被打印到控制台,如下图:

image-20230201141944885

前提是在 Student 类中已经重写了 Object 类中的 toString() 方法。

3. SQL语句构建器

回到最初的问题,此时我们又将 sql 写到了 Java 代码中,并且如果修改了 sql 语句,那么程序将要重新编译,十分的不方便,并且在 Java 代码中嵌入大量的 sql 语句是十分头疼的,例如之前使用的动态 sql 语句,此时将 sq l嵌入 Java 代码后代码可读性会大大的降低。而在 XML中定义 sql 似乎更加的方便与强大。

对于需要在 Java 代码中构建 sql 语句的情况,MyBatis 提供了 SQL 类来简化操作,我们只需要创建一个实例化对象,调用它的方法生成 sql 语句。

下面是SQL类的一些示例:

  // Anonymous inner class
    public String deletePersonSql() {
      return new SQL() {{
        DELETE_FROM("PERSON");
        WHERE("ID = ${id}");
      }}.toString();
    }

    // Builder / Fluent style
    public String insertPersonSql() {
      String sql = new SQL()
        .INSERT_INTO("PERSON")
        .VALUES("ID, FIRST_NAME", "${id}, ${firstName}")
        .VALUES("LAST_NAME", "${lastName}")
        .toString();
      return sql;
    }

    // With conditionals (note the final parameters, required for the anonymous inner class to access them)
    public String selectPersonLike(final String id, final String firstName, final String lastName) {
      return new SQL() {{
        SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME");
        FROM("PERSON P");
        if (id != null) {
          WHERE("P.ID like ${id}");
        }
        if (firstName != null) {
          WHERE("P.FIRST_NAME like ${firstName}");
        }
        if (lastName != null) {
          WHERE("P.LAST_NAME like ${lastName}");
        }
        ORDER_BY("P.LAST_NAME");
      }}.toString();
    }

    public String deletePersonSql() {
      return new SQL() {{
        DELETE_FROM("PERSON");
        WHERE("ID = ${id}");
      }}.toString();
    }

    public String insertPersonSql() {
      return new SQL() {{
        INSERT_INTO("PERSON");
        VALUES("ID, FIRST_NAME", "${id}, ${firstName}");
        VALUES("LAST_NAME", "${lastName}");
      }}.toString();
    }

    public String updatePersonSql() {
      return new SQL() {{
        UPDATE("PERSON");
        SET("FIRST_NAME = ${firstName}");
        WHERE("ID = ${id}");
      }}.toString();
    }

这里不再深入详解,初学者移步官网,因为这篇文章是 JavaWeb 基础教程系列的一部分,只是对 MyBatis 做一个基础的学习,后面在 SSM 框架的系列文章中,会详细讲解 MyBatis 框架的细节。

4. 总结

使用注解来映射简单 sql 语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java 注解不仅力不从心,还会让本就复杂的 SQL 语句更加混乱不堪。因此,如果你需要做一些很复杂的操作,最好用 XML 来映射语句。

选择何种方式来配置映射,以及是否应该要统一映射语句定义的形式,完全取决于你和你的团队。换句话说,永远不要拘泥于一种方式,你可以很轻松地在基于注解和 XML 的语句映射方式间自由移植和切换。

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

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

相关文章

MySQL - 为什么索引存储要用B+树,用链表不行吗?

MySQL - 为什么索引存储要用B树&#xff0c;用链表不行吗&#xff1f; 时间&#xff1a;2023年2月1日22:19:09 一、先来比较一下链表和树&#xff1f; 二、为什么数据库索引要用B树&#xff1f; 为什么要用索引&#xff0c;数据直接Load到内存里查不可以吗&#xff1f;&#…

Hive最全总结,学习与面试,收藏这一篇就够了!

Hive基础概念和用途 Hive是Hadoop下的顶级 Apache项目&#xff0c;早期的Hive开发工作始于2007年的 Facebook。 ⬛ Apache Hive是一款建立在Hadoop之上的开源数据仓库系统&#xff0c;可以将存储在Hadoop文件中的结构化、半结构化 数据文件映射为一张数据库表&#xff0c;基…

操作系统(day05)-- 进程调度、调度算法

文章目录进程调度&#xff08;低级调度&#xff09;进程调度的时机进程调度的方式调度算法的评价指标FCFS&#xff0c;SJF&#xff0c;HRRN调度算法先来先服务&#xff08;FCFS&#xff09;短作业优先&#xff08;SJF&#xff09;高响应比优先&#xff08;HRRN&#xff09;进程…

从0开始用hooks搭建一个事件待办的demo(一)

需求一&#xff1a;实现header&#xff0c;点击加号展示input&#xff0c;再次点击隐藏input 分析&#xff1a; 首先&#xff0c;需要两个子组件header和addInput&#xff1b; header组件负责展示图一的内容&#xff0c;给加号添加一个点击事件&#xff0c;来触发展示input的函…

zookeeper源码分享五 --- 数据结构

zookeeper 内存数据结构 zookeeper在内存当中是有一份完整的数据&#xff0c;底层数据结构是基于hashMap去实现的。 在map的key是path&#xff0c;value是具体节点信息(DataNode)。 在map的顶层中有所有节点的path信息&#xff0c;每个节点都要子节点的path(不是具体的节点信息…

图的存储与遍历

目录 一.邻接矩阵 1.1概念介绍 1.2代码示例 1.3代码测试 二.邻接表 2.1概念介绍 2.2代码示例&#xff1a; 2.3代码测试 三.遍历 3.1广度优先遍历&#xff08;BFS&#xff09; 3.1.1邻接表&#xff08;BFS&#xff09; 3.1.2邻接矩阵&#xff08;BFS&#xff09; 3.2深…

不是计算机专业的,想学Java,能学得会吗?

看到这个问题&#xff0c;想到昨天一位机电一体化专业的同学来咨询了Java和云计算两个专业的培训情况。一来就问&#xff1a;“我这种情况能学得会吗&#xff0c;之前也没接触过计算机方面的专业&#xff0c;就是玩玩游戏&#xff0c;正常上网之类的操作&#xff1b;但我是真的…

【数据结构与算法】图的基本概念 | 邻接矩阵和邻接表 | 广度优先遍历和深度优先遍历

&#x1f320;作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《数据结构与算法要啸着学》 &#x1f387;座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;…

ElasticSearc写入查询性能优化总结

文章目录前言1、bulk批量写入2、多线程写入3、修改索引刷新时间4、修改merge参数以及线程数6、index buffer7、磁盘间的任务均衡8、Mapping优化8.1、自动生成docID(避免ES对自定义ID验证的操作)8.2、调整字段Mapping8.3、调整_source字段8.4、禁用_all8.5、禁用Norms8.6、index…

Elasticsearch学习-父子文档

elasticsearch父子文档处理 join 一、背景二、需求三、前置知识四、实现步骤 1、创建 mapping2、添加父文档数据3、添加子文档4、查询文档 1、根据父文档id查询它下方的子文档2、has_child返回满足条件的父文档3、has_parent返回满足父文档的子文档 五、Nested Object 和 joi…

docker部署vue

1: 创建 Dockerfile 文件 配置一下内容&#xff1a; # 设置基础镜像&#xff0c;这里使用最新的nginx镜像&#xff0c;前面已经拉取过了 FROM nginx # 将dist文件中的内容复制到 /usr/share/nginx/html/ 这个目录下面 COPY dist/ /usr/share/nginx/html/ 2: 安装nginx …

物联网平台的产品架构

一、物联网介绍1. 概述物联网&#xff08; IoT &#xff0c;Internet of things &#xff09;即“万物相连的互联网”&#xff0c;是互联网基础上的延伸和扩展的网络&#xff0c;将各种信息传感设备与互联网结合起来而形成的一个巨大网络&#xff0c;实现在任何时间、任何地点&…

LeetCode 热题 HOT 100 -- Java 题解

LeetCode 热题 HOT 100 --Java 题解1. 两数之和2. 两数相加3. 无重复字符的最长子串4. 寻找两个正序数组的中位数1. 两数之和 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下…

【信管10.3】风险定量分析及应对监控

风险定量分析及应对监控通过前三个过程&#xff0c;我们已经有了风险登记册&#xff0c;也就是一个所有识别出来的风险情况。然后可以通过定性风险分析来进行分类和排序。接下来我们要继续通过定量&#xff0c;也就是数据的手段来继续完善风险登记册。只有有了详尽的风险登记册…

我对KMP算法的简单理解

我对KMP算法的简单理解 前言&#xff1a;字符串匹配问题 问题概述&#xff1a; “字符串A是否为字符串B的子串&#xff1f;如果是&#xff0c;出现在B的什么位置&#xff1f;”这个问题就是字符串匹配问题。字符串A称为模式串(zs)&#xff0c;字符串B称为主串(ss)。 其中&a…

C++ 深入理解模板实现多态思想

文章目录前言一、模板与多态基础1.模板2.多态二、模板实现多态三、实际应用前言 对C/C学习感兴趣的可以看看这篇文章噢&#xff1a;C/C教程 最近有时间&#xff0c;便用WTL写了一个兼具群聊、单聊以及传输文件的聊天软件&#xff0c;过几天应该就能更新到 C/C教程系列 中了 …

EasyGBS+EasyNVS技术方案,如何实现对多现场国标视频平台的统一管理?

一、平台能力 1&#xff09;EasyGBS EasyGBS国标视频云服务平台支持无缝、完整接入内网或者公网的国标设备&#xff0c;在输出上&#xff0c;实现全平台、全终端输出。EasyGBS可将GB/T28181设备/平台推送的PS流转成ES流&#xff0c;并提供RTSP、RTMP、FLV、HLS、WebRTC等多种…

使用shell进行简单操作

目录 1、shell实现乘法表的打印 2、shell判定成绩等级 3、循环创建用户 1、shell实现乘法表的打印 要求&#xff1a;嵌套循环实现9*9乘法表&#xff08;两种方式&#xff09; 创建脚本文件&#xff1a;vim mcl.sh #!/bin/bash ######################### #File name:mcl.s…

idea插件及插件使用方法

CamelCase (下划线转驼峰) 使用快捷键&#xff1a;altshiftu。 按住altshift再不停的按U&#xff0c;会把选中内容的单词的下划线转驼峰转大写等&#xff0c;不停的转换。 Maven Helper Maven助手 安装之后再次打开pom文件&#xff0c;文件左下角会多出一个视图。 切换到"…

软件测试基础(三) 之 软件的生命周期

软件的生命周期一、软件的生命周期简述软件的生命周期中最早可能是客户&#xff0c;可能是产品的一个想法阶段&#xff0c;然后再到后来的一个需求阶段&#xff0c;再到开发人员去进行编码&#xff0c;去进行自己的自测&#xff0c;再提到软件测试人员进行综合测试&#xff0c;…