首页 > 编程语言 >Java框架 —— MyBatis

Java框架 —— MyBatis

时间:2024-12-11 10:34:27浏览次数:6  
标签:Java 框架 数据库 id SqlSession user SQL MyBatis 主键

MyBatis

简介

 持久层框架,半自动映射,支持自定义SQL、高级映射、存储过程,免除了JDBC代码、参数设置、获取结果集的工

作,可以通过XML或注解方式配置、映射接口,以及实体类在数据库中的记录

Hibernate 和 Mybatis

  • Hibernate

    也是持久层框架,它是全自动映射,SQL编写量小,但是不够灵活,适合用于需求稳定的项目

  • Mybatis

    半自动映射,SQL编写量较大,比较灵活,适合需求变化频繁、快速迭代的项目

运行原理

 Mybatis的核心是一个全局配置文件 + 多个映射文件。MyBatis采用的是构建者模式,使用

SqlSessionFactoryBuilderbuild()方法加载配置文件,生成SqlSessionFactory对象,

SqlSessionFactory采用的是工厂模式,使用openSession方法获取SqlSession对象,而SqlSession不像

JDBC一样可以直接操作数据库,它本身是一个接口,提供了操作数据库中数据的方法,通过调用执行器,来操作

mapperStatement对象执行SQL语句,返回结果

核心接口

SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession

代理模式规范

  • 接口和映射文件必须同包同名

  • 文件的命名空间(namespace)必须是全限定接口名

  • 接口中的方法名必须和映射文件中SQL的 id 相同

  • 接口中方法的参数只能有一个(除非使用@Param注解),参数类型必须与映射文件中parameterType保持一致

  • 返回值类型必须和ResultMap或ResultType相同

配置文件

MyBatis配置文件中,标签的顺序是一定的,不可改变

  • configuration(配置)

    • properties(属性)

    • setting(设置)

    • typeAliases(类型别名)

    • typeHandlers(类型处理器)

    • pluging(插件)

    • environment(环境)

    • mapping(映射器)

CURD

 在Mybatis中,我们可以通过在配置文件中在<select>等标签内编写SQL语句,也可通过@Select等注解进行

<select id="selectItem" resultType="com.ry.pojo.Item">
    select * from item where id = #{id}
</select>

编写

动态SQL

  • <if>

    条件查询,<if test="条件">

    <if test="categoryIdTwo != null and categoryIdTwo != ''">
         and category_id_two = #{categoryIdTwo}
    </if>
    
  • <choose>(when、otherwise)

    类似于Java中的switch...case...,when作为条件判断,所有条件都不满足,则进入otherwise

    <select id="findActiveBlogLike"
         resultType="Blog">
        SELECT * FROM BLOG WHERE state = ‘ACTIVE’
        <choose>
            <when test="title != null">
                AND title like #{title}
            </when>
            <when test="author != null and author.name != null">
                AND author_name like #{author.name}
            </when>
            <otherwise>
                AND featured = 1
            </otherwise>
        </choose>
    </select>
    
  • <foreach>

    item:相当于var,index:索引(通常忽略)

    collection:输入参数不同,内容不同

    • 参数为数组:输入 Array

    • 参数为list:输入为 list

    • 参数为map:输入为 key

    open:循环以...开始

    separate:以...进行分割

    close:以...结束

    <select id="selectPostIn" resultType="domain.blog.Post">
        SELECT *
        FROM POST P
        WHERE ID in
        <foreach item="item" index="index" collection="list"
            open="(" separator="," close=")">
            #{item}
        </foreach>
    </select>
    
  • <trim>

    可以代替<where>或者是<set>标签

    <trim prefix="WHERE" prefixOverrides="AND |OR ">
        ... 
    </trim>
    

多表查询

 通过ResultMap进行封装

  • 多对一:association

    • javaType:声明该属性的自定义类型(全限定类名或别名)

    • property:自定义类型中的属性名

  • 一对多:collection

    • ofType:集合中泛型的全限定类名或别名

    • property:该类型的属性名

<resultMap id="ResultMapItem" type="com.ry.pojo.Item">
  <association property="yiji" column="category_id_one"/>
  <association property="erji" column="category_id_two"/>
  <collection property="pls" column="id" ofType="com.ry.pojo.Comment"/>
</resultMap>

#{} 和 ${}的区别

  • #{}就是占位符,相当于JDBC时期的,会自动进行JDBC和Java类型的装换,将传入的数据当成一个字符串,会对传入的数据添加一对双引号,很大程度上防止了SQL注入问题

  • ${}是字符串拼接,不进行类型之间的转换,一般在当动态的是字段,而不是值时使用

延迟加载

 在Mybatis中也叫懒加载,是指在进行表的关联查询时,不立即加载关联的对象,而是在真正用到关联对象的数

据时,才进行查询。这种机制有利于提高查询性能,避免不必要的查询,减少数据库的压力和内存的使用

