MyBatis 开发手册 (一)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 这一遍看Mybatis的原因是怀念一下去年的 10月24号我写自己第一个项目时使用全配置文件版本的MyBatis,那时我们三个人刚刚大二,说实话,当时还是觉得MyBatis挺难玩的,但是今年再看最新版的Mybatis3.5.0, 还是挺有感觉的 Mybatis的官网一级棒...

Mybatis的核心组件及其生命周期#


SqlSessionFactoryBuider:#


作用: 构建器,根据配置信息生成SqlSessionFactory


生命周期: 这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但是最好还是不要让其一直存在,以保证所有的 XML 解析资源可以被释放给更重要的事情。


SqlSessionFactory#


作用: 生成sqlSession


生命周期: SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“bad smell”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式


SqlSession#


作用: 它表示一次sql的会话,即可以去执行sql返回结果,也可以获取为mapper生成的代理对象 ,支持事物,通过commit、rollback方法提交或者回滚事物


生命周期: 每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,要考虑 SqlSession 放在一个和 HTTP 请求对象相似的作用域中。 换句话说,每次收到的 HTTP 请求,就可以打开一个 SqlSession,返回一个响应,就关闭它。 这个关闭操作是很重要的,你应该把这个关闭操作放到 finally 块中以确保每次都能执行关闭。


SqlMapper#


作用: : MyBatis的映射器,现在大多数都使用java接口,早前使用配置文件来描述sql查询结果和java对象之间的映射规则 定义参数类型, 描述缓存,描述SQL语句 ,定义查询结果和POJO的映射关系


生命周期: 最好把映射器放在方法作用域内


基于XML版本的环境搭建测试#


基于xml版本,搭建mybatis开发环境中,存在一个主配置文件,和多个子配置文件,主配置文件中配置数据库相关的信息, 而子配置文件中配置的是单个Dao接口层中的抽象方法对应的sql语句


点击看官方文档XML全套配置信息


主配置文件如下


需要注意的地方,下面的<mapper >标签中resource属性存放的是从配置文件的路径,但是从配置文件的目录信息得和src中相应的接口位于相同的目录


<?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">
<!--mybatis的主配置文件-->
<configuration>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"/>
            <!--配置数据源-->
            <!--dataSource存在三个, 其中的POOLED池化的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/trymybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!--指定映射配置文件的位置,也就是针对每个Dao的配置文件的位置-->
    <!--下面指定的xml配置文件的路径,需要和src下IUserDao接口的目录保持一致-->
    <mappers>
        <mapper resource="com/changwu/dao/IUserDao.xml"/>
    </mappers>
</configuration>


从配置文件


需要注意的地方: 命名空间是全类名,id是方法名,返回值是全类名


还有一点就是,单个mapper标签中,namespace和id都不能少,两者合在一起才能确定一个全局唯一的方法,至于为什么我们配置一个接口就ok,而不用添加配置文件,那是因为Mybatis会使用代理技术,为接口生成代理对象,让程序员使用代理对象


<?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是全类名-->
<mapper namespace="com.changwu.dao.IUserDao">
    <!--
    id为方法名
    resultType为返回值个体的封装类
    -->
    <select id="findAll" resultType="com.changwu.pojo.User">
         select * from user
    </select>
</mapper>


其他数据源的配置方式


把如下的配置放在resourse目录下面


jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/trymybatis
jdbc.username=root
jdbc.password=root


然后将主配置文件改成下面这样


当然也可以在<properties>标签中使用url但是需要遵循url协议的规范


<?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">
<!--mybatis的主配置文件-->
<configuration>
    <properties resource="jdbcConfig.properties"> </properties>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"/>
            <!--配置数据源-->
            <!--dataSource存在三个, 其中的POOLED池化的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--指定映射配置文件的位置,也就是针对每个Dao的配置文件的位置-->
    <!--下面指定的xml配置文件的路径,需要和src下IUserDao接口的目录保持一致-->
    <mappers>
        <mapper class="com.changwu.dao.IUserDao"/>
    </mappers>
</configuration>


编码测试类


