MyBatis学习笔记--下篇

news2024/11/24 17:09:05

MyBatis学习笔记–下篇

文章目录

  • MyBatis学习笔记--下篇
    • 1、多对一的处理(关联)
      • 1.1、表的创建
      • 1.2、实体类
      • 1.2、按照查询嵌套处理
      • 1.3、按照结果嵌套处理(联表查询 )
    • 2、一对多的处理(Collection)
      • 2.1、实体类
      • 2.2、按结果查询(联表查询)
      • 2.3、按照结果嵌套查询
    • 3、动态Sql
      • 3.1、表的创建
      • 3.2、动态sql中三大标签的使用
        • 3.2.1、if
        • 3.2.2、choose(when,otherwise)
        • 3.2.3、 trim(where,set)
        • 3.2.4、 for each
        • 3.2.5、 Sql片段
    • 4、缓存
      • 4.1、简介
      • 4.2、Mybatis缓存
      • 4.3、一级缓存(作用小)
      • 4.4、二级缓存
      • 4.5、缓存原理
      • 4.6、自定义缓存--Ehcache
    • 5、问题

1、多对一的处理(关联)

在这里插入图片描述

  • 多个学生,对应一个老师
  • 对于学生而言,关联…多个关联一个老师
  • 对于老师而言,**集合…**一个老师有多个学生
    在这里插入图片描述

1.1、表的创建

Teacher表

DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='老师表';

-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES ('1', 'radan');
INSERT INTO `teacher` VALUES ('2', 'js');

Student表

DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `tid` int DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `tid` (`tid`),
  CONSTRAINT `tid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('1', '张三', '1');
INSERT INTO `student` VALUES ('2', '李四', '1');
INSERT INTO `student` VALUES ('3', '王五', '1');
INSERT INTO `student` VALUES ('4', '溜溜', '1');

1.2、实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Teacher {
    private int id;
    private String  name;
}

public class Student {
    private int id;
    private String name;
   // 学生需要关联一个老师
    private Teacher teacher;
}

1.2、按照查询嵌套处理

  <!--
            思路:
            1、查询所有的学生信息
            根据查询出来的学生的tid,寻找对应的老师! 子查询
    -->

    <resultMap id="studentAndTeacher" type="student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <!--
            复杂属性需要单独处理
            对象:association
            集合:collection
        -->
        <association property="teacher" column="tid" javaType="teacher" select="getTeacher"/>

    </resultMap>
    <select id="getAllStudents" resultMap="studentAndTeacher">
        select * from student
    </select>
    <select id="getTeacher" resultType="teacher">
        select * from teacher where id = #{id}
    </select>

1.3、按照结果嵌套处理(联表查询 )

        注意点:就是当要联立的两张表都有相同的字段名时,会起“冲突”,导致查询的结果都是前面一张表的字段属性值
        解决思路:在编写sql语句时,给冲突的列起别名,然后在resultMap结果集映射中利用别名可以有效的避免冲突。

<!--
    联表查询
    注意点:就是当要联立的两张表都有相同的字段名时,会起“冲突”,导致查询的结果都是前面一张表的字段属性值。
    解决思路:在编写sql语句时,给冲突的列起别名,然后在resultMap结果集映射中利用别名可以有效的避免冲突。
-->
    <select id="getAllStudents2" resultMap="studentMap">
        select s.id sid,s.name sname, t.name tname, t.id t_id from student s,teacher t where s.tid=t.id
    </select>
    <resultMap id="studentMap" type="student">
        <result property="id" column="sid"/>
        <result property="name" column="sname"/>
        <association property="teacher" javaType="teacher">
            <result property="id"  column="t_id"/>
            <result property="name" column="tname"/>
        </association>
    </resultMap>

2、一对多的处理(Collection)

例如:一个老师拥有多个学生
对于老师而言就是一个一对多的处理。
在这里插入图片描述

2.1、实体类

public class Teacher {
    private int id;
    private String  name;
    //一个老师拥有多个老师
    List<Student> students;
}
public class Student {
    private int id;
    private String name;
    //学生只有一个老师
    private int tid;
}

2.2、按结果查询(联表查询)

    <!--    按照结果嵌套查询-->
    <resultMap id="teacherMap" type="teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <!--
                复杂的属性:单独处理。 我们需要单独处理的是 对象:association 集合:collection
                javaType=“”  填的都是指定属性的类型
                在集合中一般都是泛型信息,使用ofType获取
         -->
        <collection property="students" ofType="student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

    <select id="getAllTeacher" resultMap="teacherMap">
        select s.id sid,s.name sname,t.id tid,t.name tname
        from teacher t,student s where s.tid=t.id
    </select>

2.3、按照结果嵌套查询

<!--    按照结果嵌套查询-->
    <select id="getTeacher2" resultMap="teacherMap2">
        select * from teacher where id=#{id}
    </select>
    <resultMap id="teacherMap2" type="teacher">
        <collection property="students"  javaType="ArrayList"  ofType="student" column="id" select="getStudentByTeacher_id">
            
        </collection>
    </resultMap>
    <select id="getStudentByTeacher_id" parameterType="int" resultType="student">
        select * from student where tid=#{tid}
    </select>

总结:

  • 关联—【association】–多对一
  • 集合—【collection 】一对多
  • javatype &ofType
    • javatype :用来指定实体类中属性的类型
    • ofType:用来映射到List或者集合的破击类型,泛型中的约束类型!

注意点:

  • 保证sql的可读性,尽量保证sql的通俗易通
  • 注意一对多和多对一中,属性名和字段的问题!
  • 如果问题不好排查,可以使用日志,建议使用log4j

3、动态Sql

动态Sql:就是指根据不同的条件生成不同的SQL语句

3.1、表的创建

DROP TABLE IF EXISTS `blog`;
CREATE TABLE `blog` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  `title` varchar(255) DEFAULT NULL COMMENT '博客标题',
  `author` varchar(255) DEFAULT NULL COMMENT '博客作者',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `views` int DEFAULT NULL COMMENT '浏览量',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='博客表';

-- ----------------------------
-- Records of blog
-- ----------------------------
INSERT INTO `blog` VALUES ('1', '游戏', 'randan', '2023-06-30 17:22:07', '1');
INSERT INTO `blog` VALUES ('2', '日志', 'radan', '2023-10-30 17:21:21', '22');
INSERT INTO `blog` VALUES ('3', '兰州牛肉面', 'js', '2023-06-30 17:21:20', '33');

3.2、动态sql中三大标签的使用

3.2.1、if

<select id="queryBlog" parameterType="map" resultType="blog">
        select * from blog where 1=1
        <if test="title != null ">
            and title=#{title}
        </if>
        <if test="author != null ">
            and author=#{author}
        </if>
    </select>

3.2.2、choose(when,otherwise)

这个标签像Switch,Case语法的使用规则。(模糊查找,提供了什么就查询这些条件符合的记录)。
只能选择一个 按照顺序来判断

<select id="queryBlogChoose2" parameterType="map" resultType="blog">
        <!--        where 标签可以有效的解决 1=1代码的重复编写-->
        select * from blog
        <where>
          <choose>
              <!--只能选择一个 按照顺序来判断-->
              <when test="title !=null">
                  title=#{title}
              </when>
              <when test="author != null">
                  and author=#{author}
              </when>
              <otherwise>
                  and views =#{views}
              </otherwise>
          </choose>
        </where>
    </select>

3.2.3、 trim(where,set)

  • where:where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
  • set:set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

Where

    <select id="queryBlogChoose" parameterType="map" resultType="blog">
<!--        where 标签可以有效的解决 1=1代码的重复编写-->
        select * from blog
        <where>
            <if test="title != null ">
                and title=#{title}
            </if>
            <if test="author != null ">
                and author=#{author}
            </if>
        </where>

在这里插入图片描述

Set(注意:必须有一个if成立,不然就会导致update语句后面没有set更新的值。)

 <update id="updateBlog" parameterType="map" >
        update blog
        <set>
            <if test="title != null">title=#{title},</if>
            <if test="author != null">author=#{author}</if>
        </set>
        where id=#{id}
    </update>

3.2.4、 for each

在这里插入图片描述

    <select id="queryBlogForEach" parameterType="map" resultType="blog">
<!--        查询前三个人的信息-->
        select * from blog
        <where>
            <foreach collection="ids" index="index" item="id" open=" and ("  close=")" separator="or">
                 id =  #{id}
             </foreach>
        </where>

测试:

  @org.junit.Test
    public void test006() throws IOException {
        SqlSession sqlSession= MyBatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        HashMap map=new HashMap();
        List<Integer> ids=new ArrayList<Integer>();
        ids.add(1);
        ids.add(2);
        ids.add(3);
        map.put("ids",ids);
        System.out.println(mapper.queryBlogForEach(map));
        sqlSession.commit();
        sqlSession.close();
    }

3.2.5、 Sql片段

作用:将重复的SQL语句抽取出来,放到标签中,可以进行复用。

  1. 使用sql标签抽取公共部分
   <sql id="title-author">
        <if test="title != null ">
            and title=#{title}
        </if>
        <if test="author != null ">
            and author=#{author}
        </if>
    </sql>
  • 使用include标签引用公共部分定义的sql片段
    <select id="queryBlog" parameterType="map" resultType="blog">
        select * from blog where 1=1
        <!--refid:引用id-->
        <include refid="title-author"></include>
       
    </select>

注意事项:

  • 最好基于单表来定义sql片段
  • sql抽取的部分不要存在where标签

4、缓存

4.1、简介

查询数据–>连接数据库,好资源!

什么是缓存[Cache]?

  • 存在内存中的临时数据。
  • 将用户经常查询的数据放在缓存(内存)中,用户查询数据就不用偶从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
    为什么使用缓存?
  • 减少和数据库的交互次数,减少系统开销,提高系统效率。

什么样的数据能使用缓存

  • 经常查询并且不经常改变的数据。

4.2、Mybatis缓存

  • MyBatis 包含了一个非常强大的查询缓存特性,他可以非常方便地定制和配置缓存,缓存可以极大的提升查询效率。

  • MyBatis 系统中默认定义了两级缓存:以及缓存和二级缓存

    • 默认情况下,只有以及缓存开启。(SQLSession级别的缓存,也称为本地缓存)
    • 二级缓存需要手动开启和设置,它是基于namespace级别的缓存。为了提高扩展性,MyBatis定义了缓存接口Cache 。我们可以通过缓存Cache接口来定义二级缓存。

4.3、一级缓存(作用小)

测试步骤:

  • 开启日志
    <settings>
        <!--配置标准日志工厂-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
  • 测试(在一个session中查询两次相同操作)
    @Test
    public void  test001() throws IOException {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> allUsers = mapper.getAllUsers();
        List<User> users = allUsers;
        System.out.println(users==allUsers);
        sqlSession.close();
    }

在这里插入图片描述
缓存失效的情况:

  1. 查询不同的条件
  2. 增删改操作,可能会改变原来的啥时间,所以必定会刷新缓存!
  3. 查询不同的Mapper.xml
  4. 手动清理缓存!
sqlSession.clearCache();//清理缓存

小结:一级缓存默认是开启的,只在一次SQLSession中有效,也就是拿到连接到关闭连接的区间。

4.4、二级缓存

  • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以产生了二级缓存
  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
  • 工作机制
    • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
    • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保持在二级缓存中;
    • 新的会话查询信息,就可以从二级缓存中获取内容;
    • 不同的mapper查出的数据会放在自己对应的缓存(map)中;

步骤:

  • 在mybatis配置文件中,配置全局缓存设置;
 <settings>
        <!--显示的开启全局缓存   默认是开启的-->
        <setting name="cacheEnabled" value="true"/>
    </settings>
  • 在mapper.xml加缓存标签

创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。

    <!--开启二级缓存-->
        <cache
        eviction="FIFO"
        flushInterval="60000"
        size="512"
        readOnly="true"/>
<!--    eviction:缓存执行的策略
        flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。
        size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。
        readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。
   -->
  • 测试
@Test
    public void  test002() throws IOException {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        SqlSession sqlSession1 = MyBatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user1 = mapper.findUserById(1);
        sqlSession.close();
        UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
        User user2 = mapper1.findUserById(1);
        System.out.println(user1==user2);
        sqlSession1.close();
    }

注意点:
二级缓存存在于 SqlSessionFactory 生命周期中

我一直以为二级缓存针对的对象是一个Mapper对象,只要是针对同一个Mapper的操作,都可以实现二级缓存。但是前提是操作必须在同一个SqlSessionFactory 中进行。

在一开始的代码中,通过调用三次getFactory()并打开session,实例化了三个不同的SqlSessionFactory 对象,这样在后续的SQL操作中,是不可能命中二级缓存的。

在这里插入图片描述

4.5、缓存原理

在这里插入图片描述

4.6、自定义缓存–Ehcache

Ehcache是一种广泛使用的开源Java分布式缓存。主要面向通用缓存。

要在程序中使用,先导入依赖

<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache -->
<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.2.1</version>
</dependency>

在mapper.xml中使用对应的缓存即可

   <cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

编写ehcache.xml文件,如果在 加载时 未找到 /ehcache.xml 资源或出现问题,则将使用默认配置。

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false" dynamicConfig="false">
    <!--
    diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位
    置。参数解释如下:
    user.home – 用户主目录
    user.dir – 用户当前工作目录
    java.io.tmpdir – 默认临时文件路径
    -->
    <diskStore path="./tmpdir/Tmp_EhCache"/>



    <defaultCache
            eternal="false"
            maxElementsInMemory="10000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="259200"
            memoryStoreEvictionPolicy="LRU"/>
    <cache
            name="cloud_user"
            eternal="false"
            maxElementsInMemory="5000"
            overflowToDisk="false"
            diskPersistent="false"
            timeToIdleSeconds="1800"
            timeToLiveSeconds="1800"
            memoryStoreEvictionPolicy="LRU"/>
    <!--
    defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策
    略。只能定义一个。
    -->
    <!--
    name:缓存名称。
    maxElementsInMemory:缓存最大数目
    maxElementsOnDisk:硬盘最大缓存个数。
    eternal:对象是否永久有效,一但设置了,timeout将不起作用。
    overflowToDisk:是否保存到磁盘,当系统宕机时
    timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当
    eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
    timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建
    时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存
    活时间无穷大。
    diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store
    persists between restarts of the Virtual Machine. The default value is
    false.
    diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默
    认是30MB。每个Cache都应该有自己的一个缓冲区。
    diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
    memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将
    会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先
    出)或是LFU(较少使用)。
    clearOnFlush:内存数量最大时是否清除。
    memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、
    FIFO(先进先出)、LFU(最少访问次数)。
    FIFO,first in first out,这个是大家最熟的,先进先出。
    LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以
    来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
    LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容
    量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的
    元素将被清出缓存。
    -->
</ehcache>

测试结果还是和之前一样的。

5、问题

问题描述:当我们在mybatis的配置文件中,写好绑定Mapper.xml文件时,运行结果依旧提示找不到Mapper.xml或是没有绑定。
MyBatis 配置信息:
在这里插入图片描述

错误信息:
在这里插入图片描述
此时,我们可以查看target目录下的class文件夹,发现并没有编译出UserMapper.xml文件。
在这里插入图片描述
解决方法:主要原因就是Maven在导出资源失败,资源过滤出现问题。我们需要在pom.xml中添加防止一些指定的资源文件的过滤配置。

       <!-- 在build中配置resources。来防止我们资源导出失败的问题 资源过滤问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

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

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

相关文章

《绝地求生》提示d3dcompiler_47.dll缺失怎么修复win11,三个简易的修复方法

在打开《绝地求生》游戏的时候&#xff0c;报错提示“由于找不到d3dcompiler_47.dll”&#xff0c;“d3dcompiler_47.dll缺失”等问题&#xff0c;都是由于电脑系统的中的d3dcompiler_47.dll文件丢失或者损坏了。d3dcompiler_47.dll 是 Microsoft 的 DirectX 11 核心组件之一&a…

彻底搞懂Linux中10位含义的文件权限以及修改文件权限

彻底搞懂Linux中10位含义的文件权限以及修改文件权限 1. 前言1.1 创建用户及简单权限问题1.2 抛出文件权限问题 2. 第二段&#xff08;连接数&#xff09;3. 第三段&#xff08;所属者&#xff09; 第四段&#xff08;所属组&#xff09;3.1 介绍Linux中的三种角色3.2 更改文件…

Kubernetes删除ns(namespace)

一、前言 删除某个应用或模块的时候&#xff0c;可能会出现命名空间的状态一直处于Terminating状态&#xff0c;无论是重启k8s还是重启所有服务器都没卵用。 k8s遇到有无法删除的ns&#xff08;namespace&#xff09;命名空间的时候&#xff0c;可以尝试几种删除方式 二、删…

zabbix拓扑图主机拓扑的分组设置

目录 一、需求描述 二、实现方法 &#xff08;一&#xff09;第一步 编辑拓扑图 &#xff08;二&#xff09;第二步 编辑形状 &#xff08;三&#xff09;第三步 点“更新” 一、需求描述 在zabbix-监测-拓扑图-服务器拓扑图中&#xff0c;需要按照各业务来分组展示&#…

「STC8A8K64D4开发板」第2-5讲:I/O中断

第2-5讲&#xff1a;I/O中断 学习目的学习中断的相关概念。掌握中断向量大于 31的处理方法。掌握中断服务程序的编写。 STC8A8K64D4 I/O中断 STC8A8K64D4单片机的所有GPIO都支持I/O 中断&#xff0c;且支持 4 种中断触发模式&#xff1a;下降沿中断、上升沿中断、低电平中断和…

Pegasus开发环境

文章目录 Pegasus开发环境开发环境部署步骤1 安装 vs code步骤2 DecEco Device Tool 下载安装步骤3 下载Hi3861 Openharmony SDK步骤4 下载开发者工具步骤5 工程管理配置1. 打开DevEco Device Tool 主页 导入工程2. 选择Hi3861 Openharmony SDK目录3. 芯片选型4. 进行后续代码开…

Spring ServiceLocatorFactoryBean 小结

前言 偶然看到一篇微信公众号文章的分享 https://mp.weixin.qq.com/s/11VKseROGVcJHPCJ8xQ3XA&#xff0c;感觉挺有意思&#xff0c;在这里记录下。 为什么感觉有意思呢&#xff1f;是因为它通过spring 提供的ServiceLocatorFactoryBean 来实现服务定位模式&#xff0c;将服务…

linux-2.6.22.6内核i2c驱动框架源码分析

i2c是常见的通信协议&#xff0c;协议比较简单&#xff0c;只有数据和时钟两条线&#xff08;SDA和SCL&#xff09;&#xff0c;i2c的通信分为主机和从机&#xff0c;主机一般占主导地位&#xff0c;从机可以有多个。 i2c通信的数据格式为(SDA上的数据)&#xff1a;开始的7位里…

【完美复现】面向配电网韧性提升的移动储能预布局与动态调度策略【IEEE33节点】(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

机器学习实战8-基于XGBoost和LSTM的台风强度预测模型训练与应用

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下机器学习实战8-基于XGBoost和LSTM的台风强度预测模型训练与应用&#xff0c;今年夏天已经来了&#xff0c;南方的夏天经常会有台风登陆&#xff0c;给人们生活带来巨大的影响&#xff0c;本文主要基于XGBoost模型和…

Python3 错误和异常 | 菜鸟教程(十五)

目录 一、简述 二、语法错误 三、异常 四、异常处理 &#xff08;一&#xff09;try/except 1、异常捕捉可以使用 try/except 语句。 2、以下例子中&#xff0c;让用户输入一个合法的整数&#xff0c;但是允许用户中断这个程序&#xff08;使用 Control-C 或者操作系统提供…

ChatGPT从入门到精通学习路线

课程名称适应人群 ChatGPT从入门到精通&#xff0c;一站式掌握办公自动化/爬虫/数据分析和可视 点击上述名称&#xff0c;学习完整视频 全面AI时代就在转角&#xff0c;道路已经铺好了“局外人”or“先行者”就在此刻等你决定 1、对ChatGPT感兴趣并希望有人手把手教学的新手 …

apex/amp 安装问题解决

如何安装&#xff1a; 首先 pip uninstall apex卸载、apex文件夹也删除&#xff0c; 重新安装&#xff0c;具体安装步骤如下&#xff1a; git clone https://www.github.com/nvidia/apex cd apex python setup.py install --cuda_ext --cpp_ext 只要出现了下面的语句就是完成…

人工智能数学基础2:利用SciPy中的数值积分常用函数求定积分

利用SciPy中的数值积分常用函数求定积分 21/82.625 方法一&#xff1a;在 SciPy 库中&#xff0c;可以使用 quad 函数来进行数值积分。具体实现代码如下&#xff1a; from scipy.integrate import quaddef integrand(x):return x**2 1/x**4 # 定义被积函数result, error q…

vue+leaflet笔记之地图卷帘

vueleaflet笔记之地图卷帘 本文介绍了Web端使用Leaflet开发库实现地图卷帘效果的方法 (底图来源:中科星图)&#xff0c;结合leaflet-side-by-side插件可以快速简单地实现地图分屏对比效果 &#xff0c;示例效果如下图所示。 开发环境 Vue开发库&#xff1a;3.2.37 & Leaf…

FPGA-DFPGL22学习5-VERILOG

系列文章之 上章 FPGA-DFPGL22学习4-仿真平台学习 文章目录 系列文章之 上章前言一、Verilog 简介二、Verilog基础1.逻辑值2.进制3.标识符4.数据类型寄存器类型线网类型参数类型 5.运算符 三、Verilog 程序框架1.注释2.关键字3.程序框架 四、Verilog 程序语句1.结构语句2.赋值…

微信小程序+SpringBoot接入后台服务,接口数据来自后端

前言 前两天开发了一个微信小程序项目&#xff0c;只不过接口数据是自己设置的假数据。然后我就想将这些假数据替换掉。这些数据来自接口&#xff0c;之前做过前后端分离的项目&#xff0c;我就想能不能直接调用那些后端数据接口。结果是可以的。以下是自己编写的部分方法 步骤…

卷积神经网络--猫狗系列之下载、导入数据集

(由于是学习&#xff0c;所以文章会有一些报错及解决办法) 在Kaggle()获取数据集&#xff1a;&#xff08;没有账号先去注册一个账号&#xff0c;在注册时可能会出现的问题见Kaggle注册出现一排“Captcha must be filled out.”&#xff01;&#xff09; https://www.kaggle.…

DOM编程事件与简单编程

文章目录 事件绑定绑定式事件监听方法event 事件对象client、offsetkeyCode 键盘事件事件冒泡阻止浏览器默认行为 DOM编程用户名输入框长度限制鼠标移入移出复选框全选DOM编程实现动态时钟第一种&#xff1a;第二种&#xff1a;第三种&#xff1a; 事件绑定 DOM编程中的事件&a…

excel只显示想要的内容

是 后面的FG等列是不需要的&#xff0c;选择F列&#xff0c;ctrl shift 右箭头 。选中后隐藏。