Mybatis3详解 之 MyBatis 基础

news2024/12/23 16:29:50

一、Mybatis 介绍

1、什么是Mybatis

MyBatis本是Apache的一个开源项目iBatis,2010年这个项目由Apache Software Foundation迁移到了Google Code,并且改名为MyBatis,也就是从3.0版本开始 iBatis改名为MyBatis。并且于2013年11月迁移到Github,地址:https://github.com/mybatis/mybatis-3。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)

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

用一句话来形容什么Mybatis:MyBatis 是一个可以自定义 SQL、存储过程和高级映射的持久层框架。

2、一些基本概念

Mybatis是一个基于Java的持久层 / ORM框架,所以我们在学习之前,先来了解一下如下基本概念。

①、什么是“持久化”

持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等,但是一般都会存放在关系型数据库中如:MySQL、Oracle等。

②、什么是“持久层”

持久层(Persistence Layer),即专注于实现数据持久化应用领域的某个特定系统的一个逻辑层面,将数据使用者和数据实体相关联。比如我们的pojo层、Dao层和Service层的关联。

③、什么是“ORM”

ORM即Object-Relationl Mapping,意思为对象关系映射。它用于实现面向对象编程语言的类型 和 关系型数据库类型之间的相互转换。简单的说,ORM是通过描述对象和数据库之间映射的元数据,将程序中的对象与关系数据库相互映射,到时候我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。但是从前面的描述可知,我们的Mybatis是需要与SQL打交道的,所以我们认为Mybatis是一个半自动化的ORM框架。

在Java中典型的ORM中有:

  • JPA:JPA全称Java Persistence API,即Java持久化API,是sun公司推出的一套基于ORM的规范,内部由一系列的接口和抽象类构成。JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,是Java自带的框架。

  • Hibernate:全自动的ORM框架,强大、复杂、笨重、学习成本较高。Hibernate除了作为ORM框架之外,它也是一种JPA实现。

  • Mybatis:半自动的ORM框架,强大,简单,灵活,学习成本较低。Mybatis提供了自定义SQL,这样开发者将主要精力放在SQL上就行了。

之所以要做持久化和使用ORM设计,因为持久化解决了数据的存储问题,ORM解决的主要是对象关系的映射的问题。在目前的企业应用系统设计中,都是以MVC为主要的系统架构模式(MVC即 Model(模型)- View(视图)- Control(控制))。MVC 中的 Model 包含了复杂的业务逻辑和数据逻辑,以及数据存取机制等(如 JDBC的连接、SQL生成和Statement创建、还有ResultSet结果集的读取等)。将这些复杂的业务逻辑和数据逻辑分离,以将系统的紧耦合关系转化为松耦合关系(即解耦合),是降低系统耦合度迫切要做的,也是持久化要做的工作。MVC 模式实现了架构上将表现层(即View)和数据处理层(即Model)分离的解耦合,持久化的设计则实现了数据处理层内部的业务逻辑和数据逻辑分离的解耦合。 而 ORM 作为持久化设计中的最重要也最复杂的技术,也是目前业界热点技术。

一般情况下,一个持久化类和一个表对应,类的每个实例对应表中的一条记录,类的每个属性对应表的每个字段。可以用下面这样一张图来表示:

在这里插入图片描述
下面我们将关系数据中的表记录映射成为对象,以对象的形式展现,这样程序员可以把对数据库的操作转化为对对象的操作。

在这里插入图片描述
因此ORM的目的是为了方便开发人员以面向对象的思想来实现对数据库的操作。

ORM的方法论基于三个核心原则:

  • 简单:以最基本的形式建模数据。
  • 传达性:数据库结构被任何人都能理解的语言文档化。
  • 精确性:基于数据模型创建正确标准化了的结构。

3、为什么使用Mybatis

我们以前在没有ORM框架的情况下,如果你要开发一个Web应用程序的话,你就必须要使用传统的JDBC代码来操作数据库,我们除了需要自己提供 SQL 外,还必须操作 Connection、Statment、ResultSet等,不仅如此,为了访问不同的表,不同字段的数据,我们需要些很多雷同模板化的代码,而这些代码写起来往往是重复的,写起来又繁琐又枯燥。

