如何使用MyBatis简化JDBC开发?MyBatis持久层框架快速入门

news2024/10/5 14:29:47

文章目录

  • 1. 前言
  • 2. JDBC 存在的缺点
  • 3. MyBatis 优化
  • 4. MyBatis 快速入门
  • 5. 总结
  • Java编程基础教程系列

1. 前言

JavaEE 企业级 Java 项目中的经典三层架构为表现层,业务层和持久层,使用Java 代码操作数据库属于持久层内容,而 MyBatis 对 JDBC 代码进行了封装,作为一款优秀的持久层框架,专门用于简化JDBC开发。

image-20230126224012568

MyBatis 支持自定义 SQL,存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型,接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

MyBatis 本是 Apache 的一个开源项目 iBatis, 2010 年这个项目由 Apache software foundation 迁移到了google code,并且改名为 MyBatis 。2013 年 11 月迁移到 Github。

小tips:在学习一门全新的技术前,尽量做到从头到尾通读官网信息,MyBatis 的中文版官网相比于其他的网站还是非常友好的,建议首先阅读官网信息。

什么是框架呢?

框架的概念其实不难理解,这里的框架是指一个半成品的软件,是一套可重用,通用的,软件基础代码模型,在框架基础之上构建项目使编码更加高效,规范,通用并且扩展性强。

2. JDBC 存在的缺点

之前使用 JDBC 代码操作数据库时,我们一般分为注册驱动,获取连接,定义sql,设置参数值,获取 sql 执行对象,执行 sql,处理返回数据,释放资源等几个步骤。下面使用一个简单的例子分析 JDBC 究竟存在哪些缺点。

需求:使用 Java 代码操作数据库,查询学生表中所有男生信息,并且将其封装为对象,最终存放在集合中。

public class JDBCDemo {

    public static void main(String[] args) throws Exception {
        //1. 注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接
        String url = "jdbc:mysql://localhost:3306/blog?useSSL=false";
        String username = "root";
        String ppassword = "abc123";//密码
        Connection conn = DriverManager.getConnection(url, username, password);
        //接收输入的查询条件
        String gender = "男";
        //3. 定义sql
        String sql = "select * from student where gender=?";
        //4. 获取sql执行对象
        Statement stmt = conn.createStatement();
        //设置参数的值
        pstmt.setString(1,gender);
        //5. 执行sql
        ResultSet rs = stmt.executeQuery(sql);
        //6. 处理结果
        //遍历结果集,获取数据,封装为对象,装入集合
        Student s = null;
        List<Student> students = new ArrayList<>();
        while (rs.next()) {
            s = new Student();
            int id = rs.getInt(1);
            String name = rs.getString(2);
            String gender = rs.getString(3);

            s.setId(id);
            s.setName(name);
            s.setGender(gender);

            students.add(s);
        }
        System.out.println(students);
        //7. 释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
}

上面是一段简单标准的使用 JDBC 操作数据库的代码,分析代码我们不难看出,在注册驱动,获取连接和定义 sql 部分,代码中出现了大量的字符串信息,这些字符串信息非常不利于后期的维护,例如后期修改要连接的数据库等。我们把这个问题称为 JDBC 的硬编码问题。示例,存在硬编码问题的代码:

//1. 注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2. 获取连接
String url = "jdbc:mysql://localhost:3306/blog?useSSL=false";
String username = "root";
String ppassword = "abc123";//密码
Connection conn = DriverManager.getConnection(url, username, password);
//接收输入的查询条件
String gender = "男";
//3. 定义sql
String sql = "select * from student where gender=?";

在手动设置参数,封住结果集对象部分,代码中出现了大量的相似代码,例如将来的参数较多时,手动设置参数也是一件麻烦的事情等,这个问题被称为 JDBC 的操作繁琐问题。示例,存在操作繁琐问题的代码:

//设置参数的值
pstmt.setString(1,gender);
//5. 执行sql
ResultSet rs = stmt.executeQuery(sql);
//6. 处理结果
//遍历结果集,获取数据,封装为对象,装入集合
Student s = null;
List<Student> students = new ArrayList<>();
while (rs.next()) {
    s = new Student();
    int id = rs.getInt(1);
    String name = rs.getString(2);
    String gender = rs.getS  
    s.setId(id);
    s.setName(name);
    s.setGender  
    students.add(s);
}

JDBC的缺点,如下图:

image-20230126233131746

3. MyBatis 优化

JDBC 作为基础性的代码,固然会出现很多操作繁琐等的问题,那么这个问题怎么解决呢?前面说使用 MyBatis 简化 JDBC 开发,那么具体是怎么避免这些问题的呢?

首先,要解决操作繁琐的问题,只需要让JDBC中手动设置参数和手动封装结果集对象的操作由程序自动封装完成。例如下面一行代码就解决了 JDBC 封装结果集对象操作繁琐的问题:

List<Student> students = sqlSession.selectList("test.selectAll"); //参数是一个字符串,该字符串必须是映射配置文件的namespace.id

MyBatis 将注册驱动,获取连接,定义sql 的语句从 Java 代码中抽离,并单独写到配置文件中,解决了硬编码的问题。例如:在 mybatis-cinfig.xml 配置文件中定义数据库连接信息。

4. MyBatis 快速入门

每一个初学者,在学习一门全新的技术时,都要在实战练习中掌握其使用方法。今天,我们使用一个小小的案例来入门 MyBatis,学会 MyBatis 的基本使用。

需求:查询数据库中 student 表中所有的数据。

我们使用以下 5 个步骤来解决这个问题:

