MyBatis:开源、轻量级的数据长期化框架

[复制链接]
发表于 2025-4-8 16:55:44 | 显示全部楼层 |阅读模式
什么是Mybatis

   MyBatis是什么 - Mybatis教程 - 菜鸟教程:
          MyBatis 是一个开源、轻量级的数据长期化框架,是 JDBC 和 Hibernate 的更换方案。MyBatis 内部封装了 JDBC,简化了加载驱动、创建连接、创建 statement 等繁杂的过程,开辟者只需要关注 SQL 语句自己。
          MyBatis 支持定制化 SQL、存储过程以及高级映射,可以在实体类和 SQL 语句之间建立映射关系,是一种半自动化的 ORM 实现。其封装性低于 Hibernate,但性能优秀、小巧、简朴易学、应用广泛。
          MyBatis是一个优秀的半自动化长期层框架,简化了数据的操纵,同时又保留了对SQL的高度自定义,兼容了机动性和易用性,便于我们的开辟。
什么是ORM

        ORM(Object Relational Mapping,对象关系映射)是一种编程技能,用于在关系型数据库和面向对象编程语言之间建立桥梁,通过自动化的数据转换机制,实现数据库记录与程序对象的双向映射。
        我们的项目中大概会存在大量的CRUD的重复性的SQL,如果每个都需要自己写的话会非常浪费时间且意义不大。通过采用ORM技能。自动生成基础的CRUD SQL,可以减少大量重复性代码。ORM还实现了程序对象与数据库对象的数据映射,消除了因为关系模子和对象模子产生的结构化题目。
常见的ORM框架对比

  框架
  MyBatis
  Hibernate
  JPA (规范)
  DjangoORM
  控制级别
  半自动(手动SQL)
  全自动
  接口规范
  全自动
  查询方式
  XML/注解SQL
  HQL/Criteria
  JPQL
  ORM API
  性能优化
  高(直接控SQL)
  中(二级缓存)
  依靠实现
  中
  学习曲线
  中等
  高
  中等
  低
  典范应用
  电商/金融体系
  企业级背景
  Java EE 体系
  Python Web 应用
  
MyBatis的焦点对象



  • SqlSessionFactoryBuilder:解析设置,创建SqlSessionFactory;临时对象,构建完Factory后烧毁。
  • SqlSessionFactory:生产SqlSession的工程;单例模式,随着启动创建,关闭时烧毁。
  • SqlSession:会话对象,实行CRUD操纵、事务控制、获取Mapper接口。
  • Executor:实行SQL语句的焦点处理器。

    • Executor.query 实行流程:查抄一级缓存 - 未掷中则查询数据库 - 通过StatementHandler实行SQL - 通过ResultSetHandler处理结果。



MyBatis的焦点设置

        MyBatis的焦点设置文件由两部分组成,分别是全局设置文件 mybatis-config.xml 喝 Mapper xml文件组成。
