Mybatis 框架使用指南(进阶)2

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: Mybatis 框架使用指南(进阶)2

嵌套查询(了解)


Mybatis嵌套查询 介绍:将多表查询的复杂sql语句拆分多个单表查询,再由mybatis框架进行嵌套组合


  • 优点:减少sql复杂性
  • 缺点:需要编写多次sql和多个配置,代码麻烦。故一般不推荐使用

简单示例:

* 需求:查询一个订单,与此同时查询出该订单所属的用户  1v1
# 关联查询
select * from orders o left join user u on o.uid=u.id where o.id=1;
# 嵌套查询 将一条sql语句能完成的事情拆分成多条单表查询去完成
#1 查询订单号为1的订单
#2 在根据查询的订单的uid去查用户表
#3 mybatis进行组装(映射文件中组装)因最终要返回的是订单 所以去订单映射文件中组装



一对一(多对一)

需求:查询一个订单,与此同时查询出该订单所属的用户

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="cn.test.mapper.OrdersMapper">
    <resultMap id="ordersResultMap" type="orders">
        <id column="id" property="id"></id>
        <result column="ordertime" property="ordertime"></result>
        <result column="address" property="address"></result>
        <!--mybatis框架嵌套查询(一对一映射)
                association标签
                    property:要封装的对象属性名
                    select:数据来源的方法名
                    column:方法需要的参数(uid)
        -->
        <association property="user" select="cn.test.mapper.UserMapper.findUserById" 
                     column="uid">
        </association>
    </resultMap>
    <!-- 查询当前订单 -->
    <select id="findOrderById" parameterType="int" resultMap="ordersResultMap">
        select * from orders where id=#{id}
    </select>
</mapper>
<?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="cn.test.mapper.UserMapper">
    <!-- 查询当前用户 -->
    <select id="findUserByUId" parameterType="int" resultType="user">
        select * from user where id=#{id}
    </select>
</mapper>



一对多

需求:查询一个用户,与此同时查询出该用户具有的订单

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="cn.test.mapper.UserMapper">
    <resultMap id="userResultMap" type="user">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="address" property="address"></result>
        <!-- 嵌套查询(一对多的映射)
                collection标签
                    property;要封装的对象集合属性
                    ofType:泛型类型
            select:数据的来源方法  
            column:方法需要的参数数据(用户的id) 
        -->
        <collection property="orders" ofType="Orders" select="cn.test.mapper.OrdersMapper.findBylist" 
                    column="id">
        </collection>
    <!-- 查询当前用户 -->
    </resultMap>
    <select id="findUserById" parameterType="int" resultMap="userResultMap">
        select * from user where id=#{id}
    </select>
</mapper>
<?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="cn.test.mapper.OrdersMapper">
    <!--查询多个订单-->
    <select id="findBylist" parameterType="int" resultType="Orders">
        select * from orders where uid=#{id}
    </select>
</mapper>



多对多(由二个一对多组成)

需求:查询用户同时查询出该用户的所有角色

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="cn.test.mapper.UserMapper">
    <resultMap id="userResultMap" type="user">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="address" property="address"></result>
        <!-- 嵌套查询(一对多的映射)
                collection标签
                    property;要封装的对象集合属性
                    ofType:泛型类型
                    select:数据的来源方法  
           column:方法需要的参数数据(用户的id)
        -->
        <collection property="roleList" ofType="role" select="cn.test.mapper.RoleMapper.findRoles" 
                    column="id">
        </collection>
    </resultMap>
    <!--查询当前用户-->
    <select id="findUserById" parameterType="int" resultMap="userResultMap">
        select * from user where id=#{id}
    </select>
</mapper>
<?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="cn.test.mapper.RoleMapper">
    <resultMap id="RoleResultMap" type="role">
        <id column="id" property="id"></id>
        <result column="role_name" property="roleName"></result>
        <result column="role_desc" property="roleDesc"></result>
    </resultMap>
    <!--查询当前用户的角色-->
    <select id="findRoles" resultMap="RoleResultMap" parameterType="int">
        SELECT * FROM user_role ur INNER JOIN role r ON ur.rid=r.id WHERE ur.uid=#{id}
    </select>
</mapper>



调用存储过程

参考:MyBatis 调用存储过程(详解)


在mapper文件中可以使用statementType标记使用什么的对象操作SQL语句。


statementType:标记操作SQL的对象


取值说明:

   STATEMENT:直接操作sql,不进行预编译,获取数据。$—Statement

   PREPARED:预处理,参数,进行预编译,获取数据。#—PreparedStatement。默认

   CALLABLE:执行存储过程。CallableStatement


示例:

  1. 创建insert_user存储过程(MySql)
CREATE PROCEDURE insert_user(OUT u_id INTEGER,IN u_name VARCHAR(20),IN u_sex VARCHAR(20),IN u_age INTEGER)
BEGIN
INSERT INTO t_user (name,sex,age) VALUES (u_name,u_sex,u_age);
SET u_id=LAST_INSERT_ID();
END


