互联网轻量级框架整合之HibernateMyBatis

news2024/11/18 11:32:07

持久层框架

Hibernate

假设有个数据表,它有3个字段分别是id、rolename、note, 首先用IDEA构建一个maven项目Archetype选择org.apache.maven.archetypes:maven-archetype-quickstart即可,配置如下pom

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>ChapterNew</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>ChapterNew</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>

    <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
    <dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <version>8.3.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
    <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-core</artifactId>
      <version>5.3.7.Final</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>


  </dependencies>
  <build>
    <!--读取配置文件-->
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
      </resource>
    </resources>
  </build>
</project>

根据这个角色表,建立一个POJO(Plain Ordinary Java Object)和这张表的字段对应起来

package com.ssm;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable;
@Entity  //实体类
public class Role implements Serializable{
    @Id //主键
    @GeneratedValue(strategy = GenerationType.AUTO)  //自增
    private int id;
    private String roleName;
    private String note;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }
}


无论是MyBatis还是Hibernate都是依靠某种方法,将数据库的表和POJO映射起来,然后工程师通过操作POJO来完成逻辑开发

数据表有了,POJO类有了,将他们建立起映射关系,则需要提供映射规则,无论是MyBatis或Hibernate都可以使用注解或者XML的方式提供映射规则,因为注解有一定的局限性,通常都会使用XML来完成表和POJO之间的映射规则设定,这就是POJO对象和数据库表相互映射的框架,即对象关系映射(Object Relational Mapping, ORM)框架

无论是MyBatis还是Hibernate都可以被称为ORM框架,只是Hibernate的设计理念完全面向POJO,而MyBatis不是,Hibernate基本不需要编写SQL就可以通过映射关系来操作数据库,它是一种全映射的体现;而MyBatis不同,它需要工程师编写SQL来运行,也因此体现出了两者的很大的区别,MyBatis灵活,几乎可以完全代替JDBC,同时提供了接口编程,MyBatis的数据访问层DAO(Data Access Objects)是不需要实现类的,它只需要一个接口和XML(或者注解),MyBatis提供自动映射、动态SQL、级联、缓存、注解、代码和SQL分离,也因此可以对SQL进行优化,也正是因为其封装少,映射多样化,支持存储过程,可以进行SQL优化等特点,使得他取代Hibernate成为首选

以下是一个基于Hibernate框架的Java Persistence Object (POJO)类与数据库表之间的映射文件示例,假设我们要为一个名为User的实体类创建映射。该映射文件通常命名为User.hbm.xml,并放置在项目的资源目录中,以便被Hibernate自动加载

<!-- t_role.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.ssm.Role" table="t_role">

        <!-- 定义主键 -->
        <id name="id" type="int">
            <column name ="id"/>
            <generator class="identity"/>
        </id>

        <!-- 定义属性映射 -->
        <property name="roleName" type="string">
            <column name="rolename" length="60" not-null="true"/>
        </property>
        <property name="note" type="string">
            <column name="note" length="255"/>
        </property>

        <!-- 如果存在一对多关系,例如每个用户有多个订单 -->
        <!-- <set name="orders" inverse="true" cascade="all-delete-orphan">
            <key column="user_id"/>
            <one-to-many class="com.example.entity.Order"/>
        </set> -->

        <!-- 如果存在一对一关系,例如每个用户有一个头像 -->
        <!-- <one-to-one name="profilePicture" class="com.example.entity.ProfilePicture" cascade="all"/> -->

        <!-- 如果存在多对一关系,例如每个用户属于一个角色 -->
        <!-- <many-to-one name="role" column="role_id" class="com.example.entity.Role" not-null="true"/> -->

        <!-- 如果存在多对多关系,例如每个用户可以关注其他多个用户 -->
        <!-- <bag name="followingUsers" table="user_following">
            <key column="follower_id"/>
            <many-to-many column="following_id" class="com.example.entity.User"/>
        </bag> -->

    </class>
</hibernate-mapping>

解析说明:

  • DOCTYPE声明:指定了使用的Hibernate映射文件DTD版本,确保XML语法正确性。
  • <hibernate-mapping>标签:整个映射配置文件的根节点。
  • <class>标签:
    • name属性指定对应的Java POJO类全名。
    • table属性指定对应的数据库表名。
  • <id>标签:
    • 定义实体类的主键字段。此处以long类型的id为例,对应数据库表中的id列。
    • generator class=“identity” 在Hibernate映射文件中表示所映射的实体类主键字段的生成策略使用数据库的内置标识符生成机制。
  • <property>标签:
    • 对应POJO类中的非主键属性与数据库表中相应列的映射。
    • name属性指定POJO类中的属性名。
    • column属性指定数据库表中的列名。
    • type属性指定数据类型,如string、long、timestamp等。
    • 可选属性如length定义字符串长度限制,not-null和unique分别设置是否允许为空和唯一性约束。
  • 关联关系映射(已注释掉,根据实际需求启用):
    • <set>、<one-to-one>、<many-to-one>、<bag>等标签用于定义不同类型的关联关系,如一对多、一对一、多对一、多对多。
    • 关联关系的具体配置包括关系名称、外键列、目标类、级联操作等。

