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

持久层框架

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更佳

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

应用FMEA打造零风险供应链的关键因素有哪些?

当下&#xff0c;构建零风险的供应链已成为企业竞争的核心要素。其中&#xff0c;FMEA&#xff08;故障模式与影响分析&#xff09;作为一种预防性的质量工具&#xff0c;对于识别和消除潜在风险&#xff0c;优化供应链流程至关重要。本文&#xff0c;天行健六西格玛管理培训公…

sklearn的make_blobs函数

make_blobs是一个用于生成随机数据点的实用函数&#xff0c; from sklearn.datasets import make_blobs X,Y make_blobs(n_samples2000,n_features2,centers12,cluster_std0.05,center_box[-5,5],random_state21)n_samples: 要生成的样本数量。centers: 要生成的簇&#xff0…

linux文本三剑客之awk

目录 1、特点与应用场景 2、awk命令执行流程 3、awk行与列 1)awk取行 2)awk取列 3)awk行与列综合使用 4、awk模式匹配-正则匹配 5、awk模式匹配-范围模式 6、awk模式匹配-特殊模式 7、awk数组* 1) 用途 2&#xff09;格式对比 8、awk循环与判断 1、特点与应用场景…

App测试基本流程以及注意事项

1 APP测试基本流程 1.1流程图 1.2测试周期 测试周期可按项目的开发周期来确定测试时间&#xff0c;一般测试时间为两三周&#xff08;即15个工作日&#xff09;&#xff0c;根据项目情况以及版本质量可适当缩短或延长测试时间。 1.3测试资源 测试任务开始前&#xff0c;检查…

Neo4j+LLM+RAG 环境配置报错处理

开发KGLLMRAG程序时遇到以下报错&#xff0c;记录下处理方案&#xff1a; ValueError: Could not use APOC procedures. Please ensure the APOC plugin is installed in Neo4j and that ‘apoc.meta.data()’ is allowed in Neo4j configuration 这个参考文章&#xff1a;link…

【平台开发】MTK6833——cache操作记录

CPU Cache 用的是一种叫 SRAM&#xff08;Static Random-Access Memory&#xff0c;静态随机存储器&#xff09; 的芯片。 通常分为L1&#xff0c;L2&#xff0c;L3三层缓存。 CPU 并不会直接和每一种存储器设备直接打交道&#xff0c;而是每一种存储器设备只和它相邻的存储器…

vue2 Avoided redundant navigation to current location

再次点击同一个链接会报错 每次使用 push 方法时带上两个回调函数 this.$router.push({name: item.name}, ()>{}, ()>{}) //第二、第三个参数分别为成功和失败的回调函数重写 Vue-router 原型对象上的 push 函数不行 https://blog.csdn.net/weixin_43615570/article/d…

python入门demo实例-个人信息收集页面实现

dd 今天是python入门day2&#xff0c;先看一下本案例demo的样子吧~ 一个简单得html页面&#xff0c;个人信息收集界面。 案例介绍常用得input 元素 文本框&#xff0c;密码&#xff0c;邮箱。文件上传等实现。 资源下载&#xff1a;python案例demo个人信息收集页面实现资源-…

微信公众号有哪些类型,微信服务号和订阅号有哪些区别

什么是微信公众号&#xff1f; 微信公众号是国内社交媒体平台微信上的公众账号。它们是允许公司发布内容&#xff0c;收集追随者并推广其产品或服务的商业帐户。微信公众号主要有两种类型&#xff1a;订阅账号和服务账号。 微信月活跃用户突破12亿 微信最近达到了平台上的月活…

jmeter利用自身代理录制脚本

在利用代理录制脚本时一定要安装java jdk&#xff0c;不然不能录制的。 没有安装过java jdk安装jmeter后打开时会提示安装jdk&#xff0c;但是mac系统中直接打开提示安装jdk页面后下载的java并不是jdk&#xff08;windows中没有试验过&#xff0c;笔者所说的基本全部指的是在ma…

区块链 | NFT 水印:Review on Watermarking Techniques(二)