在UserMapper.xml中调用insert_user存储过程

<!-- 添加用户 -->
<insert id="addUser" parameterType="com.po.User" statementType="CALLABLE">
    {call insert_user(#{id,mode=OUT,jdbcType=INTEGER},#{name,mode=IN},#{sex,mode=IN},#{age,mode=IN})}
</insert>


2.创建deleteUser存储过程(MySql)

CREATE PROCEDURE deleteUser(IN u_id INTEGER)
BEGIN
   DELETE FROM t_user WHERE id=u_id;
END

在UserMapper.xml中调用deleteUser存储过程

<!-- 删除用户 -->
<delete id="deleteUser" parameterType="Integer" statementType="CALLABLE">
    {call deleteUser(#{id,mode=IN})}
</delete>



3.创建updateUser存储过程(MySql)

CREATE PROCEDURE updateUser(IN u_id INTEGER,IN u_name VARCHAR(20),IN u_sex VARCHAR(20),IN u_age INTEGER)
BEGIN
    UPDATE t_user SET name=u_name,sex=u_sex,age=u_age WHERE id=u_id;
END


在UserMapper.xml中调用updateUser存储过程

<!-- 更新用户 -->
<update id="updateUser" parameterType="user" statementType="CALLABLE">
    {call updateUser(#{id,mode=IN},#{name,mode=IN},#{sex,mode=IN},#{age,mode=IN})}
</update>


4.创建getUserById存储过程(MySql)

CREATE PROCEDURE getUserById(IN u_id INTEGER)
BEGIN
    SELECT id,name,sex,age FROM t_user WHERE id=u_id;
END


在UserMapper.xml中调用getUserById存储过程

<!-- 根据id查询用户 -->
<select id="getUserById" parameterType="Integer" resultType="user" statementType="CALLABLE">
    {call getUserById(#{id,mode=IN})}
</select>




拓展了解

Mybatis 核心文件概述



1)environments标签

数据库环境配置



 1.  其中,事务管理器(transactionManager)类型有两种:


   JDBC:

   这个配置就是直接使用了JDBC 的提交和回滚设置,由mybatis自己手动控制事务


   MANAGED:

   这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。

   例如:mybatis与spring整合后,事务交给spring容器管理。


2.    其中,数据源(dataSource)常用类型有二种:


   UNPOOLED:

   这个数据源的实现只是每次被请求时打开和关闭连接。


   POOLED:

   这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。使用的是mybatis自带的


2)properties标签

第三方属性配置

实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件

   <properties resource="jdbc.properties"></properties> 
   <environments default="mysql">
        <!--mysql数据库环境-->
        <environment id="mysql">
            <!-- 使用JDBC类型事务管理器 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 数据源(连接池)配置  POOLED-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"></property>
                <property name="url" value="${jdbc.url}"></property>
                <property name="username" value="${jdbc.username}"></property>
                <property name="password" value="${jdbc.password}"></property>
            </dataSource>
        </environment>
    </environments>



3)typeAliases标签

实体类型别名配置

  <typeAliases>
        <!--指定一个实体类和对应的别名-->
        <!--<typeAlias type="com.test.domain.User" alias="user"></typeAlias>-->
        <!--指定当前包下所有的实体设置别名  默认: 别名(类名) -->
        <package name="com.test.domain"></package>
    </typeAliases>

394b79c9b16a400da863592cbe7fcec9.png


4)mappers标签

映射关系配置(加载映射配置文件)

<!-- 加载指定的src目录下的映射文件 -->
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>



核心配置文件标签顺序




Mybatis 的 API 概述


1)Resources

专门用于加载mybatis核心配置文件,返回的 io流

InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");



2)SqlSessionFactoryBuilder

专门用于生产SqlSessionFactory工厂对象

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);



3)SqlSessionFactory

一个项目只有一个工厂对象,生产sqlSession对象

// 需要手动提交事务,DML语句才会持久化到数据库中
SqlSession openSession(); // 【推荐】
// 设置是否开启自动提交,如果设置为true,开启自动提交事务
SqlSession openSession(boolean autoCommit);
  参数说明
    true:每一条DML类型语句都会自动提交事务
    false(默认值):需要手动提交事务



4)SqlSession

是mybatis核心对象,可以对数据库进行CRUD基本操作

//  方法
<T> T selectOne(String statement, Object parameter);
<E> List<E> selectList(String statement, Object parameter);
int insert(String statement, Object parameter);
int update(String statement, Object parameter);
int delete(String statement, Object parameter);
// 事务
void commit();
void rollback();




MyBatis 延迟加载(懒加载)


Mybatis的延迟加载是针对嵌套查询而言的,是指在进行查询的时候先只查询最外层的SQL,对于内层SQL将在需要使用的时候才查询出来。


使用延迟加载的场景:一对多、多对多