请根据实际项目中的Role类及其关联关系调整上述映射文件内容。如有其他复杂特性(如继承、嵌套集合等),还需添加相应的映射元素进行配置

Hibernate核心配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <!-- 第一部分: 配置数据库信息 必须的 -->
            <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
            <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/ssm1</property>
            <property name="hibernate.connection.username">root</property>
            <property name="hibernate.connection.password">Ms123!@#</property>
            <!-- 使用MYSQL的 innodb引擎 -->
            <property name="hibernate.dialect.storage_engine">innodb</property>

            <!-- 第二部分: 配置hibernate信息  可选的-->
            <!-- 输出底层sql语句 -->
            <property name="hibernate.show_sql">true</property>
            <!-- 输出底层sql语句格式 -->
            <property name="hibernate.format_sql">true</property>
            <!-- hibernate帮创建表,需要配置之后
                update: 如果已经有表,更新,如果没有,创建
            -->
            <property name="hibernate.hbm2ddl.auto">update</property>
            <!-- 配置数据库方言
                在mysql里面实现分页 关键字 limit,只能使用mysql里面
                在oracle数据库,实现分页rownum
                让hibernate框架识别不同数据库的自己特有的语句
             -->
            <property name="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</property>
            <property name="hibernate.connection.autocommit">true</property>
            <!--
            for (non-JTA) DDL execution was not in auto-commit mode;
            the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
            -->
            <!-- 第三部分: 把映射文件放到核心配置文件中 必须的-->
            <mapping resource="mapper/t_role.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>

先对POJO和角色进行映射,再对POJO进行操作,从而影响角表的数据,如下代码所示

package com.ssm;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.Test;

/**
 * Unit test for simple App.
 */
public class RoleTest {
    @Test
    public void testInit() {
        StandardServiceRegistry registry = null;
        SessionFactory sessionFactory = null;
        Session session = null;
        Transaction transaction = null;
        try {
            //初始化注册服务对象
            registry = new StandardServiceRegistryBuilder()
                    .configure()//默认加载hibernate.cfg.xml,如果配置文件名称被修改:configure("被修改的名字")
                    .build();
            //获取Session工厂
            sessionFactory = new MetadataSources(registry)
                    .buildMetadata()
                    .buildSessionFactory();
            //从工厂创建Session连接
            session = sessionFactory.openSession();
            //开启事务
            transaction = session.beginTransaction();
            //创建事例
            Role role = new Role();
            role.setRoleName("zhang");
            role.setNote("123");
            session.save(role);
            //提交事务
            transaction.commit();

        } catch (HibernateException e) {
            e.printStackTrace();
            //回滚事务
            transaction.rollback();
        } finally {
            if(session!=null && session.isOpen())
                //关闭session
                session.close();
        }

    }
}

代码中并未写任何SQL,因为Hibernate会根据映射关系生成对应的SQL,应用系统首先考虑的是业务逻辑实现,然后才是性能提升,使用Hibernate的建模方式非常有利于业务分析,因此Hibernate一度成为主流选择

至此一个简单的Hibernate的框架就可以运转起来了,项目结构如下
在这里插入图片描述

MyBatis

前面已经讲了几句MyBatis和Hibernate的些许区别,应该说MyBatis不屏蔽SQL,让它更具灵活性但复杂度也随之而来,但在优化SQL的层面上缺存在巨大的差别,而SQL操作数据往往是系统瓶颈的重要维度之一,因此MyBatis框架逐渐成为了当前Java互联网持久层的首选,它更符合移动互联网高并发、大数据、高性能、快响应的要求,程序员可以自定制定SQL规则,而不是由Hibernate自动生成规则

与Hibernate一样,MyBatis需要一个映射文件把POJO和角色表对应起来,项目结构及代码如下
在这里插入图片描述

<?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">

