javaee之Mybatis4

news2025/1/23 3:58:07

延迟加载与立即加载的概念

 Mybatis中的延迟加载与立即加载

一、一对一实现延迟加载的步骤(多对一,看成一对一)

我们这里是利用account表中的一个方法来做

先来看IAccountDao里面的一个方法

然后再去看持久层IAccountDao.xml

这个方法给我们执行以后会返回如下结果 

 

 并且我们可以看到这个语句是一下全部执行完了

现在我们不想它一下执行完,我们想要一个延迟加载,那么就先来修改一下sql语句

 

 就是先把账户信息拿出来,先不做用户信息

那么下面一段映射配置也就没有用了,因为不会马上把信息加载过来

 做一下修改:

下面说一下怎么打开Mybatis的延迟策略,在我们下载的Mybatis中有一个参考手册

 下面我们去SqlMapConfig.xml去配置一下

 为了展示延迟加载,我们把这段代码给注释掉

然后出现一个结果

 二、一对多来实现一个延迟加载的操作

上面多对一我们就用到了association来实现了一个延迟加载

下面其实就是用collection标签来实现一个延迟加载

这个涉及到的操作,就是查User类去找account信息,user是主表,account是从表,主表里面引入从表

之前在IUserDao.xml下面存在这样一个方法

这个 方法会查询用户信息,同时把账户信息封装到account里面

我们现在只要先去找到用户信息,然后延迟,需要的时候在加载账户信息,那么此时的账户信息,也就需要一个user的id来进行查找账户

OK,既然说到要用一个id去查找账户的信息,那么我们就要先去IAccountDao实现一个这样的方法

然后去配置IAccountDao.xml文件

 

下面再去修改IUserDao.xml文件

 

这上面sql语句肯定要改了

然后配置文件中映射account 对象的部分,也可以不要了,从新配置一下延迟加载方法

 

 

运行结果:

 也就是user表的一个体现。

Mybatis缓存

一、缓存的概念

二、mybatis的一级二级缓存

 先来说一级缓存

之前在IUserDao里面存在一个方法和这个方法的配置

 

然后我们去测试一下这个方法

 

测试结果:

我们如何清楚缓存,我们说了这个一级缓存是依赖于什么,依赖于sqlSession的,这个就是内部会给我们产生一个代理对象,然后调用方法

那么如果在执行完了之后,把sqlSession给关闭了呢

那我们下面测试一下,清除缓存

运行代码:

UserTest.java 

测试结果: 

下面看一级缓存分析

 验证一下上面的行为

之前在IUserDao.xml里面存在一个方法

 然后现在去UserTest.java里面做一个方法

执行结果

 明显地址不一样

下面说一下二级缓存

然后第三步

 下面说一下二级缓存存储数据原理

下面用代码测试一下

UserTest.java

 

在做测试之前,说一点啊,所缓存的类,一定要实现Serializable,这样才可以利用序列化来保存对象,好像也就是说,缓存技术用到了序列化

 语句也只有一次执行

 Mybatis的注解开发

因为这是注解开发,所以我把Mybatis3复制一份变成Mybatis4

先来说一下大体的一些东西:

1.只要你用了注解,就不能有配置文件

 

这两者同时存在会报错的, 我们把这个配置文件放到另外一个位置去吧

 之前我们配了注解,一般还要去SqlMapConfig.xml里面的<mappers>

注解的话就是配置<mapper class ="com.pxx.dap.IUserDao">

但是我们已经配置了如下

另外说一下啊,常用四个CRUD注解

  

 下面我们来说一下mybatis注解说明

 1.类中属性与数据库的字段映射

2. 引用Results定义的封装

3.配置插入操作之后,获取插入数据的id

 IUserDao的操作重新配置基本的CURD操作

1.删除或者把IUserDao.xml移动到另外一个,反正不要在resources正确的路径下面

然后在IUserDao.java上面添加注解

直接上代码

package com.pxx.dao;

        import com.pxx.domain.QueryVo;
        import com.pxx.domain.User;
        import org.apache.ibatis.annotations.*;

        import java.util.List;

public interface IUserDao {

    /**
     * 查询所有操作
     * @return*/
    @Select("select * from user")
    @Results(id="userMap",value={
                                @Result(id=true,column = "id",property = "id"),
                                @Result(column = "username",property = "username"),
                                @Result(column = "sex",property = "sex"),
                                @Result(column="address",property = "address"),
                                @Result(column="birthday",property = "birthday")
    })
    List<User> findAll();

    /**
     * 保存用户信息操作*/
    @Insert("insert into user" +
            "(username,address,sex,birthday)" +
            "values" +
            "(#{username},#{address},#{sex},#{birthday})")
    @SelectKey(keyColumn = "id",keyProperty = "id",resultType = Integer.class,
            before = false,statement = {"select last_insert_id()"})
    void saveUser(User user);