&#x1f34d;原文&#xff1a;Review on Watermarking Techniques Aiming Authentication of Digital Image Artistic Works Minted as NFTs into Blockchains 1 半脆弱和可逆水印 鲁棒性好的水印技术通常会产生非常低透明度。正如前面所述&#xff0c;由于透明度在处理数字…

智慧公厕:一个让城市公共厕所更智能、更便利的信息化方案

公共厕所一直是城市管理中的一个难题。但是&#xff0c;随着科技的不断发展&#xff0c;智慧公厕正在成为解决这个问题的全新方案。智慧公厕不仅具备传统公厕的基本功能&#xff0c;更是通过信息化技术&#xff0c;实现了空余智能引导、环境监测、资源消耗监测、安全防范管理、…

【数据分析面试】38.更新图书馆数据(Python)

题目 作为一名精通Python的图书管理员&#xff0c;你正在搭建一个更高效地更新图书数据的系统。 编写一个名为 update_availability 的函数&#xff0c;用于更新数据表中特定 book_id 的 availability 值&#xff0c;并返回更新后的数据表。 注意: 如果找不到 book_id&#…

如何缩小图片大小kb?6个压缩图片大小的软件教你快速压缩

如何缩小图片大小kb&#xff1f;6个压缩图片大小的软件教你快速压缩 当需要缩小图片的大小&#xff08;KB&#xff09;时&#xff0c;可以利用一系列专门设计的工具和软件来帮助完成这一任务。这些工具可以有效地减小图片的文件大小&#xff0c;而又不会明显降低图片的质量。以…

小麦穗检测数据集VOC+YOLO格式6508张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6508 标注数量(xml文件个数)&#xff1a;6508 标注数量(txt文件个数)&#xff1a;6508 标注…

MyBatis(XML映射器操作)

文章目录 XML映射器操作&#xff08;XxxMapper.xml&#xff09;文件目录1.基本介绍1.优点2.常用顶级元素 2.环境配置1.在原来的父模块下创建一个子模块2.删除没用的两个文件夹3.创建基本目录4.父模块的pom.xml5.jdbc.properties6.mybatis-config.xml7.测试使用MonsterMapperTes…

诛吕政变后,为何会是代王刘恒登上皇位?

公元前179年——这一年对于汉帝国而言是非常特殊的一年。在这一年&#xff0c;汉惠帝的所有儿子被秘密杀害。也就在这一年&#xff0c;远在北疆的诸侯王——代王刘恒在汉朝功臣周勃、丞相陈平等人的支持下在长安登基。 自此&#xff0c;汉朝皇位完成了一次“乾坤大挪移”——汉…

10、算数运算符(以 ‘/’、‘%’、‘++’为主去讲解)(Java超详细版本)

算数运算符 一、算数运算符二、“ / ”的使用三、“ % ”的使用四、“ ”的使用⭐ 一、算数运算符 算数运算符是对数值类型的变量进行运算的&#xff0c;在Java程序中使用的非常多的。 二、“ / ”的使用 1、Java中 “ / ” 的运算结果是省略小数部分的整数&#xff0c;不存…

2024年美国市场亚太游戏品牌数字广告洞察报告

来源&#xff1a;Sensor Tower 美国是全球最大的游戏市场之一&#xff0c;也是亚太游戏品牌出海的重要市场。2023年Q2至2024年Q1&#xff0c;美国市​场广告投放额排名前10的亚太游戏品牌&#xff0c;合计支出 超过7.5亿美元&#xff0c;环比上涨23%。 排名第一的米哈游(miHoY…

DES加密解密算法(简单、易懂、超级详细)

目录 一、基础补充 二、什么是DES算法 &#xff08;1&#xff09;对称加密算法 &#xff08;2&#xff09;非对称加密算法 &#xff08;3&#xff09;对称加密算法的应用 三、DES算法的基础操作步骤 1.明文的加密整体过程 2.F轮函数解析 3.密钥的形成过程 四、AC代码 五、D…