  1. 创建 student 表,添加数据

  2. 创建新项目,创建Maven模块,导入坐标

  3. 编写MyBatis核心配置文件

  4. 编写sql映射文件

  5. 编写代码

    1. 定义 POJO实体类
    2. 加载核心配置文件,获取 SqlSessionFactory 对象
    3. 获取 SqlSession 对象,执行 sql 语句
    4. 释放资源

接下来,我们按照上面的步骤讲解需求中的问题,学习 MyBatis 的基本使用。下面为详细过程和代码演示,整个过程的分析参考文末的过程剖析

第一步:创建 student 表,添加数据

drop table if exists student;

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

insert into student(name,gender) values
('张三','男'),
('李四','女'),
('王五','男');

第二步

创建空项目,创建 Maven 模块,项目结构如下图:

image-20230127205258911

在创建好的模块中的 pom.xml 配置文件中添加依赖坐标,点击刷新使坐标信息生效:

<dependencies>
    <!--mybatis 依赖-->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.5</version>
    </dependency>

    <!--mysql 驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>

    <!--junit 单元测试-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>

    <!-- 添加slf4j日志api -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.20</version>
    </dependency>
    <!-- 添加logback-classic依赖 -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
    <!-- 添加logback-core依赖 -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.2.3</version>
    </dependency>
</dependencies>

在 resources 目录下创建 logback 的配置文件 logback.xml,用于查看日志信息:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--
        CONSOLE :表示当前的日志信息是可以输出到控制台的。
    -->
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%level] %blue(%d{HH:mm:ss.SSS}) %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern>
        </encoder>
    </appender>

    <logger name="org.chengzi" level="DEBUG" additivity="false">
        <appender-ref ref="Console"/>
    </logger>


    <!--
      level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF, 默认debug
      <root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
      -->
    <root level="DEBUG">
        <appender-ref ref="Console"/>
    </root>
</configuration>

第三步:编写 MyBatis 核心配置文件

编写 MyBatis 核心配置文件,可以用于替换连接信息,解决了 JDBC 硬编码的问题。在模块下的 resources 目录下创建 MyBatis 的配置文件 mybatis-config.xml,内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <typeAliases>
        <package name="org.chengzi.pojo"/>
    </typeAliases>
    
    <!--
    environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment
    -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/blog?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="abc123"/>
            </dataSource>
        </environment>

        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/blog?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="abc123"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
       <!--加载sql映射文件-->
       <mapper resource="StudentMapper.xml"/>
    </mappers>