全局设置文件

        代码中附有具体注释,根据自己的需求修改即可。
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  3.   "http://mybatis.org/dtd/mybatis-3-config.dtd">
  4. <configuration>
  5.     <!-- ===================== 1. 全局属性配置 ===================== -->
  6.     <!-- 加载外部属性文件,优先级:property标签 > resource属性 > 系统属性 -->
  7.     <properties resource="jdbc.properties">
  8.         <!-- 可在此覆盖外部文件的属性 -->
  9.         <property name="jdbc.username" value="root"/>
  10.     </properties>
  11.     <!-- ===================== 2. 全局设置 ===================== -->
  12.     <settings>
  13.         <!-- 开启自动驼峰命名映射(下划线转驼峰) -->
  14.         <setting name="mapUnderscoreToCamelCase" value="true"/>
  15.         
  16.         <!-- 启用二级缓存(默认true,建议显式声明) -->
  17.         <setting name="cacheEnabled" value="true"/>
  18.         
  19.         <!-- 配置JDBC的NULL值处理(Oracle需设为NULL) -->
  20.         <setting name="jdbcTypeForNull" value="NULL"/>
  21.         
  22.         <!-- 延迟加载的触发方法(默认equals,clone,hashCode,toString) -->
  23.         <setting name="lazyLoadTriggerMethods" value=""/>
  24.         
  25.         <!-- 日志日志实现(可选SLF4J | LOG4J | LOG4J2 | JDK_LOGGING等) -->
  26.         <setting name="logImpl" value="SLF4J"/>
  27.     </settings>
  28.     <!-- ===================== 3. 类型别名 ===================== -->
  29.     <typeAliases>
  30.         <!-- 为单个类定义别名 -->
  31.         <typeAlias type="com.example.model.User" alias="User"/>
  32.         
  33.         <!-- 扫描包,自动将类名首字母小写作为别名 -->
  34.         <package name="com.example.model"/>
  35.     </typeAliases>
  36.     <!-- ===================== 4. 类型处理器 ===================== -->
  37.     <typeHandlers>
  38.         <!-- 自定义枚举处理器 -->
  39.         <typeHandler handler="com.example.handler.EnumTypeHandler"
  40.                      javaType="com.example.enums.StatusEnum"/>
  41.         
  42.         <!-- 注册包下的所有处理器 -->
  43.         <package name="com.example.handler"/>
  44.     </typeHandlers>
  45.     <!-- ===================== 5. 插件配置 ===================== -->
  46.     <plugins>
  47.         <!-- MyBatis分页插件PageHelper -->
  48.         <plugin interceptor="com.github.pagehelper.PageInterceptor">
  49.             <property name="helperDialect" value="mysql"/>
  50.             <property name="reasonable" value="true"/>
  51.         </plugin>
  52.         
  53.         <!-- SQL执行时间统计插件 -->
  54.         <plugin interceptor="com.example.plugin.SqlCostInterceptor"/>
  55.     </plugins>
  56.     <!-- ===================== 6. 数据库环境配置 ===================== -->
  57.     <!-- 默认使用环境ID -->
  58.     <environments default="development">
  59.         <!-- 开发环境 -->
  60.         <environment id="development">
  61.             <!-- 事务管理器类型:JDBC(支持事务)或MANAGED(容器管理) -->
  62.             <transactionManager type="JDBC"/>
  63.             
  64.             <!-- 数据源类型:POOLED(连接池)、UNPOOLED、JNDI -->
  65.             <dataSource type="POOLED">
  66.                 <property name="driver" value="${jdbc.driver}"/>
  67.                 <property name="url" value="${jdbc.url}"/>
  68.                 <property name="username" value="${jdbc.username}"/>
  69.                 <property name="password" value="${jdbc.password}"/>
  70.                 <!-- 连接池配置 -->
  71.                 <property name="poolMaximumActiveConnections" value="20"/>
  72.                 <property name="poolMaximumIdleConnections" value="5"/>
  73.             </dataSource>
  74.         </environment>
  75.         <!-- 生产环境(多环境示例) -->
  76.         <environment id="production">
  77.             <transactionManager type="JDBC"/>
  78.             <dataSource type="JNDI">
  79.                 <property name="initial_context" value="java:comp/env"/>
  80.                 <property name="data_source" value="jdbc/ProductionDB"/>
  81.             </dataSource>
  82.         </environment>
  83.     </environments>
  84.     <!-- ===================== 7. 映射器配置 ===================== -->
  85.     <mappers>
  86.         <!-- 指定XML映射文件 -->
  87.         <mapper resource="mapper/UserMapper.xml"/>
  88.         
  89.         <!-- 指定Mapper接口类(需与XML同名同包) -->
  90.         <mapper class="com.example.mapper.OrderMapper"/>
  91.         
  92.         <!-- 包扫描方式(推荐) -->
  93.         <package name="com.example.mapper"/>
  94.     </mappers>
  95.    
  96. </configuration>
复制代码

MyBatis的两种利用方式

一、XML文件设置

