Mybatis快速入门

Mybatis

  • [Mybatis 简介](#Mybatis 简介)
  • [1.Mybatis 基础使用](#1.Mybatis 基础使用)
    • [1.1 安装依赖](#1.1 安装依赖)
    • [1.2 从 XML 中构建 SqlSessionFactory](#1.2 从 XML 中构建 SqlSessionFactory)
    • [1.3 从 SqlSessionFactory 中获取 SqlSession 执行sql](#1.3 从 SqlSessionFactory 中获取 SqlSession 执行sql)
  • [2.基于 Spring Boot 使用 Mybatis](#2.基于 Spring Boot 使用 Mybatis)
    • [2.1 创建 Spring Boot demo 项目](#2.1 创建 Spring Boot demo 项目)
    • [2.2 编写相关代码](#2.2 编写相关代码)
  • [3.Mybatis 增删改查](#3.Mybatis 增删改查)
    • [3.1 查(select)](#3.1 查(select))
    • [3.2 增](#3.2 增)
    • [3.3 删](#3.3 删)
    • [3.4 改](#3.4 改)
  • [4. 动态SQL](#4. 动态SQL)
    • [4.1 if](#4.1 if)
    • [4.2 choose、when、otherwise 标签](#4.2 choose、when、otherwise 标签)
    • [4.3 foreach 标签](#4.3 foreach 标签)
    • [4.4 where trim set](#4.4 where trim set)

Mybatis 简介

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

1.Mybatis 基础使用

1.1 安装依赖

xml 复制代码
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.2.1</version>
</dependency>

1.2 从 XML 中构建 SqlSessionFactory

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例

java 复制代码
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

XML 配置文件中包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)。

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
     <!-- <environments>元素定义了应用程序的不同环境。default属性指定了默认环境,本例中设置为"development"。 -->
    <environments default="development">
         <!-- 在<environments>元素内部,<environment>元素用于定义具体的环境,这里只有一个名为"development"的环境。 -->
        <environment id="development">
            <!-- 指定事务管理器 还有 JTA(Java Transaction API)事务管理器等 -->
            <transactionManager type="JDBC"/>
            <!-- <dataSource>元素定义数据源,类型为"POOLED",表示使用连接池。-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="120125hzy."/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--<mappers>元素用于配置MyBatis的映射器(mapper)。-->
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

1.3 从 SqlSessionFactory 中获取 SqlSession 执行sql

既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。

创建 UserMapper.java

java 复制代码
public interface UserMapper {
    // @Param 是 MyBatis 中用于给方法参数起别名的注解。这个注解主要用于在 XML 映射文件中引用参数时,提供一个明确的名称。
    User selectUser(@Param("id") int id);
}

创建 UserMapper.xml

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="com.hzy.mybatis.UserMapper">
    <select id="selectUser" resultType="com.hzy.mybatis.User">
        select * from user where id=${id}
    </select>
</mapper>

UserMapper.java 与 UserMapper.xml 是一一对应的

获取 SqlSession 执行sql

java 复制代码
    public static void main(String[] args) throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = mapper.selectUser(1);
            System.out.println(user);
        }
    }

上篇文章 讲的 JDBC 的操作流程:

txt 复制代码
1. 创建数据库连接池 DataSource
2. 通过 DataSource 获取数据库连接 Connection
3. 编写要执行带 ? 占位符的 SQL 语句
4. 通过 Connection 及 SQL 创建操作命令对象 Statement
5. 替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值
6. 使⽤ Statement 执行 SQL 语句
7. 查询操作:返回结果集 ResultSet,更新操作:返回更新的数量
8. 处理结果集
9. 释放资源

相比,Mybatis 简单了许多,但还是要手动配置一些核心组件如如 SqlSessionFactoryDataSourceTransactionManager 等。

所以我们一般基于 SpringBoot 使用 Mybatis 来简化开发。

2.基于 Spring Boot 使用 Mybatis

Spring Boot 是一个现代的、约定大于配置的框架,通过 Spring Boot 的自动配置和约定来简化整体架构,大大减少了手动配置的需求,提高了开发效率。

在 Spring Boot 中,只需在配置文件中指定数据库连接等少量信息,Spring Boot 将会根据约定自动配置 MyBatis 相关组件,包括创建 SqlSessionFactoryDataSourceTransactionManager 等。

2.1 创建 Spring Boot demo 项目

选择数据库修改依赖

2.2 编写相关代码

配置文件

yml 复制代码
Spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: 120125hzy.
    type:  com.alibaba.druid.pool.DruidDataSource
mybatis:
 type-aliases-package: com.hzy.demo.pojos # 指定MyBatis实体类的包路径,使得在XML文件中可以直接使用类名而不是全限定名。
 configuration:
   log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 日志
   map-underscore-to-camel-case: true #  将数据库字段的下划线命名方式映射为Java驼峰命名方式
   

pojos.User

java 复制代码
@Data
public class User {
    private int id;
    private String name;
    private Double balance;
    private String homeAddr;
}

mapper.UserMapper

java 复制代码
@Mapper
public interface UserMapper {
    User selectUser(@Param("id") int id);
}

UserMapper.xml

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="com.hzy.demo.mapper.UserMapper">
    <!--resultType="User" 这里不需要写全限定名。-->
    <select id="selectUser" resultType="User">
        select * from user2 where id=${id}
    </select>
</mapper>

测试代码

java 复制代码
	@Test
	void test01(){
		User user = userMapper.selectUser(1);
		System.out.println(user);
	}

当前的目录结构

需要注意的是 UserMapper 和 UserMapper.xml 文件的路径要相同,不同会报错

或者在配置文件中指定 Mapper.xml 文件的目录

yml 复制代码
mybatis:
  mapper-locations: classpath:/mybatis/mappers/*.xml

3.Mybatis 增删改查

3.1 查(select)

MyBatis 使用 <select> 元素来定义查询语句。查询可以返回单个实体对象、集合对象或基本类型的值。

xml 复制代码
<!-- User selectUser(@Param("id") int id); -->
<select id="selectUser" parameterType="int" resultType="User">
    select * from user2 where id=${id}
</select>

selectUser 是查询语句的唯一标识符,parameterType 指定了传递给查询的参数类型,resultType 指定了查询结果的返回类型。

对于简单 sql 语句可以直接使用@Select() 注解实现

java 复制代码
    @Select("select * from user2 where id=${id}")
    User selectUser(@Param("id") int id);

测试

java 复制代码
	@Test
	void test01(){
		User user = userMapper.selectUser(1);
		System.out.println(user);
	}

3.2 增

MyBatis 使用 <insert> 元素来定义插入语句。

xml 复制代码
    <!-- int addUser(User user); -->
	<insert id="addUser" parameterType="User">
        insert into user2(name,balance,home_addr) values(#{name},#{balance},#{homeAddr})
    </insert>

insertUser 是插入语句的唯一标识符,parameterType 指定了传递给插入语句的参数类型,name,balance,homeAddr是 User 的属性

同样也可以使用@Insert()注解实现:

java 复制代码
    @Insert("insert into user2(name,balance,home_addr) values(#{name},#{balance},#{homeAddr})")
    int addUser(User user);

测试

java 复制代码
	@Test
	void test03(){
		User user = new User();
		user.setName("李四");
		user.setBalance(1200.0);
		user.setHomeAddr("cq");
		int i = userMapper.addUser(user);
		assert i == 1;
	}

3.3 删

MyBatis 使用 <delete> 元素来定义删除语句。

xml 复制代码
<!-- int removeUserById(@Param("id") int id); -->    
	<delete id="removeUserById" parameterType="int">
        delete from user2 where id = #{id}
    </delete>

MyBatis 使用 <delete> 元素来定义删除语句。

同样也可以使用@Insert()注解实现:

java 复制代码
@Delete("delete from user2 where id = #{id}")
int removeUserById(@Param("id") int id);

测试

java 复制代码
	@Test
	void test04(){
		int i = userMapper.removeUserById(4);
		assert i == 1;
	}

3.4 改

MyBatis 使用 <update> 元素来定义更新语句。

xml 复制代码
	<!--int updateUserById(User user);-->
	<update id="updateUserById" parameterType="User">
        update user2 set name=#{name},balance=#{balance},home_addr=#{homeAddr} where id = #{id}
    </update>

同样使用@Update()注解也行

java 复制代码
	@Update("update user2 set name=#{name},balance=#{balance},home_addr=#{homeAddr} where id = #{id}")
    int updateUserById(User user);

测试

java 复制代码
	@Test
	void test05(){
		User user = new User();
		user.setId(4);
		user.setName("哈哈哈");
		user.setBalance(1000.0);
		user.setHomeAddr("sh");
		int i = userMapper.updateUserById(user);
		assert i == 1;
	}

因为前面已经删除id为4的数据所以这里断言未通过

4. 动态SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

4.1 if

判断一个参数是否有值的,如果没值,那么就会隐藏 if 中的 sql

xml 复制代码
    <!-- List<User> selectUsers(@Param("id") Integer id); -->
   	<select id="selectUsers" resultType="User">
        select * from user2
        <if test="id != null">
            where id=#{id}
        </if>
    </select>

测试

java 复制代码
	@Test
	void test06(){
		List<User> users = userMapper.selectUsers(null);
		for(User user: users){
			System.out.println(user);
		}
	}

通常情况下 if 标签会和 where 标签一起用,不然有可能出现 select * from user2 where 这样的语句。

xml 复制代码
	<!--List<User> selectUsers(User user);-->    
	<select id="selectUsers" resultType="User">
        select * from user2
        <where>
            <if test="name != null and name != '' ">
                and name like concat('%',#{name},'%')
            </if>
            <if test="homeAddr != null and homeAddr != '' ">
                and home_addr = #{homeAddr}
            </if>
        </where>
    </select>

测试

java 复制代码
	@Test
	void test06(){
		User user = new User();
		List<User> users = userMapper.selectUsers(user);
		for(User u: users){
			System.out.println(u);
		}
		System.out.println("不带参查询");

		user.setName("s");
		user.setHomeAddr("sh");
		users = userMapper.selectUsers(user);
		for(User u: users){
			System.out.println(u);
		}
		System.out.println("带参查询");
	}

4.2 choose、when、otherwise 标签

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

xml 复制代码
<!--List<User> selectUsers(User user);-->    
    <select id="selectUsers" resultType="User">
        select * from user2 where
        <choose>
            <when test="name != null and name != '' ">
                 name like concat('%',#{name},'%')
            </when>
            <when  test="homeAddr != null and homeAddr != '' ">
                 home_addr = #{homeAddr}
            </when>
            <otherwise>
                id = 1
            </otherwise>
        </choose>
    </select>

测试

java 复制代码
	@Test
	void test06(){
		User user = new User();
		List<User> users = userMapper.selectUsers(user);
		for(User u: users){
			System.out.println(u);
		}
		System.out.println("不带参查询");

		user.setName("s");
		user.setHomeAddr("sh");
		users = userMapper.selectUsers(user);
		for(User u: users){
			System.out.println(u);
		}
		System.out.println("带参查询");
	}

虽然传入两个参数只生效了一个参数

4.3 foreach 标签

<foreach> 元素用于迭代集合或数组,动态生成 SQL 片段。这在处理 IN 子句中的多个参数时非常有用。

java 复制代码
// 批量删除
int removeUserByIds(@Param("ids") List<Integer> ids); 
xml 复制代码
    <delete id="removeUserByIds">
        delete 
        from user2
        where id in
        <foreach collection="ids" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>        
    </delete>

foreach 标签中主要属性介绍:

txt 复制代码
collection:绑定方法参数中的集合,如List, Set, Map或数组对象
item:遍历时的每一个对象
open:语句块开头的字符串
close:语句块结束的字符串
separator:每次遍历之间间隔的字符串

测试

java 复制代码
	@Test
	void test07(){
		int i = userMapper.removeUserByIds(Arrays.asList(3,5,6));
		assert i == 3;
	}

4.4 where trim set

trim

<trim>标签:<trim>标签用于处理字符串拼接时可能出现的空格问题。它包含了四个属性:prefixsuffixprefixOverridessuffixOverrides,用于在SQL语句的拼接时添加前缀、后缀,或者移除多余的前缀、后缀。

修改前面的修改语句

xml 复制代码
    <update id="updateUserById" parameterType="User">
        update user2
        <trim prefix="SET" suffixOverrides=",">
            <if test="name != null" >
               name = #{name},
            </if>
            <if test=" balance != null">
                balance = #{balance},
            </if>
            <if test="home_addr != null">
                home_addr = #{homeAddr},
            </if>
        </trim>
        where id = #{id}
    </update>

在上述例子中,<trim>标签用于处理SET关键字后可能出现的多余逗号。

set

<set>标签:<set>标签用于处理UPDATE语句中SET关键字后可能出现的多余逗号,并且可以灵活地处理更新字段。

xml 复制代码
    <update id="updateUserById" parameterType="User">
        update user2
        <set>
            <if test="name != null" >
               name = #{name},
            </if>
            <if test=" balance != null">
                balance = #{balance},
            </if>
            <if test="home_addr != null">
                home_addr = #{homeAddr},
            </if>
        </set>
        where id = #{id}
    </update>

这个和语句和上面 <trim> 标签实现的功能一样,区别在于使用<trim>标签,手动指定了SET关键字和可能的多余逗号的处理方式。

<set>标签,它自动处理了SET关键字后可能出现的多余逗号,确保生成的SQL语句是合法的。

两者相比<set>标签更直观,而<trim>标签更加灵活,允许你手动指定前缀和后缀。

where

<where>标签:<where>标签用于将WHERE关键字加到SQL语句中,并且能够智能处理条件语句的连接。如果条件语句中的第一个条件是AND或OR,<where>标签会自动将其去除。

前面提到过。

相关推荐
drebander19 分钟前
使用 Java Stream 优雅实现List 转化为Map<key,Map<key,value>>
java·python·list
乌啼霜满天24923 分钟前
Spring 与 Spring MVC 与 Spring Boot三者之间的区别与联系
java·spring boot·spring·mvc
tangliang_cn28 分钟前
java入门 自定义springboot starter
java·开发语言·spring boot
程序猿阿伟29 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
Grey_fantasy39 分钟前
高级编程之结构化代码
java·spring boot·spring cloud
弗锐土豆1 小时前
工业生产安全-安全帽第二篇-用java语言看看opencv实现的目标检测使用过程
java·opencv·安全·检测·面部
Elaine2023911 小时前
零碎04 MybatisPlus自定义模版生成代码
java·spring·mybatis
小小大侠客1 小时前
IText创建加盖公章的pdf文件并生成压缩文件
java·pdf·itext
一二小选手1 小时前
【MyBatis】全局配置文件—mybatis.xml 创建xml模板
xml·java·mybatis
猿java1 小时前
Linux Shell和Shell脚本详解!
java·linux·shell