延迟加载:默认不开启,需要进行手动设置

  • 全局配置

    <settings>
        <!-- 启用延迟加载 -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 只有当使用属性时,才加载对象的所有延迟加载属性 -->
        <setting name="aggressiveLazyLoading" value="false"/>
    </settings>
    
  • 局部配置

    在具体的映射文件中进行配置,例如在<association><collection>中指定fetchType

    <resultMap id="blogResultMap" type="Blog">
        <association property="author" javaType="Author" select="selectAuthorById" fetchType="lazy"/>
    </resultMap>
     
    <select id="selectAuthorById" resultType="Author">
        SELECT * FROM author WHERE id = #{id}
    </select>
    

日志处理

使用:导包(log4j-core、log4j-api) -> 编写配置文件

<settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <setting name="logImpl" value="LOG4J"/>
</settings>

分页

  • RowBounds

先将数据查询到内存中,在内存中进行分页处理(数据量大时,不建议使用)

  • PageHelper

分页插件使用: 导包->在mybatis配置文件中进行配置->调用

<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <property name="reasonable" value="true"/>
    </plugin>
</plugins>

缓存

缓存:减少数据库的压力,提高数据库的性能。 实现原理:从数据库中将对象查询出来,使用后不进行销毁,而是存储在内存中,当再次需要获取该对象时,直接从内存中调用,减少数据库查询次数,提高性能

一级缓存

Mybatis默认开启一级缓存,一级缓存的作用域是同一个SqlSession,在同一个SqlSession下,多次执行同一个SQL语句,第二次不进行查询,走缓存

缓存失效

  • 当SqlSession调用close()方法,SqlSession对象关闭,直接会释放掉一级缓存PerpetualCache对象,一级缓存将不可用

  • 如果SqlSession调用了clearCache()方法,会清空PerpetualCache对象中的数据,但是SqlSession仍然可用

  • SqlSession执行了任何一个updatedeleteinsert操作,都会清空PerpetualCache中的数据,但SqlSession对象仍然可用

二级缓存

 二级缓存是SqlSessionFactory级别的,根据mapper的命名空间(namespace)划分,不同SqlSession多次调用同一mapper中的同一SQL语句,走缓存

使用

  1. 在配置文件中进行配置
<settings>
  <setting name="cacheEnabled" value="true"/>