流程如下


  • 通过在resource下面创建mapper包用于存储Mapper.xml映射文件。
  • 在Mapper接口中定义需要的方法。
  • 在XML映射文件中设置SQL语句。
XML设置文件示例

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  3.   "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace="com.example.mapper.UserMapper">
  5.   <!-- 结果映射(解决字段名不一致问题) -->
  6.   <resultMap id="userResultMap" type="User">
  7.     <id property="id" column="user_id"/>
  8.     <result property="name" column="user_name"/>
  9.     <result property="email" column="user_email"/>
  10.   </resultMap>
  11.   <!-- 基础查询 -->
  12.   <select id="selectUserById" resultMap="userResultMap">
  13.     SELECT * FROM users WHERE user_id = #{id}
  14.   </select>
  15.   <!-- 动态SQL -->
  16.   <select id="selectUsersByCondition" resultMap="userResultMap">
  17.     SELECT * FROM users
  18.     <where>
  19.       <if test="name != null">
  20.         AND user_name LIKE CONCAT('%', #{name}, '%')
  21.       </if>
  22.       <if test="minAge != null">
  23.         AND age >= #{minAge}
  24.       </if>
  25.       <choose>
  26.         <when test="role == 'admin'">
  27.           AND is_admin = 1
  28.         </when>
  29.         <otherwise>
  30.           AND status = 1
  31.         </otherwise>
  32.       </choose>
  33.     </where>
  34.     ORDER BY create_time DESC
  35.   </select>
  36.   <!-- 批量插入 -->
  37.   <insert id="batchInsert" parameterType="list">
  38.     INSERT INTO users (user_name, email)
  39.     VALUES
  40.     <foreach item="user" collection="list" separator=",">
  41.       (#{user.name}, #{user.email})
  42.     </foreach>
  43.   </insert>
  44. </mapper>
复制代码
二、注解方式设置

        该方法比力实用于SQL语句比力简朴的时间,例如基础的CRUD。通过注解设置的方式可以简化开辟。
注解映射示例

  1. public interface UserMapper {
  2.   @Select("SELECT * FROM users WHERE user_id = #{id}")
  3.   @Results(id = "userResult", value = {
  4.     @Result(property = "id", column = "user_id", id = true),
  5.     @Result(property = "name", column = "user_name"),
  6.     @Result(property = "email", column = "user_email")
  7.   })
  8.   User selectUserById(Long id);
  9.   @SelectProvider(type = UserSqlBuilder.class, method = "buildSelectByCondition")
  10.   List<User> selectUsersByCondition(Map<String, Object> params);
  11.   @Insert("INSERT INTO users (user_name, email) VALUES (#{name}, #{email})")
  12.   @Options(useGeneratedKeys = true, keyProperty = "id")
  13.   int insertUser(User user);
  14.   @UpdateProvider(type = UserSqlBuilder.class, method = "buildUpdateSql")
  15.   int updateUser(User user);
  16.   // 动态SQL构建器
  17.   class UserSqlBuilder {
  18.     public String buildSelectByCondition(Map<String, Object> params) {
  19.       return new SQL() {{
  20.         SELECT("*");
  21.         FROM("users");
  22.         if (params.get("name") != null) {
  23.           WHERE("user_name LIKE CONCAT('%', #{name}, '%')");
  24.         }
  25.         if (params.get("minAge") != null) {
  26.           WHERE("age >= #{minAge}");
  27.         }
  28.         ORDER_BY("create_time DESC");
  29.       }}.toString();
  30.     }
  31.   }
  32. }
复制代码
两种方法的对比



  • XML的方式更适合复杂的SQL语句编写;对于简朴的SQL语句,我们还是发起利用注解的方式举行编写。
  • XML将SQL举行统一管理,而注解的方式将SQL分散在了Java代码中。
  • XML支持动态SQL,而注解方式需要通过Provider类或拼接字符串实现动态SQL。
        发起根据利用场景,混合利用XML和注解方式。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
继续阅读请点击广告

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
回复

使用道具 举报

×
登录参与点评抽奖,加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表