<mapper namespace="com.ssm.RoleMapper">
    <resultMap id="roleMap" type="com.ssm.Role">
        <id property="id" column="id"/>
        <result property="roleName" column="roleName"/>
        <result property="note" column="note"/>
    </resultMap>

        <!-- 插入Role -->
    <insert id="insertRole" parameterType="com.ssm.Role">
        INSERT INTO t_role(roleName, note) VALUES (#{roleName}, #{note})
    </insert>

        <!-- 根据ID查询Role -->
    <select id="getRoleById" parameterType="int" resultMap="roleMap">
        SELECT * FROM t_role WHERE id = #{id}
    </select>

        <!-- 更新Role -->
    <update id="updateRole" parameterType="com.ssm.Role">
        UPDATE t_role SET roleName = #{roleName}, note = #{note} WHERE id = #{id}
    </update>

        <!-- 删除Role -->
    <delete id="deleteRole" parameterType="int">
        DELETE FROM t_role WHERE id = #{id}
    </delete>
</mapper>

解析说明
在这个MyBatis的Mapper XML文件中:

  • <mapper>元素定义了命名空间(namespace),他要和一个接口的全限定名保持一致
  • resultMap用于定义映射规则,实际上当MyBatis满足一定的规则时,可以自动完成映射
  • 对于每个CRUD操作,分别使用了<insert><select><update><delete>标签来编写SQL语句。
  • id属性指定了在Mapper接口中对应的方法名,也要完全保持一致
  • parameterType属性指定传递给SQL语句的参数类型,这里是com.example.pojo.Role或long。
  • resultType属性(仅在SELECT语句中使用)指定查询结果应映射到的Java类型,也可以类似于XML所写,指定resultMap,Java类在resultMap里指定,这里是com.ssm.pojo.Role
//定义MyBatis映射接口
package com.ssm;
import com.ssm.Role;
public interface RoleMapper {
    public Role getRoleById(int id);
    public int deleteRole(int id);
    public int updateRole(Role role);
    public int insertRole(Role role);
}

//实体类
package com.ssm;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import java.io.Serializable;
@Entity  //实体类
public class Role implements Serializable{
    @Id //主键
    @GeneratedValue(strategy = GenerationType.AUTO)  //自增
    private int id;
    private String roleName;
    private String note;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", roleName='" + roleName + '\'' +
                ", note='" + note + '\'' +
                '}';
    }
}



整条链路下来,显然MyBatis在业务逻辑上的实现和Hibernate是大同小异的,区别在于MyBatis需要提供接口和SQL,这意味着他的工作量会大于Hibernate,但由于自定义SQL、映射关系,所以其灵活性和可优化的属性超过了Hibernate 如何取舍完全取决于技术面向业务的业务对象的复杂度

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTDConfig3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="config.properties"/>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm1?useUnicode=true;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="Ms123!@#"/>
                -->
                <property name="driver" value="${className}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>

            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/t_role.xml"/>
    </mappers>
</configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTDConfig3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <properties resource="config.properties"/>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm1?useUnicode=true;characterEncoding=utf8"/>
                <property name="username" value="root"/>
                <property name="password" value="Ms123!@#"/>
                -->
                <property name="driver" value="${className}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>

            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/t_role.xml"/>
    </mappers>