    /**
     * 用户数据的更新操作*/
    @Update(" update user set\n" +
            "         username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}")
    void updateUser(User user);

    /**
     * 删除某一个用户的操作*/
    @Delete(" delete from user where id=#{id}")
    void deleteUser(int userId);

    /**
     * 根据id查询一个用户
     * 注意的是这里有个结果集需要封装
     * 引用上面配置的Results注解
     * */
    @Select("select * from user where id=#{id}")
    @ResultMap("userMap")
    User findById(Integer userId);


    /**
     * 通过名字进行模糊查询一个用户
     * 注意这里也会给我们返回一个封装结果
     * @param username
     * @return
     */
    @Select(" select * from user where username like #{username}")
    @ResultMap("userMap")
    List<User> findByName(String username);

   /**
    * 这种int返回数据结果集就可以不用管
     * 查询总用户数*/
    @Select("select count(id) from user")
    int findTotal();


   /* *//**
     * 根据queryVo的条件来查询对象*//*

    List<User> findUserByVo(QueryVo vo);

   *//**
     * 根据传入参数条件进行查询的例子*//*

    List<User> findUserByCondition(User user);


   *//**
     * 根据queryvo中提供的id集合,查询用户信息*//*

    List<User> findUserInIds(QueryVo vo);

    *//**
     * 查询所有用户信息,并且同时获取每个用户下面的账户信息
     *//*
    List<User> findAllUser();*/



}

使用注解实现复杂关系映射开发

 上面是基本的CURD操作

 

具体信息
 这里是操作IAccountDao.

首先把IAccountDao.xml移动到另外一个目录里面

 测试运行

下面来做一个一对多的关系映射

这个就是通过user表来查询account,首先就是一个user对应的是多个account表

user是主表,account是从表,我们需要在主表里面引入从表

需求:查询所有用户信息以及相关相互信息的方法

首先去IAccountDao.java配置一下findByUid这个方法,因为延迟要用

package com.pxx.dao;

import com.pxx.domain.Account;
import com.pxx.domain.AccountUser;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;

import java.util.List;

public interface IAccountDao {

    /**
     * 查询所有账户,同时获取当前账户的所属信息
     */
    @Select("select * from account")
    @Results(id="accountMap",
            value = {
                    @Result(id=true,column = "id",property = "id"),
                    @Result(column = "uid",property = "uid"),
                    @Result(column = "money",property = "money"),
                    //这里配置account中的user类
                    @Result(column="uid",property = "user",
                    one=@One(select="com.pxx.dao.IUserDao.findById",fetchType= FetchType.LAZY))
            }
    )
    List<Account> findAll();

    /**
     * 查询所有账户,同时获取账户所属用户名称以及它的地址信息
     */

    List<AccountUser> findAllAccount();


    /**
     * 根据用户id查询账户信息
     */
    @Select("select * from account where uid = #{uid}")
    @ResultMap("accountMap")
    List<Account> findByUid(int uid);

}

下面去IUserDao.java配置

package com.pxx.dao;

        import com.pxx.domain.QueryVo;
        import com.pxx.domain.User;
        import org.apache.ibatis.annotations.*;
        import org.apache.ibatis.mapping.FetchType;

        import java.util.List;

public interface IUserDao {

    /**
     * 查询所有操作
     * @return*/
    @Select("select * from user")
    @Results(id="userMap",value= {
            @Result(id = true, column = "id", property = "id"),
            @Result(column = "username", property = "username"),
            @Result(column = "sex", property = "sex"),
            @Result(column = "address", property = "address"),
            @Result(column = "birthday", property = "birthday"),
            @Result(column = "id", property = "accounts",
                    many = @Many(select = "com.pxx.dao.IAccountDao.findByUid", fetchType = FetchType.LAZY))
    })
    List<User> findAll();

    /**
     * 保存用户信息操作*/
    @Insert("insert into user" +
            "(username,address,sex,birthday)" +
            "values" +
            "(#{username},#{address},#{sex},#{birthday})")
    @SelectKey(keyColumn = "id",keyProperty = "id",resultType = Integer.class,
            before = false,statement = {"select last_insert_id()"})
    void saveUser(User user);

    /**
     * 用户数据的更新操作*/
    @Update(" update user set\n" +
            "         username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}")
    void updateUser(User user);

    /**
     * 删除某一个用户的操作*/
    @Delete(" delete from user where id=#{id}")
    void deleteUser(int userId);

    /**
     * 根据id查询一个用户
     * 注意的是这里有个结果集需要封装
     * 引用上面配置的Results注解
     * */
    @Select("select * from user where id=#{id}")
    @ResultMap("userMap")
    User findById(Integer userId);