不推荐使用延迟加载的场景:一对一(使用 立即加载)

特别注意:延迟加载是基于 嵌套查询 组合使用

1)局部延迟加载

* 需要手动在每一个select相关标签中单独配置
  <association>、<collection>
    fetchType="lazy"  懒加载
    fetchType="eager" 立即加载


2)全局延迟加载

lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载,特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。默认值为false。

  <!-- 在核心配置文件SqlMapConfig.xml,设置全局参数 -->
    <settings>
        <!--开启懒加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
    </settings>


若是pringboot集成,在yaml配置文件中配置开启延迟加载。

mybatis:
  configuration:
    lazy-loading-enabled: true    #开启延时加载开关


注意:如果全局配置了延迟加载,那么一对一也会起作用

可以为一对一设置局部的立即加载,因为局部优先级高于全局延迟加载

<association property="user" javaType="User" column="uid" select="com.itheima.mapper.UserMapper.findById" 
             fetchType="eager"> 
</association>


3)指定触发延迟加载的方法配置

lazyLoadTriggerMethods 默认情况下仅仅支持自动将 equals,clone,hashCode,toString 这几个方法定义为延迟加载的加载触发方法。

* 在SqlMapConfig.xml核心配置文件,设置全局参数
  <settings>
    <!-- 如果将 Person 的 doLazyLoadingNow()方法加入这个列表中,
       则调用 doLazyLoadingNow()方法将会导致 Person 上的所有延迟加载属性的关联对象被执行加载。 -->
    <setting name="lazyLoadTriggerMethods" value="doLazyLoadingNow,equals,clone,hashCode,toString"/>
  </settings>


若是springboot集成,在yaml配置文件中配置

mybatis:
  configuration:
    lazy-loading-enabled: true    # 开启延时加载开关
    aggressive-lazy-loading: false  # 将积极加载改为消极加载(即按需加载),默认值就是false
    # 指定触发延迟加载的方法
    lazy-load-trigger-methods: "doLazyLoadingNow,equals,clone,hashCode,toString"
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
SQL XML Java
33 0
|
1月前
|
SQL Java 数据库连接
区分iBatis与MyBatis:两个Java数据库框架的比较
总结起来:虽然从技术角度看,iBATIS已经停止更新但仍然可用;然而考虑到长期项目健康度及未来可能需求变化情况下MYBATISS无疑会是一个更佳选择因其具备良好生命周期管理机制同时也因为社区力量背书确保问题修复新特征添加速度快捷有效.
80 12
|
2月前
|
SQL XML Java
MyBatis框架如何处理字符串相等的判断条件。
总的来说,MyBatis框架提供了灵活而强大的机制来处理SQL语句中的字符串相等判断条件。无论是简单的等值判断,还是复杂的条件逻辑,MyBatis都能通过其标签和属性来实现,使得动态SQL的编写既安全又高效。
154 0
|
7月前
|
Oracle 关系型数据库 Java
|
7月前
|
SQL 缓存 Java
框架源码私享笔记(02)Mybatis核心框架原理 | 一条SQL透析核心组件功能特性
本文详细解构了MyBatis的工作机制,包括解析配置、创建连接、执行SQL、结果封装和关闭连接等步骤。文章还介绍了MyBatis的五大核心功能特性:支持动态SQL、缓存机制(一级和二级缓存)、插件扩展、延迟加载和SQL注解,帮助读者深入了解其高效灵活的设计理念。
|
9月前
|
SQL Java 数据库连接
对Spring、SpringMVC、MyBatis框架的介绍与解释
Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
388 29
|
11月前
|
SQL Java 数据库连接
持久层框架MyBatisPlus
持久层框架MyBatisPlus
213 1
持久层框架MyBatisPlus
|
12月前
|
缓存 Cloud Native 安全
探索阿里巴巴新型ORM框架:超越MybatisPlus?
【10月更文挑战第9天】在Java开发领域,Mybatis及其增强工具MybatisPlus长期占据着ORM(对象关系映射)技术的主导地位。然而,随着技术的发展,阿里巴巴集团推出了一种新型ORM框架,旨在提供更高效、更简洁的开发体验。本文将对这一新型ORM框架进行探索,分析其特性,并与MybatisPlus进行比较。
399 0
|
SQL Java 数据库连接
【Java 第十三篇章】MyBatis 框架介绍
MyBatis 原名 iBATIS,2001 年由 Clinton Begin 创建,以其简易灵活著称。2010 年更名以重塑品牌形象。MyBatis 通过 SQL 映射文件将 SQL 语句与 Java 代码分离,支持编写原生 SQL 并与方法映射。具备对象关系映射功能,简化数据库记录处理。支持动态 SQL 构建,灵活应对不同查询条件。内置缓存机制,提升查询效率。相比全功能 ORM,MyBatis 提供更高 SQL 控制度和更好的维护性,并易于与 Spring 等框架集成,广泛应用于 Java 数据访问层。
196 0
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】