</configuration>

这里使用了<typeAliases>标签以后,在 sql 映射配置文件中的 resultType 的值可以直接设置为 Student ,而不是:

在这里插入图片描述

第四步:编写 sql 映射文件

编写 sql 映射配置文件,用于统一管理 sql 语句,同样也是为了解决 JDBC 硬编码的问题。在模块的 resources 目录下创建映射配置文件 StudentMapper.xml ,内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="test">
    <select id="selectAll" resultType="org.chengzi.pojo.User">
        select * from student;
    </select>
</mapper>

第五步:编写代码

在编写代码时,大概可以分为四步。首先是定义 POJO 类,在指定的包下创建 Student 类,如下:

package org.chengzi.pojo;

public class Student {
    private int id;
    private String name;
    private String gender;

    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 String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

接下来在 org.chengzi 包下创建 MyBatisDemo 测试类,用于加载核心配置文件,获取SqlSessionFactory 对象,获取 SQLSession 对象并执行 sql 语句,最后释放资源。

public class MyBatisDemo {

    public static void main(String[] args) throws IOException {
        //1. 加载mybatis的核心配置文件,获取 SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2. 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3. 执行sql
        List<Student> students = sqlSession.selectList("test.selectAll"); //参数是一个字符串,该字符串必须是映射配置文件的namespace.id
        System.out.println(students);
        //4. 释放资源
        sqlSession.close();
    }
}

过程剖析

在使用 MyBatis 持久层框架开发时,我们首先创建 Maven 模块,使用 Maven 构建和管理这个 Java 项目,所以我们要导入项目依赖的坐标信息,例如 MySQL 数据库的驱动坐标,用于单元测试的 Junit 和用于查看日志信息的依赖坐标。

接下来是编写 MyBatis 核心配置文件,一般命名为 mybatis-config.xml,其中<environments>标签用于配置数据库连接环境信息,可以配置多个<environment>标签,通过 default 属性切换不同的环境。我们还要定义<mapper> 标签用于加载 sql 映射文件。

而 sql 映射文件在哪里呢?接下来一步就是编写 sql 映射文件,在模块的 resources 文件目录下创建映射文件的核心配置文件,一般命名有其语法规则,使用 xxxMapper.xml 命名,而 xxx 表示要操作的数据库表。其中使用 namespace 作为命名空间,而 id 作为标签中 sql 语句的唯一标识,使用命名空间的方式类似于 Java 中包的概念,允许在不同的命名空间中存在相同名称的 id ,方便在不同的 sql 映射文件中使用相同的 id,resultType 参数表示对应语句返回结果的类型,例如案例中将数据包装为 Student 类型的对象,其 resultType 参数的值就为 Student。

接下来就是定义 POJO 实体类,用于封装查询结果数据,例如案例中查询学生表,将每条记录封装为一个对象,这里就在 POJO 包中定义 Student 类。

最后就是核心的一部分,编写相关测试类来操作数据库,在源代码 Java 文件目录对应的包中创建测试类来操作数据库并封装结果集对象。内容大致为加载核心配置文件 mybatis-config.xml ,获取 SqlSessionFactory 类对象,使用该对象的openSession() 方法获取 SqlSession 对象,用于执行 sql,然后封装结果集对象 ,此时传入的参数是一个字符串,该字符串是映射配置文件的 namespace.id ,最后释放资源。

5. 总结

初学者入门时,整个构建过程可以多参考官网给出的示例教程和代码,直接 C V 到 IDE 练习即可。

本文是 MyBatis 持久层框架的入门篇,MyBatis 作为大多数Java 开发者第一个学习的大型框架,其思想十分重要,慢慢体会其中每个步骤的意义,多练习就能熟练掌握。


Java编程基础教程系列

JDBC快速入门,如何使用JDBC操作数据库?

如何使用JDBC操作数据库?JDBC API的使用详细解读

什么是数据库连接池?Druid(德鲁伊)连接池的使用详细解读

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

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

相关文章

Multus k8s网络浅谈

Multus是什么 k8s不提供网络解决方案&#xff0c;提供CNI ( Container Networking Interface )规范&#xff0c;被CNI插件遵守&#xff08;Flannel, Calico&#xff0c;Multus等&#xff0c;这些是网络方案&#xff09; Multus 提供了将多个接口添加到pod的功能 Flannel 为每…

实现自己的数据库三

一 前言上篇实现了数据库的持久化&#xff0c;就是一个质的飞跃&#xff0c;虽然代码不复杂&#xff0c;但是对没有这方面经验者来说&#xff0c;还是意思的&#xff0c;下一步就是要完成另外一个飞跃&#xff0c;将存储的数据结构采用B树的形式来保存。在改造之前&#xff0c;…

为什么要设计非公平锁?

背景 公平&#xff1a;排队 非公平&#xff1a;在合适时机插队 非公平还是 ReentrantLock 的默认策略&#xff0c;排队时间不浪费了&#xff1f; 场景 来看这种场景 假如A持有一把锁&#xff0c;B请求这把锁&#xff0c;这时候B被挂起进入阻塞&#xff0c;A释放锁的时候&a…

点与线段的关系

点与线段的关系 对于向量a(x1,y1)和b(x2,y2) 点乘的数学意义&#xff1a;a * b x1x2 y1y2 点乘的几何意义&#xff1a;a * b |a||b|cosQ 这个可以看成是投影关系表达式&#xff1a;cosQ a * b / ( |a||b|) 令r cosQ&#xff1b; 求p点和线段AB的位置关系&#xff0c;可以…

将字符串根据指定的分隔符拆分为元组str.partition()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 将字符串根据指定的分隔符拆分为元组 str.partition() 选择题 对于以下python代码最后输出的结果是? string "I Love Python" print("【显示】string.partition(Love)"…

Unity3d 微信小程序(小游戏)项目实现流量主接入功能(含源码)

前言 很早之前编写了Unity导出微信小游戏的博客&#xff0c;也尝试自己做了个Demo上线了&#xff0c;基本没更新过&#xff0c;不过几个月的时间&#xff0c;用户超过了一千&#xff0c;可以开通流量主了&#xff0c;大概率是因为上篇的帖子浏览量大了&#xff0c;扫码体验的人…

Aurora、Chip2chip、Ethernet(二)

摘要&#xff1a;Aurora、Chip2chip、Ethernet共用一个gt时钟的正确的解决方案以及在实际实现以及在实现过程中遇到的其它的问题。 我在实际中遇到的困难如下&#xff1a; 现在需要将三个ip共用一对GT时钟&#xff0c;一个Ethernet IP&#xff0c;一个Ethernet IP&#xff08…

每日学术速递1.29

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV 1. Compact Transformer Tracker with Correlative Masked Modeling 标题&#xff1a;带有相关掩码建模的紧凑型变压器跟踪器 作者&#xff1a; Zikai Song, Run Luo, Junqing Yu, Y…

GLM国产大模型训练加速:性能最高提升3倍,显存节省1/3,低成本上手

作者&#xff5c;BBuf、谢子鹏、冯文 2017 年&#xff0c;Google 提出了 Transformer 架构&#xff0c;随后 BERT 、GPT、T5等预训练模型不断涌现&#xff0c;并在各项任务中都不断刷新 SOTA 纪录。去年&#xff0c;清华提出了 GLM 模型&#xff08;https://github.com/THUDM…

一句话说明线程和进程

知识点&#xff1a; 1、一句话说明线程和进程 2、操作系统为什么需要进程 3、为什么要引入线程 4、一图说明线程和进程的关系 一、一句话说明线程和进程 进程&#xff1a;是指⼀个内存中运⾏的应⽤程序&#xff0c;比如QQ、微信、浏览器等&#xff1b;⼀个应⽤程序可以同时运⾏…

CAS 和 Synchronized优化过程以及常见的锁策略

目录 &#x1f411;今日良言:追星赶月莫停留,平芜尽处是春山 &#x1f402;一、锁策略 &#x1f43c;二、CAS &#x1f42d;三、Synchronized &#x1f411;今日良言:追星赶月莫停留,平芜尽处是春山 &#x1f402;一、锁策略 锁策略是实现锁的时候,考虑出现锁竞争了该怎么…

电驱系统电磁兼容基础知识及测试方法

电驱系统电磁兼容基础知识及测试方法 学习参考&#xff1a;驱动视界公众号、百度百科、《电动汽车电机驱动系统EMC研究综述》 1.背景 2.电磁干扰三要素 3.电波暗室与屏蔽室的原理 4.测试方法 5.如何看测试数据 6.工作中需要注意的EMC的几点问题 7.案例 1.背景 汽车工业发展…

docker安装db2

第一步&#xff1a;下载镜像 docker pull ibmcom/db2express-c:latest备注&#xff1a;docker images -a 可以查看已安装镜像&#xff1b; 第二步&#xff1a;启动镜像 docker run -d --name db2 -p 50000:50000 -e DB2INST1_PASSWORD[数据库密码] -e LICENSEaccept ibmcom…

玩转PPT 第1节 PPT制作理念学习笔记

ppt神器islide 第1节 初步接触强大的工具1 PPT大神的课程总结1.1 骨架篇1.2 色彩篇1.3 对齐篇1.4 对比篇1.5 修饰篇1.6 字体篇1.7 素材篇1.8 线条篇1.8.1 可以随意画线条&#xff0c;填充空白1.8.2 在字体上画线条&#xff0c;做成艺术字1.8.3 做对称线条&#xff0c;比如递进三…

Bluesky勒索软件深度技术分析

0 1、 背景介绍 勒索软件作为一种流行的木马&#xff0c;近年来已成为最为常见的安全威胁之一。与其他威胁不同&#xff0c;勒索软件先向受害者表明自己的身份&#xff0c;再通过加密的方式使用户数据资产或计算资源无法正常使用&#xff0c;而恢复数据资产的唯一方法通常是支…

收藏破万,谷歌联手哈佛发布首个炼丹指南:教你科学化「调参」

调参不能只靠直觉&#xff0c;也是一门大学问&#xff01; 虽然算法工程师往往调侃自己是「调参侠」&#xff0c;但调参这件事可能真没想象中那么简单。 比如&#xff0c;你是不是经常会有疑惑到底该选择哪个优化器&#xff1f;一个batch放多少数据&#xff1f;超参数如何设置…

人工智能英文缩写怎么读,人工智能英文缩写大全

1、人工智能英文缩写是什么&#xff1f; AI。 人工智能&#xff0c;英文缩写为AI。它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术以及应用系统的一门技术科学。“十三五”以来&#xff0c;我国高度重视人工智能的发展&#xff0c;国内科研机构也围绕人工智能…

【Pytorch项目实战】之机器翻译:编码器-解码器、注意力机制AM

文章目录机器翻译 - 中英文翻译算法一&#xff1a;编码器-解码器&#xff08;Encoder - Decoder&#xff09;算法二&#xff1a;注意力机制&#xff08;Attention Model&#xff0c;AM&#xff09;2.1为何要引入注意力机制&#xff1f;2.2注意力机制的语义向量表示C计算2.3每个…

2023年首更,警惕6本SCISSCI期刊被剔除

2023年1月17日&#xff0c;Web of Science核心期刊目录首次更新。此次SCIE & SSCI期刊目录更新&#xff0c;与上次更新&#xff08;2022年12月&#xff09;相比&#xff0c;共有6本期刊被剔除出SCIE & SSCI期刊目录&#xff0c;详情如下&#xff1a; 公众号“Unionpub…

Redis实战9-全局唯一ID

发布优惠券的时候&#xff0c;每个店铺都可以发布优惠券&#xff0c;当用户抢购的时候,优惠券表中的id如果使用数据库的自增长ID会存在以下问题&#xff1a; 1&#xff1a;id的规律太明显&#xff0c;容易被刷 2&#xff1a;当数据量很大的时候&#xff0c;会受到单表数据的限…