    /**
     * 通过名字进行模糊查询一个用户
     * 注意这里也会给我们返回一个封装结果
     * @param username
     * @return
     */
    @Select(" select * from user where username like #{username}")
    @ResultMap("userMap")
    List<User> findByName(String username);

   /**
    * 这种int返回数据结果集就可以不用管
     * 查询总用户数*/
    @Select("select count(id) from user")
    int findTotal();


   /* *//**
     * 根据queryVo的条件来查询对象*//*

    List<User> findUserByVo(QueryVo vo);

   *//**
     * 根据传入参数条件进行查询的例子*//*

    List<User> findUserByCondition(User user);


   *//**
     * 根据queryvo中提供的id集合,查询用户信息*//*

    List<User> findUserInIds(QueryVo vo);

    /**
     * 查询所有用户信息,并且同时获取每个用户下面的账户信息
     */
    @Select("select * from user")
    @ResultMap("userMap")
    List<User> findAllUser();



}

 这里来说一下这个位置 

 这个位置子啊某个方法配了就代表全局映射,群居都可以调用

在UserTest中测试一下运行结果:

 

运行结果:

 下面说一下基于注解的二级缓存

在Dao上面配置一个注解 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/105419.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux学习-92-SELinux管理

18 SELinux管理 root 用户在 Linux 系统当中就是无所不能的&#xff0c;而且读、写和执行权限对 root 用户完全没有作用。root 用户的存在极大地方便了 Linux 的管理&#xff0c;但是也造成了一定的安全隐患。绝大多数系统的严重错误都是由于 root 用户的误操作引起的&#xff…

开源项目 Spartacus 的 git 分支使用规范

Spartacus 开源项目里存在如下的 git 分支&#xff1a; feature/GH-xxxx 分支用于简单的功能和错误修复epic/epic-name 分支用于大功能的开发release/1.4.0-rc.0 分支用于特定的发布&#xff08;你可以将它们与维护分支区分开来&#xff0c;因为包含了完整的版本号&#xff09…

压力测试笔记

压测学习 要求&#xff1a;满足100并发500ms性能要求 压测场景 新系统上线支持 在新系统上线前&#xff0c;通过执行性能压测能够对系统的负载能力有较为清晰的认知&#xff0c;从而结合预估的潜在用户数量保障系统上线后的用户体验。技术升级验证 在系统重构过程中&#xf…

Github每日精选(第80期):自动生成命令行python-fire

Python Fire 是一个用于从绝对任何Python对象自动生成命令行界面 (CLI) 的库。 Python Fire 是一种在 Python 中创建 CLI 的简单方法。 [1]Python Fire 是用于开发和调试 Python 代码的有用工具。 [2]Python Fire 有助于探索现有代码或将其他人的代码转换为 CLI。[3]Python Fi…

Co-Scale Conv-Attentional Image Transformers

Co-Scale Conv-Attentional Image Transformers一、引言二、实现方法&#xff08;一&#xff09;、Conv-Attention Module三、Co-Scale Conv-Attentional Transformers&#xff08;一&#xff09;、Co-Scale串行块&#xff08;二&#xff09;、Co-Scale并行块&#xff08;三&am…

跳频和扩频通信

跳频(FH, Frequency Hopping)是指载波频率在很宽频率范围内按某种序列或图案进行跳变&#xff0c;它能进一步提高系统的抗干扰性能。 跳频技术改善了无线信号的传输质量&#xff0c;可以明显地降低同频干扰和频率选择性衰落&#xff0c;为了避免在同一小区或临近小区中&#xf…

无惧管控放开,分享居家办公、远程办公项目经验

国家已经放开疫情管控&#xff0c;随之而来的&#xff0c;是各地大面积的“小阳人”爆发&#xff0c;很多企业不得不重新启动远程办公机制。 云盒子科技拥有良好的的远程办公经验&#xff0c;产品是包含企业云盘、流程审批、邮件、通讯录、企业公告一体化的在线文档协作平台。…

Ubuntu18.04下调用fastdds实现通信

提纲 1、编写idl 2、fastddsgen生成cpp的源代码文件 3、编译生成可执行文件 4、执行可执行文件完成通讯 1、编写idl 现在我们可以编写一个简单的 IDL&#xff1a; 2、fastddsgen生成cpp的源代码文件 编写好idl后&#xff0c;就可以通过 fastddsgen 快速生成代码。 最终会自动…

【Vsan数据恢复】Vsan分布式文件系统数据丢失的数据恢复

