Mybatis 简介

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

1.Mybatis 基础使用

1.1 安装依赖

<dependency>
  <groupId>org.mybatis</groupId>
  &lt;artifactId&gt;mybatis</artifactId>
  <version>3.2.1</version>
</dependency>

1.2 从 XML 中构建 SqlSessionFactory

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

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

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

<?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

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

创建 UserMapper.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

    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 的操作流程

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 编写相关代码

配置文件

Spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&amp;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

@Data
public class User {
    private int id;
    private String name;
    private Double balance;
    private String homeAddr;
}

mapper.UserMapper

@Mapper
public interface UserMapper {
    User selectUser(@Param("id") int id);
}

UserMapper.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>

测试代码

	@Test
	void test01(){
		User user = userMapper.selectUser(1);
		System.out.println(user);
	}

在这里插入图片描述

当前目录结构

在这里插入图片描述

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

在这里插入图片描述

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

mybatis:
  mapper-locations: classpath:/mybatis/mappers/*.xml

在这里插入图片描述

3.Mybatis 增删改查

3.1 查(select)

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

<!-- 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() 注解实现

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

测试

	@Test
	void test01(){
		User user = userMapper.selectUser(1);
		System.out.println(user);
	}

在这里插入图片描述

3.2 增

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

    <!-- 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()注解实现

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

测试

	@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> 元素来定义删除语句。

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

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

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

@Delete("delete from user2 where id = #{id}")
int removeUserById(@Param("id") int id);

测试

	@Test
	void test04(){
		int i = userMapper.removeUserById(4);
		assert i == 1;
	}

在这里插入图片描述

3.4 改

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

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

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

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

测试

	@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

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

测试

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

在这里插入图片描述

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

	<!--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>

测试

	@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 语句。

<!--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>

测试

	@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 子句中的多个参数时非常有用。

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

foreach 标签中主要属性介绍

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

测试

	@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语句的拼接添加前缀后缀,或者移除多余的前缀后缀

修改前面修改语句

    <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关键字后可能出现的多余逗号,并且可以灵活地处理更新字段

    <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>标签会自动将其去除。

前面提到过。

原文地址:https://blog.csdn.net/zxwyhzy/article/details/134745887

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_23216.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除!

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注