@Test
public void text01() {
    try {
        // 1. 读取配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
        // 2. 创建SqlSessionFactory工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        // 3. 创建sqlSession
        SqlSession sqlSession = factory.openSession();
        // 4. SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法
        // 使用正确描述每个语句的参数和返回值的接口(比如 BlogMapper.class),
        // 你现在不仅可以执行更清晰和类型安全的代码,而且还不用担心易错的字符串字面值以及强制类型转换
        IUserDao userDao = sqlSession.getMapper(IUserDao.class);
        // 5. 执行方法
        List<User> all = userDao.findAll();
        for (User user : all) {
            System.out.println(user.getUsername());
        }
        // 6, 释放资源
        sqlSession.close();
        resourceAsStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}


基于注解版本的环境搭建测试#


因为现在依然是MyBatis孤军深入,没有和Spring,Springboot等框架进行整合,因此上面说的那个主配置文件无论如果都不能缺失,不像SpringBoot那样一个@MapperScan("XXX")就完成扫描整合这么给力


基于注解的开发模式,我们可以轻易进一步去除单个dao层的接口对应的xml配置文件,取代之的是注解,三步:

  • 第一步: 删除原来的子配置文件的目录
  • 第二步: 在dao层接口使用注解开发


@Select("select * from user")
List<User> findAll();


  • 第三步: 修改部分主配置文件


<mappers>
    <mapper class="com.changwu.dao.IUserDao"/>
</mappers>


常用的注解#


  • @Results


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Results {
  // 因为当前的Results注解中存在实例的描述,使用id标识当前的map,实现给 @resultMap 的复用
  String id() default "";
  Result[] value() default {};
}


  • @Result

继续看看这个@Result注解,如下: 这个注解拥有xml中的resultMap中大部分的属性


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Result {
  boolean id() default false;
  // 表中的列名
  String column() default "";  
  // java实体类中的属性名
  String property() default "";
  // 实体类型
  Class<?> javaType() default void.class;
  JdbcType jdbcType() default JdbcType.UNDEFINED;
  Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class;
  // 实体之间的关系为1对1
  One one() default @One;
// 实体之间的关系为1对多
  Many many() default @Many;
}


  • @One

跟进@One注解, 他是对select属性的封装, FetchType是一个枚举,三种值,分别是LAZY, EAGER, DEFAULT


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface One {
  String select() default "";
  FetchType fetchType() default FetchType.DEFAULT;
}


  • @Many


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Many {
  String select() default "";
  FetchType fetchType() default FetchType.DEFAULT;
}


  • @ResultMap


@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ResultMap {
  String[] value();
}


类型别名#


原来在xml版本配置mapper时,会使用parameterType属性指定程序员提供的类的全类名,但是这个全类名真的太长了,于是MyBatis官方提供了给全类名取别名的标签,在Mybatis的主配置文件中添加如下的配置,如下:


<typeAliases>
  <typeAlias alias="user" type="com.changwu.pojo.User"/>
</typeAliases>


添加了全类名的配置之后,我们的在mapper中就可以使用别名了,如下: 并且在windows系统下不区分大小写


<update id="updateUser" parameterType="UsEr">
  update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id = #{id}"
</update>


但是像上面这样,为每一个POJO都添加上别名的配置,确实显得有点麻烦,于是可以像下面这样,为一整个包下面的类名配置别名, 别名就是类名不区分大小写的格式


<typeAliases>
  <package alias="user" type="com.changwu.pojo"/>
</typeAliases>


公共sql的抽取#


一处抽取,多处使用


<sql id="findUsers">
    select * form user;
</sql>
<select id="findAll" resultType="com.changwu.pojo.User">
    <include refid="findUsers"></include>
</select>


优先级#


MyBatis支持的3种配置方式, 编码>properties配置文件>property元素标签, 优先级如下:

  1. 在properties配置文件中指定的配置文件的属性首先被读取
  2. 根据配置文件中的resources属性读取类路径下的属性文件,或者根据url属性读取属性文件并会覆盖同名属性
  3. 读取作为方法参数传递的属性,并覆盖已经读取的同名属性


不要混合使用xml版和注解版两种开发模式,否则Mybatis启动不了




相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
XML 存储 Java
神了!阿里P8纯手写出了这份10W字的MyBatis技术原理实战开发手册
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录
99 0
|
SQL XML Java
MyBatis 开发手册 (二)
MyBatis 开发手册 (二)
224 0
|
SQL XML 缓存
MyBatis 开发手册 (三)
MyBatis 开发手册 (三)
167 0
|
2月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
146 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
2月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
76 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
2月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
514 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
2月前
|
SQL Java 数据库连接
mybatis使用二:springboot 整合 mybatis,创建开发环境
这篇文章介绍了如何在SpringBoot项目中整合Mybatis和MybatisGenerator,包括添加依赖、配置数据源、修改启动主类、编写Java代码,以及使用Postman进行接口测试。
27 0
mybatis使用二:springboot 整合 mybatis,创建开发环境
|
2月前
|
Java 数据库连接 API
springBoot:后端解决跨域&Mybatis-Plus&SwaggerUI&代码生成器 (四)
本文介绍了后端解决跨域问题的方法及Mybatis-Plus的配置与使用。首先通过创建`CorsConfig`类并设置相关参数来实现跨域请求处理。接着,详细描述了如何引入Mybatis-Plus插件,包括配置`MybatisPlusConfig`类、定义Mapper接口以及Service层。此外,还展示了如何配置分页查询功能,并引入SwaggerUI进行API文档生成。最后,提供了代码生成器的配置示例,帮助快速生成项目所需的基础代码。
159 1
|
3月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
2月前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
76 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学