我们下面来分析一下使用传统JDBC的缺陷,先看如下代码:

public class SqlConnection {
 
    public static void main(String[] args) {
        //定义数据库连接
        Connection con = null;
        //定义数据库语句
        PreparedStatement ps = null;
        //定义返回结果集
        ResultSet rs= null;
 
        try {
            //加载数据库驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //定义MySQL URL,因为这里有的长所以在这里定义了
            String url = "jdbc:mysql://localhost:3306/user?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8";
            //获取连接
            con = DriverManager.getConnection(url,"root","root");
            //定义SQL语句,?表示占位符
            String sql = "select * from t_user where username = ?";
            //获取编译处理的statement
            ps = con.prepareStatement(sql);
            //设置SQL参数
            ps.setString(1,"唐浩荣");
            //执行SQL语句查询,并且返回结果集
            rs = ps.executeQuery();
            //遍历结果集
            while (rs.next()){
                System.out.println(rs.getInt("id")+
                        "--"+rs.getString("username")+
                        "--"+rs.getInt("age"));
            }
 
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //关闭数据库连接(三个写一起方便0.0)
            try {
                rs.close();
                ps.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

通过上面的一段JDBC连接数据代码,我们看有哪些不好的地方:

  • 在创建Connection对象的时候,存在硬编码问题。也就是直接把连接数据库的信息写死,如果需要连接不同的数据库则要更改配置,不方便后期维护。
  • 在使用PreparedStatement对象执行SQL语句的时候同样存在硬编码问题。将SQL语句硬编码到Java代码中,如果SQL语句修改,需要重新编译Java代码,不利于系统维护。
  • 向PreparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在Java代码中,不利于系统维护。
  • 从ResutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,如果表的字段修改了则代码也需要修改,不利于系统维护。
  • 每次在进行一次数据库连接后都会创建和关闭数据库连接,频繁的开启/关闭数据连接会造成数据库资源浪费,影响数据库性能。
  • 缓存做的很差,如果存在数据量很大的情况下,这种方式性能特别低。

所以通过上面的分析,我们知道为什么要使用Mybatis了吧。在使用了 MyBatis 之后,只需要提供 SQL 语句就好了,其余的诸如:建立连接、操作Statment、ResultSet,处理 JDBC 相关异常等等都可以交给 MyBatis 去处理,我们的关注点于是可以就此集中在 SQL 语句上,关注在增删改查这些操作层面上。并且 MyBatis 支持使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,即普通的 Java对象)映射成数据库中的记录。

简单的说一下Mybatis相对JDBC的优势:

  • Mybatis是把连接数据库的信息都是写在配置文件中,因此不存在硬编码问题,方便后期维护。
  • Mybatis执行的SQL语句都是通过配置文件进行配置,不需要写在Java代码中。
  • Mybatis的连接池管理、缓存管理等让连接数据库和查询数据效率更高。

4、Mybatis的特点及优缺点

特点:

  • MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。
  • MyBatis 封装了底层 JDBC API 的调用细节,并能自动将结果集转换成 Java Bean 对象,大大简化了 Java 数据库编程的重复工作。
  • MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
  • MyBatis 可以使用简单的XML或注解用于配置和原始映射,将接口和Java的实体映射成数据库中的记录。
  • MyBatis 把 SQL语句从 Java 源程序中独立出来,放在单独的 XML 文件中编写,给程序的维护带来了很大便利。
  • MyBatis 需要程序员自己去编写 SQL语句,程序员可以结合数据库自身的特点灵活控制 SQL语句,因此能够实现比 Hibernate 等全自动 ORM框架更高的查询效率,能够完成复杂查询。

优点:

  • 简单易学,Mybatis本身就很小且简单,整个源代码大概5MB左右。并且没有任何第三方依赖,简单实用只要几个Jar包+配置几个SQL映射文件,而且有官方中文文档,可以通过官方文档轻松学习。
  • 使用灵活,易于上手和掌握。相比于JDBC需要编写的代码更少,减少了50%以上的代码量。
    提供XML标签,支持编写动态SQL,满足不同的业务需求。
  • SQL写在XML里,便于统一管理和优化,同时也解除SQL与程序代码的耦合。使系统的设计更清晰,更易维护,更易单元测试。SQL和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的ORM字段关系映射。
  • 提供对象关系映射标签,支持对象关系组建维护。

缺点:

  • SQL语句的编写工作量较大,尤其在表、字段比较多的情况下,对开发人员编写SQL的能力有一定的要求。
  • SQL语句依赖于数据库,导致数据库不具有好的移植性,不可以随便更换数据库。

总体来说,MyBatis 是一个非常优秀和灵活的数据持久化框架,适用于需求多变的互联网项目,也是当前主流的 ORM 框架。

5、Mybatis和Hibernate的区别

Mybatis和Hibernate都是一款非常受欢迎的持久化框架,那么Mybatis和Hibernate二组之间有哪些区别呢?

下面我们来看一下,因为这个问题面试很可能会问到。

①、开发方面:

  • Hibernate 属于全自动 ORM 映射工具,使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。
  • Mybatis 属于半自动 ORM 映射工具,Mybatis 在查询关联对象或关联集合对象时,需要手动编写 SQL来完成,所以,称之为半自动 ORM 映射工具。不过 Mybatis 可以通过 XML 或注解方式灵活配置要运行的 SQL语句,并将Java 对象和 SQL语句映射生成最终执行的 SQL,最后将 SQL执行的结果再映射生成Java 对象。

②、底层方面:

  • Hibernate的底层则是 JPA 规范的实现。
  • Mybatis的底层封装了 JDBC 的代码。

③、SQL优化方面:

  • Hibernate 自动生成SQL,有些语句较为繁琐,会多消耗一些性能。
  • Mybatis 手动编写SQL,可以避免不需要的查询,提高系统性能。

④、学习成本方面:

  • Hibernate 的学习门槛高,要精通门槛更高,而且怎么设计 O/R 映射,在性能和对象模型之间如何权衡,以及怎样用好 Hibernate 需要具有很强的经验和能力才行。
  • Mybatis的学习门槛低,简单易学,程序员只需要把重心放在写原生态 SQL 上即可,可严格控制 SQL执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。

⑤、对象管理方面

  • Hibernate 是完整的对象/关系映射的框架,对象/关系映射能力极强,开发工程中,无需过多关注底层实现,只要去管理对象即可;而且数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用 Hibernate 开发可以节省很多代码,提高效率。
  • Mybatis 需要自行管理 映射关系;而且Mybatis 无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套 SQL映射文件,工作量大。

⑥日志系统方面:

  • Hibernate日志系统非常健全,涉及广泛,包括:SQL记录、关系异常、优化警告、缓存提示、脏数据警告等。
  • Mybatis则除了基本记录功能外,功能薄弱很多。

⑦、缓存方面

相同点:
Hibernate和Mybatis的二级缓存除了采用系统默认的缓存机制外,都可以通过实现你自己的缓存或为其他第三方缓 存方案,创建适配器来完全覆盖缓存行为。

不同点:

  • Hibernate的二级缓存配置在SessionFactory生成的配置文件中进行详细配置,然后再在具体的表-对象映射中配置是那种缓存。如果使用二级缓存时如果出现脏数据,系统会报出错误并提示。

  • MyBatis的二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不同的表可以自定义不同的缓存机制。并且Mybatis可以在命名空间中共享相同的缓存配置和实例,通过Cache-ref来实现。

⑧、各一句话总结它们:

  • Mybatis:小巧、方便、高效、简单、直接、半自动化。比喻:机械工具,使用方便,拿来就用,但工作还是要自己来作,不过工具是活的,怎么使由我决定。
  • Hibernate:强大、方便、高效、复杂、间接、全自动化。比喻:智能机器人,但研发它(学习、熟练度)的成本很高,工作都可以摆脱他了,但仅限于它能做的事。

最后,不管你使用哪个持久化框架,它们都有它们各自的特点。总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。

6、MyBatis的重要组件

Mybatis封装了JDBC的代码,我们来分析Mybatis给我们的一些重要组件。

在这里插入图片描述
我们从上往下看,MyBatis 中的一些重要组件如下:

  • Mybatis的配置文件:SqlMapConfig.xml是Mybatis的全局配置文件,主要配置数据源、事务、加载映射文件等,它的名称可以是任意(最好见名知意)。Mapper.xml主要是配置Statement的相关信息,如SQL语句。
  • SqlSessionFactoryBuilder:会根据XML配置或是Java配置来生成SqlSessionFactory对象.采用建造者模式(简单来说就是分步构建一个大的对象,例如建造一个大房子,采用购买砖头、砌砖、粉刷墙面的步骤建造,其中的大房子就是大对象,一系列的建造步骤就是分步构建)。
  • SqlSessionFactory:用于生成SqlSession,可以通过 SqlSessionFactory.openSession() 方法创建 SqlSession 对象。使用工厂模式(简单来说就是我们获取对象是通过一个类,由这个类去创建我们所需的实例并返回,而不是我们自己通过new去创建)。
  • SqlSession:相当于JDBC中的 Connection对象,可以用 SqlSession 实例来直接执行被映射的 SQL 语句,也可以获取对应的Mapper。
  • Executor:MyBatis 中所有的 Mapper 语句的执行都是通过 Executor 执行的。(Mapper:由XML文件和Java接口组成,根据XML中配置的映射信息执行对应的SQL语句并返回执行结果。)
  • Mapper接口:数据操作接口也就是通常说的 DAO 接口,要和 Mapper 配置文件中的方法一一对应,也就是必须和Mapper.xml中的增删改查标签Id一致。
  • Mapper配置:用于组织具体的查询业务和映射数据库的字段关系,可以使用 XML 格式(Mapper.xml)或 Java 注解格式来实现。
  • MappedStatement:作用是封装了Statement的相关信息,包括SQL语句、输入参数和输出结果等等。

7、MyBatis 执行流程简单说明

  1. 首先是加载Mybatis的全局配置文件,随后会加载SQL 映射文件或者是注解的相关 SQL 内容。
  2. 创建会话工厂,MyBatis 通过读取配置文件的信息来构造出会话工厂(SqlSessionFactory)。
  3. 创建会话,根据会话工厂,MyBatis 就可以通过它来创建会话对象(SqlSession),会话对象是一个接口,该接口中包含了对数据库操作的增、删、改、查方法。
  4. 创建执行器,因为会话对象本身不能直接操作数据库,所以它使用了一个叫做数据库执行器(Executor)的接口来帮它执行操作。
  5. 封装 SQL 对象,在这一步,执行器将待处理的 SQL 信息封装到一个对象中(MappedStatement),该对象包括 SQL 语句、输入参数映射信息(Java 简单类型、HashMap 或 POJO)和输出结果映射信息(Java 简单类型、HashMap 或 POJO)。
  6. 操作数据库,拥有了执行器和 SQL 信息封装对象就使用它们访问数据库了,最后再返回操作结果,结束流程。

二、Mybatis 的使用

1、创建一个数据库

由于Mybatis是对数据库的操作,所以首先得先创建一个数据库和一个表,数据库命名为mybatis,表命名为t_user。这里针对MySQL数据库。

SQL脚本如下:


DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `address` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, '奥利给', 18, '男', '上海');
INSERT INTO `t_user` VALUES (2, '蔡徐坤', 18, '男', '北京');
INSERT INTO `t_user` VALUES (3, '黄飞鸿', 42, '男', '大清');
INSERT INTO `t_user` VALUES (4, '十三姨', 18, '女', '大清');
INSERT INTO `t_user` VALUES (5, '梁宽', 42, '男', '大清');
INSERT INTO `t_user` VALUES (6, '马保国', 33, '男', '深圳');
INSERT INTO `t_user` VALUES (7, '纳兰元述', 42, '男', '大清');

2、创建Maven工程

在Eclipse或IDEA中创建一个Maven项目。

在这里插入图片描述
然后导入pom依赖,如下:

<dependencies>
    <!-- Mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.6</version>
    </dependency>
    <!-- mysql驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
    </dependency>
    <!-- 日志处理 -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>
    <!-- 单元测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>

3、编写User实体类

创建一个User实体类,这里省略了getter、setter和toString方法,需自己加上。

/**
 * 用户实体类
 */
public class User {
    private Integer id;
    private String username;
    private Integer age;
    private String sex;
    private String address;

    //getter、setter、toString方法省略......
}

4、创建Mybatis全局配置文件

然后在resources目录中,创建Mybatis的全局配置文件mybatis-config.xml。它是mybatis核心配置文件,配置文件内容为数据源、事务管理和指定映射配置文件的位置。代码如下:

<?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>
    <!-- 配置环境.-->
    <environments default="development">
        <!-- id属性必须和上面的default一致 -->
        <environment id="development">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 -->
            <dataSource type="POOLED">
                <!--配置连接数据库的4个基本信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/user?serverTimezone=GMT%2B8&amp;useUnicode=true&amp;characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

对mybatis-config.xml中配置项的简单说明:

  • environments:配置当前的环境,default属性有development和work两种选择,默认是development开发模式,work是工作模式。
  • environment:配置每个environment定义的环境,可以配置多个运行环境,但是每个SqlSessionFactory实例只能选择一个运行环境。其id属性也有development和work两种选择,并且必须和上面的default属性一致。如果配置了两个相同的environment,Mybatis会用后面的覆盖掉前面的。
  • transactionManager:配置事务管理器类型,type属性中有JDBC和MANAGED两种,一次只能配置一个。
  • JDBC使用JdbcTransactionFactory工厂生成的JdbcTransaction对象实现,以JDBC的方式进行数据库的提交、回滚等操作,它依赖于从数据源得到的连接来管理事务范围。
  • MANAGED使用ManagedTransactionFactory工厂生成的ManagedTransaction对象实现,它的提交和回滚不需要任何操作,而是把事务交给容器进行处理,默认情况下会关闭连接,如果不希望默认关闭,只要将其中的closeConnection属性设置为false即可。
  • dataSource:配置数据源类型,type属性有UNPOOLED、POOLED和JNDI三种选择:
    UNPOOLED(UnpooledDataSourceFactory):采用非数据库池的管理方式,每次请求都会新建一个连接,并用完后关闭它,所以性能不是很高。该方式适用于只有小规模数量并发用户的简单应用程序上。
  • POOLED(PooledDataSourceFactory):采用连接池的概念将数据库链接对象Connection组织起来,可以在初始化时创建多个连接,使用时直接从连接池获取,避免了重复创建连接所需的初始化和认证时间,从而提升了效率,所以这种方式比较适合对性能要求高的应用中。在开发或测试环境中经常用到此方式。
  • JNDI(JndiDataSourceFactory):数据源JNDI的实现是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。在生产环境中优先考虑这种方式。
  • property:dataSource中的property元素就是数据库相关的配置信息。

5、编写SQL映射配置文件

我们在目录resources—>mapper(mapper目录自行创建)下创建一个UserMapper.xml文件。Mybatis中所有数据库的操作都会基于该映射文件配置的SQL语句,在这个配置文件中可以配置任何类型的SQL语句。框架会根据配置文件中的参数配置,完成对SQL语句输入输出参数的映射配置。

在这里插入图片描述
文件代码如下所示:

<?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属性:表示命名空间,用来设定当前Mapper配置文件的唯一标识,将来在Java程序中通过namespace属性的值来定位到这个配置文件 -->
<!-- namespace属性值设置的方式:名字可以随便取,但是推荐以相对应的Mapper接口的全类名,例如com.thr.mapper.UserMapper -->
<mapper namespace="com.thr.mapper.UserMapper">
    <!-- 查询所有用户 -->
    <select id="selectAllUser" resultType="com.thr.entity.User">
        select * from t_user;
    </select>
    <!-- 通过Id查询一个用户 -->
    <select id="selectUserById" parameterType="int" resultType="com.thr.entity.User">
        select * from t_user where id = #{id};
    </select>
    <!-- 模糊查询,根据username字段查询用户-->
    <select id="selectUserByName" parameterType="int" resultType="com.thr.entity.User">
        select * from t_user where username like '%${value}%';
    </select>
    <!-- 添加用户-->
    <insert id="insertUser" parameterType="com.thr.entity.User">
        insert into t_user(username, age, sex, address)
        values (#{username}, #{age}, #{sex}, #{address});
    </insert>
    <!-- 根据Id更新用户 -->
    <update id="updateUser" parameterType="com.thr.entity.User">
        update t_user set username = #{username},
            age = #{age},sex = #{sex},address = #{address} where id = #{id}
    </update>
    <!-- 根据Id删除用户 -->
    <delete id="deleteUser" parameterType="int">
        delete from t_user where id = #{id}
    </delete>
</mapper>

6、加载映射文件

将上面创建的UserMapper.xml文件添加至全局配置文件mybatis-config.xml下。

在这里插入图片描述


<!--指定映射配置文件的位置,这个映射配置文件指的是每个业务独立的配置文件-->
<mappers>
    <mapper resource="mapper/UserMapper.xml"/>
</mappers>

7、导入日志文件

导入日志文件,在resources目录中创建log4j.properties文件,并且导入如下配置(如果log报错则以管理员的方式启动Eclipse或IDEA)。

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
 
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
 
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
 
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:/axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

8、编写测试代码

最后创建一个MybatisTest的测试类,其源代码如下所示:

注意:使用JDBC的事务管理在进行增删改操作时,需要进行提交事务,也就是sqlSession.commit(),否则数据不会操作成功。

/**
 * Mybatis的测试
 */
public class MybatisTest {
    //定义 SqlSession
    SqlSession sqlSession = null;

    @Before
    public void getSqlSession() {
        //加载 mybatis 全局配置文件
        InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
        //创建 SqlSessionFactory 对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        //根据 sqlSessionFactory 产生 session
        sqlSession = sqlSessionFactory.openSession();
    }

    //查询所有用户数据
    @Test
    public void testSelectAllUser() {
        /**
         * 注意:这个字符串由 UserMapper.xml 文件中的两个部分构成(namespace + id)
         * <mapper namespace="com.thr.mapper.UserMapper">中 namespace 的值
         * <select id="selectAllUser" > 中的 id 值
         * 这样Mybatis才能找到需要的SQL
         */
        String statement = "com.thr.mapper.UserMapper.selectAllUser";
        List<User> listUser = sqlSession.selectList(statement);
        for (User user : listUser) {
            System.out.println(user);
        }
        sqlSession.close();
    }

    //根据Id查询一个用户数据
    @Test
    public void testSelectUserById() {
        String statement = "com.thr.mapper.UserMapper.selectUserById";
        User user = sqlSession.selectOne(statement, 1);
        System.out.println(user);
        sqlSession.close();
    }

    //模糊查询:根据 user 表的username字段
    @Test
    public void testSelectUserByName() {
        String statement = "com.thr.mapper.UserMapper.selectUserByName";
        List<User> listUser = sqlSession.selectList(statement, "三");
        for (User user : listUser) {
            System.out.println(user);
        }
        sqlSession.close();
    }

    //添加一个用户数据
    @Test
    public void testInsertUser() {
        String statement = "com.thr.mapper.UserMapper.insertUser";
        User user = new User();
        user.setUsername("张三");
        user.setAge(34);
        user.setSex("男");
        user.setAddress("中国深圳");
        int i = sqlSession.insert(statement, user);
        System.out.println( (i>0)? "添加成功!":"添加失败!");
        //提交插入的数据
        sqlSession.commit();
        sqlSession.close();
    }

    //根据Id修改用户数据
    @Test
    public void testUpdateUser(){
        //如果设置的 id不存在,那么数据库没有数据更改
        String statement = "com.thr.mapper.UserMapper.updateUser";
        User user = new User();
        user.setId(3);
        user.setUsername("王红");
        user.setAge(26);
        user.setSex("女");
        user.setAddress("中国上海");
        int i = sqlSession.update(statement, user);
        System.out.println( (i>0)? "修改成功!":"修改失败!");
        //提交数据
        sqlSession.commit();
        sqlSession.close();
    }

    //根据Id删除用户数据
    @Test
    public void testDeleteUser(){
        String statement = "com.thr.mapper.UserMapper.deleteUser";
        int i = sqlSession.delete(statement, 4);
        System.out.println( (i>0)? "删除成功!":"删除失败!");
        sqlSession.commit();
        sqlSession.close();
    }
}

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

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

相关文章

集约管控、按需分配:和鲸聚焦 AI for Science 科研算力高校调配

随着人类社会进入信息时代的智能化阶段&#xff0c;数据逐渐成为基础生产要素之一&#xff0c;而算力也因此成为重要生产力。《学习时报》9 月 3 日发文《算力为何如此重要》&#xff0c;文中指出&#xff0c;人工智能技术的突破与产业数字化应用对算力提出了更高的要求&#x…

怎么把一个音频平均拆分成多个?3个方法快速拆分

怎么把一个音频平均拆分成多个&#xff1f;近年来&#xff0c;随着音频文件在日常生活和工作中的广泛应用&#xff0c;人们对于对音频进行编辑、处理和转换的需求也越来越高。由此&#xff0c;音频编辑软件应运而生&#xff0c;可帮助我们轻松地剪辑、切分、编辑和转换音频文件…

Blender纹理UV映射快速入门

推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 Blender 的功能包括 UV 映射&#xff0c;它是指将 3D 模型的表面展开到 2D 平面上并将纹理或图像应用到模型表面的过程。 这是创建具有真实纹理的 3D 模型的重要组成部分。 最新版本的 Blender (3.4) 包含有用的更新和功能…

大规模语言模型的模型结构--解码器结构(PaLM,BLOOM,InstructGPT系列)

与编码器结构(encoder-only) 的语言模型结构相反&#xff0c; 解码器结构(decoder-only) 的语言模型结构只包含trans- former 结构里的 decoder 部分。在 BERT 发布之前的 GPT- 1 就是 decoder-only 的语言模型&#xff0c; 但在 GPT-3 发布并展 示其惊人表现后&#xff0c; de…

PSINS工具箱学习(二)姿态的表示:姿态阵、四元数、欧拉角、等效旋转矢量的概念和转换

原始 Markdown文档、Visio流程图、XMind思维导图见&#xff1a;https://github.com/LiZhengXiao99/Navigation-Learning 文章目录 一、基础概念1、坐标系定义1. 惯性坐标系&#xff08; i 系 &#xff09;2. 地心地固坐标系&#xff08; e 系 )3. 导航坐标系&#xff08; n 系&…

Tomcat报404问题的原因分析

1.未配置环境变量 按照需求重新配置即可。 2.IIs访问权限问题 注意:这个问题有的博主也写了,但是这个问题可有可无,意思是正常情况下,有没有都是可以访问滴放心 3.端口占用问题 端口占用可能会出现这个问题,因为tomcat的默认端口号是8080,如果在是运行tomcat时计算机的…

深度学习与视频直播美颜sdk:背后的技术革新

时下&#xff0c;深度学习技术在视频直播美颜sdk中的应用正引领着一场技术革新的浪潮。本文将探讨深度学习如何在视频直播美颜sdk背后推动了技术的革新&#xff0c;以及它是如何影响我们的日常直播体验的。 一、传统美颜技术的局限性 在深入探讨深度学习之前&#xff0c;让我们…

目标识别项目实战:基于Yolov7-LPRNet的动态车牌目标识别算法模型

目标识别项目&#xff1a;基于Yolov7-LPRNet的动态车牌目标识别算法模型(一) 前言 目标识别如今以及迭代了这么多年&#xff0c;普遍受大家认可和欢迎的目标识别框架就是YOLO了。按照官方描述&#xff0c;YOLOv8 是一个 SOTA 模型&#xff0c;它建立在以前 YOLO 版本的成功基…

MacOS Sonoma 14更新:优化小组件、升级视频会议、沉浸式游戏体验等

苹果今天发布新闻稿&#xff0c;宣布以免费软件更新形式&#xff0c;正式发布 macOS Sonoma&#xff0c;为 Mac 带来一系列丰富新功能。 在 macOS Sonoma 中&#xff0c;桌面小组件解锁了个性化 Mac 与提升效率的全新方式&#xff0c;引入精美的新屏幕保护程序、视频会议和 Saf…

golang工程——grpc TLS配置

TLS配置 非对称加密流程 TLS流程 这是单向TLS流程 ECDHE握手过程&#xff08;图片来自透视Http协议课程&#xff09; 浏览器发送Client Hello消息 客户端向服务器打招呼&#xff0c;消息中包含客户端生成的随机数C&#xff0c;客户单的TLS版本号&#xff0c;可使用的密码套…

SkyWalking分布式链路追踪学习

为什么要用分布式链路追踪 实际生产中&#xff0c;面对几十个、甚至成百上千个的微服务实例&#xff0c;如果一旦某个实例发生宕机&#xff0c;如果不能快速定位、提交预警&#xff0c;对实际生产造成的损失无疑是巨大的。所以&#xff0c;要对微服务进行监控、预警&#xff0…

nodejs进阶知识

文章目录 写在前面一、dependencies、devDependencies和peerDependencies区别&#xff1a;二、需要牢记的npm命令2.1 npm2.2 npm config list2.3 npm配置镜像源 三、npm install 的原理四、package-lock.json的作用五、npm run 的原理六、npx6.1 npx是什么6.2 npx的优势6.3 npm…

linux使用md5sum校验下载文件是否完整/被篡改

素材&#xff1a;cuda的run文件&#xff08;见下图&#xff09;。 网址&#xff1a;点击这里 任务&#xff1a;检验下载的cuda_11.7.0_515.43.04_linux.run文件是否完整。 步骤&#xff1a; 图片下方倒数第2行&#xff0c;提供了文件的checksum。 找到我需要的checksum&#…

用Python让字符串整齐排列:左对齐、右对齐还是居中对齐?

文章目录 左对齐使用字符串的对齐属性使用`format`函数右对齐使用字符串的对齐属性使用`format`函数居中对齐使用字符串的对齐属性format 居中对齐多行字符串居中对齐在Python中,可以使用字符串的对齐属性以及format函数来实现字符串的对齐。下面将分别介绍左对齐、右对齐、居…

如何实现朋友圈一键转发?

还在用传统的发朋友圈方式吗&#xff1f;NO NO NO 快来看看&#xff0c;新的发圈姿势等你get&#xff01;企业统一编辑任务&#xff0c;定时发送、立即发送随你心情。统一素材&#xff0c;一键发送&#xff0c;轻松操作&#xff0c;尤其是节假日&#xff0c;员工放假&#xff0…

Rust 在前端都干了些啥

前言 这里有一篇两年前的文章&#xff1a;Rust 是 JavaScript 基础设施的未来&#xff0c;应该还是有挺多人看到过的。当时在前端社区上还掀起了一阵 Rust 风&#xff0c;有人说怎么天天造轮子&#xff0c;有人说实在是学不动了&#xff0c;也有人抱着积极的心态去拥抱新东西。…

C++之std::atomic解决多线程7个问题(二百四)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Redis的安装与基本使用

文章目录 Linux 环境下安装Redis下载Redis 安装包解压安装包安装Redis进入redis安装包下编译并且安装到指定目录下 启动redis配置远程访问找到Redis.config文件 Windows 环境下安装Redis说明官方提供方式安装或启用WSL2在WSL&#xff08;Ubuntu&#xff09;上安装Redis启动Redi…

【QT+CUDA】QT中使用cuda,QT+VS+cuda下载安装配置

文章目录 相关网址汇总&#xff1a; 一、软件安装&#xff1a;VS、CUDA、QT1 安装VS1.1 下载1.2 vs2017安装1.3 vs2015安装 2 安装CUDA2.1 下载2.2 安装2.3 测试2.4 卸载 3 安装QT3.1 下载3.2 安装 二、QT使用cuda1 .pro文件 三、常用操作1 NVIDIA控制面板&#xff1a;显卡、驱…

口袋参谋:如何快速补充缺失的免费流量入口?30秒就可操作!

​在淘宝店铺运营过程中&#xff0c;流量过低怎么办&#xff1f; 我相信很多卖家会选择付费流量&#xff0c;如&#xff1a;直通车、引力魔方等付费推广&#xff0c;虽然说它们的流量来的比较快&#xff0c;但是也要花大价钱去投流。 如果想免费提高店铺流量的&#xff0c;不妨…