MyBatis 学习(二)之 第一个 MyBatis 案例

目录

[1 配置 MyBatis 方式](#1 配置 MyBatis 方式)

[1.1 XML 配置文件](#1.1 XML 配置文件)

[1.2 Java 注解配置](#1.2 Java 注解配置)

[1.3. Java API 配置](#1.3. Java API 配置)

[2 在 MySQL 中创建一张表](#2 在 MySQL 中创建一张表)

[3 创建一个基于 Maven 的 JavaWeb 工程](#3 创建一个基于 Maven 的 JavaWeb 工程)

[4 编写 User 实体类](#4 编写 User 实体类)

[5 创建 Mybatis 全局配置文件](#5 创建 Mybatis 全局配置文件)

[6 编写一个 DAO 或 Mapper 接口](#6 编写一个 DAO 或 Mapper 接口)

[7 编写 SQL 映射配置文件(重要)](#7 编写 SQL 映射配置文件(重要))

[8 加载映射文件](#8 加载映射文件)

[9 导入日志文件](#9 导入日志文件)

[10 创建 MyBatisTest 测试类](#10 创建 MyBatisTest 测试类)

[11 参考文档](#11 参考文档)


1 配置 MyBatis 方式

MyBatis 可以通过以下三种方式来创建和配置

1.1 XML 配置文件

最常见的方式是使用 XML 配置文件来配置 MyBatis。在 XML 配置文件中,可以定义数据源、映射文件的位置、类型别名、插件等信息。XML 配置文件通常包括 MyBatis 的全局配置和映射文件的配置。以下是一个简单的 XML 配置文件示例:

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>
    <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/mydatabase"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/example/mapper/ExampleMapper.xml"/>
    </mappers>
</configuration>

1.2 Java 注解配置

从 MyBatis 3.4.1 版本开始,MyBatis 支持使用 Java 注解来配置映射关系。可以使用 @MapperScan 注解来指定 Mapper 接口所在的包,也可以使用 @Mapper 注解来标记 Mapper 接口。以下是一个简单的 Java 注解配置示例:

java 复制代码
@Configuration
@MapperScan("com.example.mapper")
public class MyBatisConfig {
    // 数据源配置
    // 其他配置...
}

1.3. Java API 配置

除了使用 XML 配置文件和 Java 注解外,MyBatis 还支持使用 Java API 来进行配置。通过编写 Java 代码,可以动态地创建 SqlSessionFactory 对象,并且进行各种配置。以下是一个简单的 Java API 配置示例:

java 复制代码
DataSource dataSource = getDataSource(); // 获取数据源
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(MyMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

2 在 MySQL 中创建一张表

java 复制代码
drop table if exists person; 
create table person (
id int(10) primary key auto_increment, #主键,自动增长
name varchar(14) unique not null, #该行不重复,不为空
age int,
sex char(10) default '女' # 没有插入该列,填入默认值"女"
)charset=utf8; #utf-8 编码

#多行插入
insert into person(name, age, sex) values
('西施', 18, '女'),
('大乔', 32, null),
('王昭君', 24, null);

insert into person(name,age) values('赵飞燕',27);
insert into person(name,age) values('虞姬', 25);
insert into person(id,name,age) values(9, '貂蝉', 26);

3 创建一个基于 Maven 的 JavaWeb 工程

可以参考以下博文:

IDEA 2023.2 配置 JavaWeb 工程-CSDN博客https://blog.csdn.net/zjs246813/article/details/136199249?spm=1001.2014.3001.5501导入依赖

XML 复制代码
<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>

4 编写 User 实体类

java 复制代码
public class User {
    private Integer id;
    private String name;
    private Integer age;
    private String sex;


    // Getter、Setter、toString() 方法省略
}

5 创建 Mybatis 全局配置文件

创建 mysql.properties 配置文件

study 改为自己的数据库名

root 是数据库用户名

123456 是数据库用户密码

驱动器一般为 com.mysql.jdbc.Driver

java 复制代码
url=jdbc:mysql://localhost:3306/study?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
name=root
password=123456
driver=com.mysql.cj.jdbc.Driver

在 resources 目录中,创建 Mybatis 的全局配置文件 mybatis-config.xml

java 复制代码
<?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>
    <!-- 通过properties标签,读取java配置文件的内容 -->
    <properties resource="mysql.properties" />
    <!-- 配置环境.-->
    <environments default="development">
        <!-- id属性必须和上面的default一致 -->
        <environment id="development">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象源 -->
            <dataSource type="POOLED">
                <!--配置连接数据库的4个基本信息-->
                <property name="url" value="${url}" />
                <property name="username" value="${name}" />
                <property name="password" value="${password}" />
                <property name="driver" value="${driver}" />
            </dataSource>
        </environment>
    </environments>
</configuration>

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

  • properties :**用于加载外部属性文件,**通过指定 resource="mysql.properties",MyBatis 会尝试从当前目录下查找名为 "mysql.properties" 的文件,并将其中的属性值应用到配置 property 中
  • environments配置当前的环境,default 属性有 development 和 work 两种选择,默认是 development 开发模式,work 是工作模式 指定当前运行环境 ,通过 default 属性 指定某个运行环境的标识符 id 来使用该运行环境
  • environment :配置每个 environment 定义的环境,可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境。其 id 属性也有 development 和 work 两种选择,并且必须和上面的 default 属性一致 配置运行环境,通过 id 属性来标识该环境。如果配置了两个相同的 environment,即它们的 id 属性值相同,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 元素就是数据库相关的配置信息

6 编写一个 DAO 或 Mapper 接口

在 com.mapper 目录下创建一个 UserMapper 接口

java 复制代码
package com.mapper;

import com.entity.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserMapper {
    // 查询所有用户
    List<User> selectAllUser();
    // 通过 id 查询一个用户
    User selectUserById(int id);
    // 模糊查询,根据 name 字段查询用户
    List<User> selectUserByName(String name);
    // insert、update、delete的返回值都是int(影响行数)
    // 添加用户
    // 带两个参数,需要在接口中通过@Param注解指定名称(因为编译时参数名不会保留)
    int insertUser(@Param("name") String name,
                    @Param("age") int age,
                    @Param("sex") String sex);
    // 根据 id 更新用户
    int updateUser(@Param("id") int id,
                    @Param("name") String name,
                    @Param("age") int age,
                    @Param("sex") String sex);
    // 根据 id 删除用户
    int deleteUsesr(int id);
}

7 编写 SQL 映射配置文件(重要)

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

相关属性 描述
namespace 表示命名空间,用来设定当前 Mapper 配置文件的唯一标识,将来在 Java 程序中通过 namespace 属性值来定位到这个配置文件,namespace 属性值可以随意命名,建议使用 Mapper 接口的全类名命名,如 com.mapper.UserMapper
id SQL 映射语句的唯一标识
parameterType 用来指定 SQL 语句中的参数类型,可以是一个简单类型,也可以是一个复杂对象类型
resultType 和 resultMap 用来指定 SQL 语句的返回值类型,resultType 用于指定返回的单一结果类型,而 resultMap 用于指定返回结果的映射关系,通常用于复杂的查询结果映射
parameterMap 用来指定参数映射关系
sql 用于定义可重用的 SQL 片段,可以在不同的 SQL 语句中重复使用,从而减少重复编写相同的 SQL 代码
include 用于引用外部的 SQL 片段,可以在 SQL 映射文件中引用其他 SQL 片段,从而实现模块化的 SQL 代码编写
cache 用于配置结果缓存,可以指定 SQL 语句的查询结果是否需要被缓存
#{} #{} 表示 SQL 语句的占位符
${} ${} 表示 SQL 语句的拼接符

#{} 和 ${} 介绍

  • #{}SQL 语句的占位符,相当于JDBC中的 "?",它会自动进行 Java 类型和 JDBC 类型转换,可以防止 SQL 注入攻击。#{} 接受的输入参数的类型可以是简单类型、普通 JavaBean 或者 HashMap 。当接受简单类型时,#{} 中可以写 value 或者其他任意名称。如果接受的是JavaBean,它会通过 OGNL 读取对象中的属性值,例如,一个JavaBean user,它有一个属性 name,在映射文件中可以使用 #{user.name} 来引用这个属性值
  • **{}** : **SQL 语句的拼接符**,会将接收到的参数在不进行 JDBC 类型转换的情况下拼接在 SQL 语句中,{} 里面必须要写参数,不然会报错。{} 接受输入参数的类型可以是简单类型、普通 JavaBean 或者 HashMap 。当接受简单类型时,{} 中只能写 value,而不能写其他任意名称。如果接受的是 JavaBean,它会通过 OGNL 读取对象中的属性值,同上
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">

<!--namespace-绑定一个对应dao/mapper接口-->
<mapper namespace="com.mapper.UserMapper">
    <!-- 查询所有用户 -->
    <!--
     通过 resultType 指定查询的结果是 User 类型的数据
     只需要指定 resultType 的类型,MyBatis 会自动将查询的结果映射成 JavaBean 中的属性
      -->
    <!-- id 和 com.mapper.UserMapper.selectAllUser 对应 -->
    <select id="selectAllUser" resultType="com.entity.User">
        select * from person;
    </select>
    <!-- 通过id查询一个用户 -->
    <!-- 带一个简单类型的参数, 这种情况下parameterType属性可以省略,
    mybatis可以自动推断出类型 -->
    <select id="selectUserById" parameterType="int" resultType="com.entity.User">
        select * from person where id = #{id};
    </select>
    <!-- 模糊查询,根据name字段查询用户-->
    <select id="selectUserByName" parameterType="String" resultType="com.entity.User">
        select * from person where name like '%${value}%';
    </select>
    <!-- 添加用户-->
    <!-- 带两个参数,需要在接口中通过@Param注解指定名称(因为编译时参数名不会保留) -->
    <!-- insert、update、delete的返回值都是int(影响行数) -->
    <insert id="insertUser" parameterType="com.entity.User">
        insert into person(name, age, sex)
        values (#{name}, #{age}, #{sex});
    </insert>
    <!-- 根据id更新用户 -->
    <update id="updateUser" parameterType="com.entity.User">
        update person set name = #{name},
                          age = #{age},sex = #{sex} where id = #{id}
    </update>
    <!-- 根据id删除用户 -->
    <delete id="deleteUser" parameterType="int">
        delete from person where id = #{id}
    </delete>
</mapper>

8 加载映射文件

将上面创建的 UserMapper.xml 文件配置到全局配置文件 mybatis-config.xml 中

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

9 导入日志文件

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

html 复制代码
# 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

10 创建 MyBatisTest 测试类

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

java 复制代码
public class MybatisTest {
    //定义 SqlSession
    SqlSession sqlSession = null;

    @Before
    public void getSqlSession() throws IOException {
        //加载 mybatis 全局配置文件 Resources
        // 原 InputStream is = MybatisTest.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
        InputStream is = Resources.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.mapper.UserMapper">中 namespace 的值
         * <select id="selectAllUser" > 中的 id 值
         * 这样Mybatis才能找到需要的SQL
         */
        String statement = "com.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.mapper.UserMapper.selectUserById";
        User user = sqlSession.selectOne(statement, 1);
        System.out.println(user);
        sqlSession.close();
    }

    //模糊查询:根据 person 表的 name 字段
    @Test
    public void testSelectUserByName() {
        String statement = "com.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.mapper.UserMapper.insertUser";
        User user = new User();
        user.setName("嫦娥");
        user.setAge(24);
        user.setSex("女");
        int i = sqlSession.insert(statement, user);
        System.out.println( (i>0)? "添加成功!":"添加失败!");
        //提交插入的数据
        sqlSession.commit();
        sqlSession.close();
    }

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

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

部分执行结果

执行过程(添加一个用户)

11 参考文档

Mybatis3详解(二)----Mybatis的第一个入门实例 - 唐浩荣 - 博客园 (cnblogs.com)

[MyBatis中#{}占位符与{}拼接符的用法说明_java_脚本之家 (jb51.net)](https://www.jb51.net/article/206134.htm "MyBatis中#{}占位符与{}拼接符的用法说明_java_脚本之家 (jb51.net)")

相关推荐
程序员南飞40 分钟前
ps aux | grep smart_webrtc这条指令代表什么意思
java·linux·ubuntu·webrtc
弥琉撒到我43 分钟前
微服务swagger解析部署使用全流程
java·微服务·架构·swagger
一颗花生米。2 小时前
深入理解JavaScript 的原型继承
java·开发语言·javascript·原型模式
问道飞鱼2 小时前
Java基础-单例模式的实现
java·开发语言·单例模式
dengqingrui1234 小时前
【树形DP】AT_dp_p Independent Set 题解
c++·学习·算法·深度优先·图论·dp
我的心永远是冰冰哒5 小时前
ad.concat()学习
学习
ZZZ_O^O5 小时前
二分查找算法——寻找旋转排序数组中的最小值&点名
数据结构·c++·学习·算法·二叉树
ok!ko5 小时前
设计模式之原型模式(通俗易懂--代码辅助理解【Java版】)
java·设计模式·原型模式
2402_857589366 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
吾爱星辰6 小时前
Kotlin 处理字符串和正则表达式(二十一)
java·开发语言·jvm·正则表达式·kotlin