</configuration>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>org.example</groupId>
  <artifactId>ChapterNewOne</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>ChapterNewOne</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
    <dependency>
      <groupId>com.mysql</groupId>
      <artifactId>mysql-connector-j</artifactId>
      <version>8.3.0</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.2</version>
    </dependency>
    <dependency>
      <groupId>javax.persistence</groupId>
      <artifactId>javax.persistence-api</artifactId>
      <version>2.2</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <build>
    <resources>
    <!--解决mybatis-generator-maven-plugin运行时没有将XxxMapper.xml文件放入target文件夹的问题-->
    <resource>
      <directory>src/main/resources</directory>
      <includes>
        <include>**/*.xml</include>
      </includes>
    </resource>
    <!--解决mybatis-generator-maven-plugin运行时没有将jdbc.properites文件放入target文件夹的问题-->
    <resource>
      <directory>src/main/resources</directory>
      <includes>
        <include>config.properties</include>
        <include>*.xml</include>
      </includes>
    </resource>
    </resources>

  </build>
</project>

//测试配置
package com.ssm;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.apache.ibatis.session.*;

import java.io.IOException;
import java.io.Reader;


public class RoleTest{
    @Test
    public void testInit() throws IOException {
        Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
        Role role = roleMapper.getRoleById(3);
        System.out.println(role);
        sqlSession.close();
    }

}

总结对比

  1. Hibernate和MyBatis的CRUD对于业务逻辑来说大同小异,对于映射层,Hibernate的配置不需要接口和SQL,而MyBatis需要
  2. Hibernate不需要编写大量的SQL就可以完全映射,同时提供了日志、缓存、级联(级联比MyBatis强大)等特性,此外还提供了HQL(Hibernate Query Language)对POJO进行操作使用起来很方便,但也存在致命缺陷,由于无须SQL,当关联超过3个表的时候,通过Hibernate的级联会造成很多性能的损失,例如财务表会关联财产信息表,财产信息表又细分为机械、原料等等,很显然这些字段是不一样的,关联字段只能根据特定的条件变化而变化,而Hibernate就不具备这样的灵活性;遇到存储过程Hibernate也无法很好地支持
  3. MyBatis可以自由编写SQL,支持动态SQL、处理列表、动态生成表名、支持存储过程,从而解决了以上Hibernate遇到的问题,更灵活的满足移动互联网的特性系统性能决定了用户忠诚度
  4. MyBatis需要编写SQL和映射规则,工作量会大于Hibernate,且它支持的工具很有限,而Hibernate有许多的插件可以帮助生成映射代码和关联关系,开发者只需要优化或者简化生成内容
  5. 对于性能要求不苛刻的系统,例如管理系统、ERP等使用Hibernate完全可以,对于性能要求较高的系统MyBatis更佳

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

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

相关文章

ERROR: tensorboard 1.14.0 has requirement setuptools>=41.0.0(问题解决)

问题描述&#xff1a; ERROR: tensorboard 1.14.0 has requirement setuptools>41.0.0, but youll have setuptools 39.2.0 which is incompatible. 问题原因&#xff1a; setuptools 版本太低 解决方法&#xff1a;升级setuptools版本 pip install --upgrade setuptools…

Notepad8.1.9汉化中文版

下载地址&#xff1a;Notepad8.1.9.zip 一款优秀免费的源代码编辑器&#xff0c;支持语法高亮的开源纯文本编辑器&#xff0c;并且可以替代系统自带的记事本的功能。

40V/300mA快速瞬态低压差线性稳压器替代ADP7142

概述(替代ADP7142/LT1962/LT1521/LT3060) PCD4900 是一款 CMOS、低压差&#xff08;LDO&#xff09;线性稳压器&#xff0c;采用 1.9V 至 40V 电源供电&#xff0c;最大输出电流为 300 mA。这款高输入电压 LDO 适用于调节 36V 至 1.2V 供电的高性能模拟和混合信号电路。该器件…

iOS copy的正确姿势

参考文章 知识准备&#xff08;理解堆栈&#xff09; 堆区&#xff1a; 程序员管理 若程序员不释放&#xff0c;由os释放不同于数据结构中的堆&#xff0c;堆区的结构类似于数据结构中的链表栈区&#xff1a; 由编译器来管理 存放函数参数值&#xff0c;局部变量的值等结构类似…

C语言(指针)7

Hi~&#xff01;这里是奋斗的小羊&#xff0c;很荣幸各位能阅读我的文章&#xff0c;诚请评论指点&#xff0c;关注收藏&#xff0c;欢迎欢迎~~ &#x1f4a5;个人主页&#xff1a;小羊在奋斗 &#x1f4a5;所属专栏&#xff1a;C语言 本系列文章为个人学习笔记&#x…

nestjs封装一个响应体

封装一个DTO // response.dto.tsimport {CallHandler,ExecutionContext,Injectable,NestInterceptor, } from "nestjs/common"; import { FastifyReply } from "fastify"; import { Observable } from "rxjs"; import { map } from "rxjs/…

苹果macOS无法给App麦克风授权解决办法

好久没有在电脑上录制课程了&#xff0c;有些东西还是录下来记忆深刻&#xff0c;却意外发现MAC系统升级后无法授权给第三方的App使用摄像头和麦克风&#xff0c;而录屏软件是需要开启麦克风和摄像头才能录制屏幕上的操作和声音&#xff0c;官方提示在第三方APP若有使用摄像头和…

echarts切换tab,图表设置宽度100%结果为100px

当外层div盒子设置宽度为100%时&#xff0c;可echarts渲染出来宽度只有100px&#xff0c;这种情况大多数echarts所在的div设置了display:none&#xff0c;获取不到外部盒子的宽度。 这里可以通过echarts源码获取宽度的行为来解释 究其原因就是出现在了图表设置了display:none…

【从零开始实现stm32无刷电机foc】【理论】【1/6 电机旋转本质】

目录 电机旋转需要什么样的力&#xff1f;怎么产生力矢量&#xff1f;怎么产生任意的线圈磁矢量&#xff1f; 电机旋转需要什么样的力&#xff1f; 电机切向存在受力&#xff0c;电机就会旋转。 进一步查看电机结构&#xff0c;分为转子和定子&#xff0c;大部分情况下&#…

超级简单的地图操作工具开发可疑应急,地图画点,画线,画区域,获取地图经纬度等

使用echars的地图画点,画线,画区域,获取地图经纬度等 解压密码:10086007 地图也是用临时的bmap.js和china.js纯离线二选一 一共就这么多文件 画点,画线,画区域 点击地图获取经纬度-打印到控制台,这样就能渲染航迹,多变形,结合其他算法算圆等等操作 下载资源:https://download…

ROS2 conda 环境下报 No module named ‘catkin_pkg‘

这里使用的环境是&#xff1a;Ubuntu 22.04, ROS2, Conda python 虚拟环境是3.10 ~/.bashrc 里注释掉 conda&#xff0c;并添加 export PYTHONPATH$PYTHONPATH:/usr/lib/python3/dist-packages sudo gedit ~/.bashrc source ~/.bashrc

使用Remix部署智能合约到币安链(Remix的操作介绍 币安链合约的部署) 点赞收藏哦

大家好&#xff0c;我是程序员大猩猩呀。 据我所知&#xff0c;很多人进入币圈之后&#xff0c;想要通过炒币一夜暴富&#xff01;另一部分人呢他们希望自己能创建一个项目&#xff0c;然后发行自己的数字货币然后暴富。 不管是什么方式吧&#xff0c;只要不违法&#xff0c;…

Spring框架中常见注解

Spring&#xff1a; SpringMVC&#xff1a; RequestMapping用在类上表示所有该类下方法的父路径 RequestParam 做映射&#xff0c;前端请求的参数映射到控制器Controller的处理方法上的参数上。 【当参数需要设置默认值&#xff08;前端没有发送这个参数&#xff09;、参数名…

面对.halo勒索病毒,如何有效防范与应对?

导言&#xff1a; 随着网络技术的不断发展&#xff0c;网络安全问题也日益凸显。其中&#xff0c;勒索病毒作为一种极具破坏性的网络攻击手段&#xff0c;近年来在全球范围内频发。其中&#xff0c;.halo勒索病毒作为勒索病毒家族中的一员&#xff0c;其危害性和传播性不容忽视…

供水设备数据采集

随着城市化进程的加快&#xff0c;供水系统作为城市基础设施的重要组成部分&#xff0c;其运行效率和稳定性直接关系到市民的日常生活。在这个信息化、智能化的时代&#xff0c;如何利用先进技术提升供水系统的管理水平&#xff0c;成为了摆在我们面前的重要课题。HiWoo Cloud平…

链表----带环链表快慢指针进阶版

1.带环链表及其拓展 &#xff08;1&#xff09;这个题目组要就是进行判断这个链表是否带环&#xff0c;使用的是布尔类型作为返回值&#xff1b; &#xff08;2&#xff09;我们这里的思路是使用的快慢指针&#xff0c;快指针一次走2步&#xff0c;慢指针一次走1步&#xff0c…

泰山众筹:创新电商模式引领共赢新潮流

一、泰山众筹模式创新解读 泰山众筹&#xff0c;这一电商领域的创新模式&#xff0c;通过巧妙地将产品销售与积分众筹相结合&#xff0c;为用户和平台带来了双赢的局面。在泰山众筹模式下&#xff0c;用户购买产品的同时能够积累积分&#xff0c;这些积分可以作为参与众筹的筹…

MySQL旧表做分区流程

1. 为什么做分区 数据库分区是将数据库中的数据划分成独立的部分&#xff0c;每个部分称为一个分区。分区可以根据特定的标准&#xff0c;如范围、列表或哈希值&#xff0c;将数据分隔到不同的物理存储位置中。数据库表分区可以在多种情况下提供显著的好处。以下是一些应该考虑…

Windows安装Linux子系统

WSL 是 Windows Subsystem for Linux 的简称&#xff0c;意思是 linux 版的 window 子系统。适用于 Linux 的 Windows 子系统可让开发人员按原样运行 GNU/Linux 环境 - 包括大多数命令行工具、实用工具和应用程序 - 且不会产生传统虚拟机或双启动设置开销。 Linux 分发版可以在…

Windows Server 2022 环境下WEB和DNS服务器配置方法

目录 实验名称&#xff1a;WEB和DNS服务器配置实验目的实验原理&#xff1a;主要设备、器材&#xff1a;实验内容&#xff1a;配置本地WEB站点配置本地DNS服务器 实验名称&#xff1a;WEB和DNS服务器配置 实验目的 掌握 Windows Server 2022 环境下WEB服务器配置方法 掌握 Wi…