</setttings>
  1. 将所有实体类序列化(实现接口Serializable
public class User implements Serializable
  1. 配置映射文件
<!--
    表示此namespace使用二级缓存
    cache标签的属性:
        eviction="LRU" :清除策略,默认为LRU,移除最长时间不被使用的对象。
        flushInterval="60000" :刷新间隔,以毫秒为单位的合理时间量
        size="512" :引用数目
        readOnly="true" :只读的缓存会给所有调用者返回缓存对象的相同实例
-->
<cache></cache>
<!--按照学号迭代查询-->
<!--
    二级缓存
        属性useCache="false",sql语句自己可以决定是否使用二级缓存
        属性flushCache="false",sql语句自己可以决定是否刷新缓存,多用与新增,修改,删除语句
-->
<select id="findUser" resultType="User">
    SELECT * FROM t_user WHERE id in
        <foreach collection="list" item="id" open="(" separator="," close=")">
            #{id}
        </foreach>
</select>

主键生成

解决在插入操作时,主键无法回显的问题

数据库支持主键自增

  • 使用JDBC方式返回主键自增的值

    这种方式只适用于支持主键自增的数据库

    <insert id="insertSysUser" useGeneratedKeys="true" keyProperty="id" >
        insert into sys_user(user_name,user_password,user_email,user_info,head_img,create_time) 
        values (
    	    #{userName},
    	    #{userPassword},
    	    default,
    	    #{userInfo},
    	    #{headImg,jdbcType=BLOB},
    	    #{createTime,jdbcType=TIMESTAMP}
        );
    </insert>
    

 在以上代码中,我们将useGeneratedKeys属性设置为true, MyBatis会使用 JDBC 的getGeneratedKeys方法

来取出由数据库内部生成的主键;获得主键值后将其赋值给keyProperty属性配置的id属性(实体类中的属性)。当

需要设置多个属性时,使用逗号隔开,这种情况下通常还需要设置 keyColumn 属性按顺序指定数据库的列,这里

列的值会和 keyProperty 配置的属性一一对应。

  • 使用selectKey返回主键的值

    使用<selectKey>标签进行获取主键的值,这种方式不仅适用于不提供主键自增功能的数据库,也适用于提供主键自增功能的数据库

    1. selectKey 中的keyColumnkeyProperty和上面 useGeneratedKeys 的用法相同

    2. resultType用于设置返回值

    3. order属性的设置与数据库有关,MySql 中,order属性的值为 AFTER ,因为当前记录的主键值在 insert 语句执行后才能获取

    <insert id="insertSysUser">
        insert into sys_user(user_name,user_password,user_email,user_info,head_img,create_time)
        values (
            #{userName},
            #{userPassword},
            default,
            #{userInfo},
            #{headImg,jdbcType=BLOB},
            #{createTime,jdbcType=TIMESTAMP}
        );
        <selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">
            SELECT LAST_INSERT_ID ()
        </selectKey>
    </insert>
    

数据库不支持主键自增

  • 使用selectKey返回主键的值

    在不支持主键自增的数据库中,如Orcal,order的值为 BEFORE,这是因为Orcal中需要先从序列获取值,然后将值作为主键插入到数据库中

注:selectKey元素放置的位置不会影响selectKey中的方法在insert前面或者后面执行的顺序,影响执行顺序的是order属性。

```
<insert id="insertSysUser">
    <selectKey keyColumn="id" resultType="long" keyProperty="id" order="BEFORE">
        SELECT UUID
    </selectKey>
    insert into sys_user(id,user_name,user_password,user_email,user_info,head_img,create_time)
    values (
        #{id},
        #{userName},
        #{userPassword},
        default,
        #{userInfo},
        #{headImg,jdbcType=BLOB},
        #{createTime,jdbcType=TIMESTAMP}
    );
</insert>
```

XML 文件中的特殊字符

  • 使用<![CDATE[" "]]>包裹

  • 使用转义字符

    &amp; 和  &lt; 小于  &gt; 大于

标签:Java,框架,数据库,id,SqlSession,user,SQL,MyBatis,主键
From: https://www.cnblogs.com/codyxz/p/18597515

相关文章

  • javaweb毕业设计项目 网上飞机票售票预订系统
    目录项目介绍具体实现截图开发核心技术:核心代码部分展示详细视频演示源码获取方式项目介绍本次设计的网上机票预订系统通过访问主页,可以实现用户管理、公告信息管理、航班信息管理、机票信息管理、订单信息管理、退订信息管理、兑换信息管理、系统管理等基本功能,为......
  • javaweb软件工程网络教育设计与实现3f4c8
    目录项目介绍具体实现截图开发核心技术:核心代码部分展示详细视频演示源码获取方式项目介绍在线课堂问答教学是由高校学生依据兴趣爱好自愿组成,按照章程自主开展在线课堂问答教学。在线课堂问答教学是实施素质教育的重要途径和有效方式,在加强校园文化建设、提高学生......
  • Mybatis 拦截器实现单数据源内多数据库切换
    作者:京东保险王奕龙物流的分拣业务在某些分拣场地只有一个数据源,因为数据量比较大,将所有数据存在一张表内查询速度慢,也为了做不同设备数据的分库管理,便在这个数据源内创建了多个不同库名但表完全相同的数据库,如下图所示:现在需要上线报表服务来查询所有数据库中的数据进行统计,......
  • .NET MAUI开发的安卓、iOS软件和Java开发的安卓和Swift开发的iOS的区别
    1. 开发语言和平台.NETMAUI:使用 C# 作为开发语言。通过 .NET6/7/8 平台编译并打包应用。.NETMAUI 会根据目标平台(Android或iOS)编译和运行不同的本地代码。代码是跨平台的,开发者可以使用相同的代码库为Android和iOS构建应用,只需要针对平台特定功能进行少量调......
  • 在 Java 中,要处理 未知的输入格式(可能是日期字符串或时间戳字符串),统一返回日期对象。
    在Java中,要处理未知的输入格式(可能是日期字符串或时间戳字符串),可以通过以下步骤实现:判断输入是日期字符串还是时间戳字符串。如果是全数字组成的字符串,可以尝试将其解析为时间戳。否则,按照支持的日期格式解析。支持多种日期格式。定义常见日期格式的数组,逐一尝试解......
  • java核心基础 第一章 基石篇
    内容概述在java的世界里,我们离不开三个核心的概念,这是java世界的基石。他们分别是java语言、JVM、JDK。本章的学习目标是深刻理解java语言、JVM、和JDK。并额外需要理解一个classpath这个概念。以及要知道java程序运行时都需要经历哪些环节。前置阅读本章涉及到的一些术......
  • 认识java
    认识JAVAJAVA简介主要特性以下是Java的一些主要特性以下是Java的一些其他特性Java开发环境Java程序结构学习Java学习Java通常涉及以下几个步骤JAVA简介Java是由SunMicrosystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称。由Ja......
  • 校园二手物品交易市场系统|Java|SSM|VUE| 前后端分离
                  【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、VUE、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetom......
  • 校园点餐系统|Java|SSM|JSP| 前后端分离
                  【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetom......
  • 摊位管理系统|Java|SSM|JSP| 前后端分离
                  【技术栈】1⃣️:架构:B/S、MVC2⃣️:系统环境:Windowsh/Mac3⃣️:开发环境:IDEA、JDK1.8、Maven、Mysql5.7+4⃣️:技术栈:Java、Mysql、SSM、Mybatis-Plus、JSP、jquery,html5⃣️数据库可视化工具:navicat6⃣️服务器:SpringBoot自带apachetom......