vSAN存储数据恢复环境&#xff1a; 某公司一台vSAN分布式文件系统存储设备&#xff1b; VSAN存储采用了超融合架构&#xff0c;存储内总共有24块硬盘。 vSAN存储故障&初检&#xff1a; 由于未知原因关机重启&#xff0c;逻辑架构出现严重故障&#xff0c;上层虚拟机瘫痪&am…

新冠确诊阳性后的第一篇博客,一文带你学习SQL注入

新冠确诊阳性后的第一篇博客&#xff0c;一文带你学习SQL注入1.你好SQL注入2.盲注3.Timing Attack4.常见的攻击技巧5.SQL CoIumn Truncation6.防御SQL注入SQL注入防御的误区使用预编译语句使用存储过程SQL注入攻击属于注入攻击的一种&#xff0c;注入攻击的本质&#xff0c;是把…

echarts3D柱状图,多个柱子,单个柱子,传参即可

<template><!-- 折线图 --><div ref"line" class"line"></div> </template><script> // colorList 横条颜色数组 // data 数据 格式为&#xff1a; [] // areaStyle 渐变色 import * as echarts from echarts import…

AOT(超前编译)实例分析

文章目录一、背景二、具体实施2.1 tfcomfile 是什么&#xff1f;2.2 tfcompile 的功能是什么&#xff1f;2.3使用tfcompile三、总结一、背景 前边已经了解了JIT和AOT的基本概念&#xff0c;AOT(提前编译)方式就是在代码执行阶段之前全部编译成目标指令&#xff0c;进入执行阶段…

自动网络搜索NAS之FBNetV1

1. 摘要 为移动设备设计卷积网络挑战巨大&#xff0c;因为设计空间巨大&#xff0c;现有NAS方法在计算上是昂贵的。另外&#xff0c;之前的工作关注降低FLOPs&#xff0c;但是FLOPs并不总是反应真实的延迟。因此基于differentiable neural architecture search&#xff08;DNA…

sd卡怎么格式化?5个步骤轻松教会你

随着SD卡的广泛使用&#xff0c;总会有各种情况导致SD卡必须要格式化才行。但是格式化有没有办法执行&#xff0c;sd卡怎么格式化&#xff1f;还有人会因为误操作导致的数据丢失。现在&#xff0c;小编就给大家介绍一下怎么格式化SD卡&#xff1f;以及格式化后SD卡数据的恢复方…

VUE3-模板语法《二》

首先看到这张图&#xff0c;左边的结构就不分析了&#xff0c;上一章有说明顺序。 中间红色的部分&#xff0c;分为3块&#xff0c;第一块是模板&#xff0c;里面写html&#xff1b;第二块是脚本语言&#xff0c;里面写js或者ts语言&#xff0c;lang"ts"就是ts语法…

GreatSQL MGR 使用 IPv6 连接

GreatSQL社区原创内容未经授权不得随意使用&#xff0c;转载请联系小编并注明来源。GreatSQL是MySQL的国产分支版本&#xff0c;使用上与MySQL一致。作者&#xff1a;王权富贵文章来源&#xff1a;社区原创 1.概述 本文基于 GreatSQL 8.0.25-16 &#xff0c;以下测试均使用此版…

嵌入式:Load/Store之单寄存器的存取指令

文章目录Load/Store指令分类单寄存器的存取指令1、单字和无符号字节的数据传送指令指令说明指令汇编格式2、半字和有符号字节的数据传送指令指令汇编格式ARM处理器是Load/Store型的&#xff0c;即它对数据的操作是通过将数据从存储器加载到片内寄存器中进行处理&#xff0c;处理…

SuperMap iPortal 对接postgis业务数据库(二):大屏使用接口数据更新图表和地图

本文是SuperMap iPortal 对接postgis业务数据库的第二个步骤&#xff1a;大屏使用接口数据更新图表和地图。 这个步骤可以有两种方式去实现数据的展示和更新如下&#xff1a; 一、使用数据上图构建地图并在大屏中使用 1. 数据上图构建地图 打开iPortal 应用中心的数据上图&a…

教你如何轻松搞定云上打印管理

摘要&#xff1a;加快自主创新&#xff0c;满足数字化用户多场景文印需求。本文分享自华为云社区《有了司印云打印&#xff0c;云上打印管理轻松搞定&#xff01;》&#xff0c;作者&#xff1a;云商店 。 作为与职场和个人办公息息相关的工作场景&#xff0c;打印长期以来都是…

uniapp-uView在离线状态下无法显示icon图标的问题

1、修改uview-ui下的u-icon.vue配置文件&#xff0c;一般目录在 uni_modules\uview-ui\components\u-icon\u-icon.vue 2、源文件引入的是阿里巴巴的icon https://at.alicdn.com/t/font_2225171_8kdcwk4po24.ttf font-face {font-family: uicon-iconfont;src: url(https://at.…