一篇文章读懂mybatis-plus原理和CRUD接口

news2024/11/22 9:41:53

Myabtis-Plus配置

MybatisPlus官网

官方文档上有详细的spring boot配置mybatis-plus的教程,此处就不在详细赘述。

mybatis-plus是基于spring完成的只能再spring相关应用上实现。

  1. 引入父工程

在这里插入图片描述
注意mybatis-plus和spring boot的版本匹配不然会出现
在这里插入图片描述

推荐版本

  <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>

参考pom依赖

  <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>


    </dependencies>

配置并连接数据库

  • 创建数据库表

在这里插入图片描述

  • 添加若干数据

在这里插入图片描述

  • application.properties中配置datasource

datasource是连接数据库必须的配置,数据库驱动包通过反射来加载这些信息

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://139.9.209.93/task?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true

  • ORM映射

将数据库表映射到java的对象中,实现信息交换。

@Data
@TableName("bt_04")
public class BT_04 {

    @TableId(value = "opt_id")
    private Integer id;

    @TableField("drag_start_lat")
    private Double DragStartLat;

    @TableField("drag_start_lon")
    private Double DragStartLon;

    @TableField("drag_end_lat")
    private Double DragEndLat;

    @TableField("drag_end_lon")
    private Double DragEndLon;
}

注意@TableName@TableField相辅相成共同完成ORM映射。后者辅助前者。

名称作用备注
@TableName完成数据库表到对象的映射位于bean的开头参数为数据库表名
@TableField完成字段到属性的映射mp默认下划线命名到驼峰命名转换,遵守规则可以省去该注解,参数为对象属性
@TableId完成主键的映射参数可以设置自增等条件

car_name[下环线命名]
carName[驼峰命名]
mybatis-plus默认前者转后者。

mp作为myabtis的升级版延续了前身的注解,也扩展了许多新的注解

在这里插入图片描述
具体请参考官网 MyBatis-Plus

之前已经通过@TableFieId注解将数据库表实现映射了,而关系的桥梁就是sql,那么如何应用sql呢?
通过mybatis的mapper接口和mapper映射文件关联即可。但是mp有更好的方法就是BaseMapper
一个BaseMapper管理一个映射关系。

myabtis

public interface BTfourMapper {    //extends BaseMapper<BT_04>

    @Select("select * from bt_04")
    List<BT_04> query();
}

mybatis-plus

public interface BTfourMapper extends BaseMapper<BT_04>{ 
    
}

通过BaseMapper的泛型映射后无需编写sql语句更方便。

可以看到BaseMapper中定义了很多接口来满足常规需求

在这里插入图片描述

因此只要集成该接口就可以调用方法,由于泛型的绑定实现了表的唯一性。

BaseMapper的CRUD接口

public interface BTfourMapper extends BaseMapper<BT_04>{

}

任意接口继承BaseMapper就可以使用其方法,在通过泛型绑定变成相关表的专属mapper,例如

//mybatis

public interface UserMapper{
	/**
	*相关CURD操作
	*/
	
	List<User> queryAll();

	...
		
	//每个查询返回结果使用泛型接收,所以mapper下的有需要的都要写
}


//mybatis-plus
public interface UserMapper extends BaseMapper<User>{
} 

//在接口处使用泛型,后续直接使用

BaseMapper的具体方法及使用参考官网

mapper实例:

@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class BTtest {

    @Autowired
    BTfourMapper bTfourMapper;

    @Test
    public void method(){
        List<BT_04> bt_04s = bTfourMapper.selectList(null);
        System.out.println(bt_04s);

    }
}

在该单元测试中自动装配的mapper为一个只集成BaseMapper的接口,selectList为接口super的方法,参数为一个Wraper(查询条件包装),没有填null。

在这里插入图片描述

BaseMapper中包含了基本的CURD操作,其实就是对mapper做了一个包装,因为每个mapper无外乎都是CURD操纵,具有统一型,面向不同的对象又具有多样性,包装后的mapper具有通用性。---- 感谢开发团队 😮

下面是BaseMapper的源码:

public interface BaseMapper<T> {
    int insert(T entity);

    int deleteById(Serializable id);

    int deleteByMap(@Param("cm") Map<String, Object> columnMap);

    int delete(@Param("ew") Wrapper<T> wrapper);

    int deleteBatchIds(@Param("coll") Collection<? extends Serializable> idList);

    int updateById(@Param("et") T entity);

    int update(@Param("et") T entity, @Param("ew") Wrapper<T> updateWrapper);

    T selectById(Serializable id);

    List<T> selectBatchIds(@Param("coll") Collection<? extends Serializable> idList);

    List<T> selectByMap(@Param("cm") Map<String, Object> columnMap);

    T selectOne(@Param("ew") Wrapper<T> queryWrapper);

    Integer selectCount(@Param("ew") Wrapper<T> queryWrapper);

    List<T> selectList(@Param("ew") Wrapper<T> queryWrapper);

    List<Map<String, Object>> selectMaps(@Param("ew") Wrapper<T> queryWrapper);

    List<Object> selectObjs(@Param("ew") Wrapper<T> queryWrapper);

    IPage<T> selectPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);

    IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param("ew") Wrapper<T> queryWrapper);
}

需要注意的是使用BaseMapper一定要加上泛型。

Model的CRUD接口

细心的朋友可能就发现使用mapper时都有相应的xml的文件映射呀,或者相应的注解绑定着sql语句呀?

是的,上面的实例并未出现sql语句,是如何实现了的呢?对于CURD操作也是具有相似性的,例如

// 表a查询

select username,password,status from user

//查询表2

select code,name,status from sys_dict

同理只要将表的字段与对应sql的条件对应上也就具通用性,如下所示:

package com.baomidou.mybatisplus.core.enums;

public enum SqlMethod {
    INSERT_ONE("insert", "插入一条数据(选择字段插入)", "<script>\nINSERT INTO %s %s VALUES %s\n</script>"),
    DELETE_BY_ID("deleteById", "根据ID 删除一条数据", "<script>\nDELETE FROM %s WHERE %s=#{%s}\n</script>"),
    DELETE_BY_MAP("deleteByMap", "根据columnMap 条件删除记录", "<script>\nDELETE FROM %s %s\n</script>"),
    DELETE("delete", "根据 entity 条件删除记录", "<script>\nDELETE FROM %s %s\n</script>"),
    DELETE_BATCH_BY_IDS("deleteBatchIds", "根据ID集合,批量删除数据", "<script>\nDELETE FROM %s WHERE %s IN (%s)\n</script>"),
    LOGIC_DELETE_BY_ID("deleteById", "根据ID 逻辑删除一条数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),
    LOGIC_DELETE_BY_MAP("deleteByMap", "根据columnMap 条件逻辑删除记录", "<script>\nUPDATE %s %s %s\n</script>"),
    LOGIC_DELETE("delete", "根据 entity 条件逻辑删除记录", "<script>\nUPDATE %s %s %s\n</script>"),
    LOGIC_DELETE_BATCH_BY_IDS("deleteBatchIds", "根据ID集合,批量逻辑删除数据", "<script>\nUPDATE %s %s WHERE %s IN (%s) %s\n</script>"),
    UPDATE_BY_ID("updateById", "根据ID 选择修改数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),
    UPDATE("update", "根据 whereEntity 条件,更新记录", "<script>\nUPDATE %s %s %s\n</script>"),
    LOGIC_UPDATE_BY_ID("updateById", "根据ID 修改数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),
    LOGIC_UPDATE_ALL_COLUMN_BY_ID("updateAllColumnById", "根据ID 选择修改数据", "<script>\nUPDATE %s %s WHERE %s=#{%s} %s\n</script>"),
    SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s}"),
    SELECT_BY_MAP("selectByMap", "根据columnMap 查询一条数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "<script>\nSELECT %s FROM %s WHERE %s IN (%s)\n</script>"),
    SELECT_ONE("selectOne", "查询满足条件一条数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_COUNT("selectCount", "查询满足条件总记录数", "<script>\nSELECT COUNT(%s) FROM %s %s\n</script>"),
    SELECT_LIST("selectList", "查询满足条件所有数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_PAGE("selectPage", "查询满足条件所有数据(并翻页)", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_MAPS("selectMaps", "查询满足条件所有数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_MAPS_PAGE("selectMapsPage", "查询满足条件所有数据(并翻页)", "<script>\nSELECT %s FROM %s %s\n</script>"),
    SELECT_OBJS("selectObjs", "查询满足条件所有数据", "<script>\nSELECT %s FROM %s %s\n</script>"),
    LOGIC_SELECT_BY_ID("selectById", "根据ID 查询一条数据", "SELECT %s FROM %s WHERE %s=#{%s} %s"),
    LOGIC_SELECT_BATCH_BY_IDS("selectBatchIds", "根据ID集合,批量查询数据", "<script>\nSELECT %s FROM %s WHERE %s IN (%s) %s\n</script>");

    private final String method;
    private final String desc;
    private final String sql;

    private SqlMethod(String method, String desc, String sql) {
        this.method = method;
        this.desc = desc;
        this.sql = sql;
    }

    public String getMethod() {
        return this.method;
    }

    public String getDesc() {
        return this.desc;
    }

    public String getSql() {
        return this.sql;
    }
}

SqlMethod是mybatis封装sql的类,位于com.baomidou.mybatisplus.core.enums包下该类的返回值是一个集合。通过SqlMethod.获取需要的sql语句。

SqlMethod不是泛型没有通用性,还需要包装类对其解析封装并具有泛型,这个类就是Model

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.baomidou.mybatisplus.extension.activerecord;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Assert;
import com.baomidou.mybatisplus.core.toolkit.GlobalConfigUtils;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.TableInfoHelper;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.SqlSessionUtils;

public abstract class Model<T extends Model> implements Serializable {
    private static final long serialVersionUID = 1L;

    public Model() {
    }

    public boolean insert() {
        SqlSession sqlSession = this.sqlSession();

        boolean var2;
        try {
            var2 = SqlHelper.retBool(sqlSession.insert(this.sqlStatement(SqlMethod.INSERT_ONE), this));
        } finally {
            this.closeSqlSession(sqlSession);
        }

        return var2;
    }

    public boolean insertOrUpdate() {
        return !StringUtils.checkValNull(this.pkVal()) && !Objects.isNull(this.selectById(this.pkVal())) ? this.updateById() : this.insert();
    }

    public boolean deleteById(Serializable id) {
        SqlSession sqlSession = this.sqlSession();

        boolean var3;
        try {
            var3 = SqlHelper.delBool(sqlSession.delete(this.sqlStatement(SqlMethod.DELETE_BY_ID), id));
        } finally {
            this.closeSqlSession(sqlSession);
        }

        return var3;
    }

    public boolean deleteById() {
        Assert.isFalse(StringUtils.checkValNull(this.pkVal()), "deleteById primaryKey is null.", new Object[0]);
        return this.deleteById(this.pkVal());
    }

    public boolean delete(Wrapper<T> queryWrapper) {
        Map<String, Object> map = new HashMap(1);
        map.put("ew", queryWrapper);
        SqlSession sqlSession = this.sqlSession();

        boolean var4;
        try {
            var4 = SqlHelper.delBool(sqlSession.delete(this.sqlStatement(SqlMethod.DELETE), map));
        } finally {
            this.closeSqlSession(sqlSession);
        }

        return var4;
    }

    public boolean updateById() {
        Assert.isFalse(StringUtils.checkValNull(this.pkVal()), "updateById primaryKey is null.", new Object[0]);
        Map<String, Object> map = new HashMap(1);
        map.put("et", this);
        SqlSession sqlSession = this.sqlSession();

        boolean var3;
        try {
            var3 = SqlHelper.retBool(sqlSession.update(this.sqlStatement(SqlMethod.UPDATE_BY_ID), map));
        } finally {
            this.closeSqlSession(sqlSession);
        }

        return var3;
    }

    public boolean update(Wrapper<T> updateWrapper) {
        Map<String, Object> map = new HashMap(2);
        map.put("et", this);
        map.put("ew", updateWrapper);
        SqlSession sqlSession = this.sqlSession();

        boolean var4;
        try {
            var4 = SqlHelper.retBool(sqlSession.update(this.sqlStatement(SqlMethod.UPDATE), map));
        } finally {
            this.closeSqlSession(sqlSession);
        }

        return var4;
    }

    public List<T> selectAll() {
        SqlSession sqlSession = this.sqlSession();

        List var2;
        try {
            var2 = sqlSession.selectList(this.sqlStatement(SqlMethod.SELECT_LIST));
        } finally {
            this.closeSqlSession(sqlSession);
        }

        return var2;
    }

    public T selectById(Serializable id) {
        SqlSession sqlSession = this.sqlSession();

        Model var3;
        try {
            var3 = (Model)sqlSession.selectOne(this.sqlStatement(SqlMethod.SELECT_BY_ID), id);
        } finally {
            this.closeSqlSession(sqlSession);
        }

        return var3;
    }

    public T selectById() {
        Assert.isFalse(StringUtils.checkValNull(this.pkVal()), "selectById primaryKey is null.", new Object[0]);
        return this.selectById(this.pkVal());
    }

    public List<T> selectList(Wrapper<T> queryWrapper) {
        Map<String, Object> map = new HashMap(1);
        map.put("ew", queryWrapper);
        SqlSession sqlSession = this.sqlSession();

        List var4;
        try {
            var4 = sqlSession.selectList(this.sqlStatement(SqlMethod.SELECT_LIST), map);
        } finally {
            this.closeSqlSession(sqlSession);
        }

        return var4;
    }

    public T selectOne(Wrapper<T> queryWrapper) {
        return (Model)SqlHelper.getObject(this.selectList(queryWrapper));
    }

    public IPage<T> selectPage(IPage<T> page, Wrapper<T> queryWrapper) {
        Map<String, Object> map = new HashMap(2);
        map.put("ew", queryWrapper);
        map.put("page", page);
        SqlSession sqlSession = this.sqlSession();

        try {
            page.setRecords(sqlSession.selectList(this.sqlStatement(SqlMethod.SELECT_PAGE), map));
        } finally {
            this.closeSqlSession(sqlSession);
        }

        return page;
    }

    public Integer selectCount(Wrapper<T> queryWrapper) {
        Map<String, Object> map = new HashMap(1);
        map.put("ew", queryWrapper);
        SqlSession sqlSession = this.sqlSession();

        Integer var4;
        try {
            var4 = SqlHelper.retCount((Integer)sqlSession.selectOne(this.sqlStatement(SqlMethod.SELECT_COUNT), map));
        } finally {
            this.closeSqlSession(sqlSession);
        }

        return var4;
    }

    public SqlRunner sql() {
        return new SqlRunner(this.getClass());
    }

    protected SqlSession sqlSession() {
        return SqlHelper.sqlSession(this.getClass());
    }

    protected String sqlStatement(SqlMethod sqlMethod) {
        return this.sqlStatement(sqlMethod.getMethod());
    }

    protected String sqlStatement(String sqlMethod) {
        return SqlHelper.table(this.getClass()).getSqlStatement(sqlMethod);
    }

    protected Serializable pkVal() {
        return (Serializable)ReflectionKit.getMethodValue(this, TableInfoHelper.getTableInfo(this.getClass()).getKeyProperty());
    }

    protected void closeSqlSession(SqlSession sqlSession) {
        SqlSessionUtils.closeSqlSession(sqlSession, GlobalConfigUtils.currentSessionFactory(this.getClass()));
    }
}

有了Model后,直接使用该类可以进行CRUD,但是必须存在对应的mapper继承BaseMapper。基本步骤就是实体类继承Model添加泛型,对应Mapper继承BaseMapper,然后实体类对象也可以进行CRUD操作。

实例:

//实体类继承Model添加泛型
@TableName("user")
public class User extends Model<User> {

    @TableId
    private int id;

    @TableField("username")
    private String username;

    @TableField("password")
    private String password;
}
//对应接口继承BaseMapper
public interface UserMapper extends BaseMapper<User>{
}
//实体类直接调用方法
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class UserMapperTest {

    //@Autowired User user;

    @Test
    public void one(){
        User user = new User();
        List<User> users = user.selectList(null);
        System.out.println(users);
    }
}

Model调用CRUD的接口的限制是需要接收到实体类参数。

IService的CRUD接口

service调用方法基本方法比mapper层调用多了service层

//实体类
@TableName("user_address")
public class UserAddress {

    private int id;

    private int address_id;

    private String detail_address;

    private int user_id;

    private Date create_time;

    private Date update_time;

    private String name;

    private String phone;
}
//mapper层
public interface UserAddressMapper extends BaseMapper<UserAddress> {
}

mapper没有@MapperScan注解的话需要加@Component

service接口继承Iservice,并且service接口的实现类要继承ServiceImpl<xxxMapper,pojo>

//service层

//接口
public interface UserAddressService extends IService<UserAddress> {
}

//接口实现类
@Service
public class UserAddressServiceImpl extends ServiceImpl<UserAddressMapper, UserAddress>implements UserAddressService{
}

在这里插入图片描述

具体需要在那层调用要根据实际需求。

//测试
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class UserAddressTest {

    @Autowired
    UserAddressService userAddressService;

    @Test
    public void methodOne(){
        UserAddress one = userAddressService.getById(1);
        System.out.println(one);
    }
}

在这里插入图片描述

总结:

1、Model:使用映射类pojo继承model,直接使用该类可以进行CRUD,但是必须存在对应的mapper继承BaseMapper;

2、BaseMapper和Iservice
BaseMapper是使用dao层数据进行CRUD,只需要进行使用dao层接口继承BaseMapper即可;
Iservice是使用service层进行CRUD,需要使用service接口继承Iservice,并且service接口的实现类要继承ServiceImpl<xxxMapper,pojo>;

BaseMapper和Iservice里面提供的方法都差不多,只是Iservice提供了批量操作的实现,比如: 批量添加、批量修改。

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

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

相关文章

自媒体神器 Previs Shot 使用指南

Previs Shot 是一款影视创作的项目管理工具&#xff0c;更高效的方式开始您的影视创作历程。分镜表分镜表可高效绘制画面、编写景别、运镜、内容、台词等&#xff0c;甚至可以填写摄影器材、灯光等信息。分镜结构场景&#xff1a;电影里比如过生日、开party都是不同的场景&…

【程序员陪你过大年】html+css+js 实现动态新年烟花特效及服务器部署

前言 不知不觉又到了年底&#xff0c;这一年是值得庆贺的一年&#xff0c;疫情过去&#xff0c;经济好转。我们急需在春节这个特殊的日志释放下自己的情绪。但是大部分地区都不让放炮&#xff0c;于是乎我为大家带来一套十分炫酷应景的春节烟花动画代码实现。效果如下图所示 :…

【如何在Linux下使用Git命令在Gitee上创建项目】

目录 1 创建仓库 2 Git提交三板斧 2.1 add 2.2 commit 2.3 push 1 创建仓库 首先我们可以使用命令&#xff1a;git --version 来查看是否下在了git,没有下载的可以使用下面的命令安装&#xff1a; sudo yum install -y git 成功后就可以查看了&#xff1a; [grmVM-8-12-…

深度学习目标检测_YOLOV3超详细解读

文章目录YOLO V3概述网络结构backbone&#xff1a;darknet-53特征细化&#xff08;多scale&#xff09;残差连接残差网络的发家史先验框softmax改进YOLO V3概述 yolo v3论文地址&#xff1a;https://pjreddie.com/media/files/papers/YOLOv3.pdf 先说说yolo v3的效果&#xff…

字节青训营Go语言学习第二天-Go语言进阶与依赖管理

文章目录并行VS并发GoroutineCSPChannel并发安全LockWithGroupGo依赖管理GoPathGo VendorGo Module依赖分发-回源并行VS并发 并发指的是多线程在一个CPU上运行&#xff0c;而并行是直利用多核来实现多线程。 内核是系统里比较昂贵的系统资源&#xff0c;它的创建、切换停止都是…

K8s可视化界面Kubernetes DashboardKuboard

目录一、简介二、Kubernetes Dashboard2.1 部署dashboard2.2 访问UI2.3 创建访问账号三、Kuboard3.1 部署2.2 访问UI一、简介 本文给大家介绍两个K8s集群的可视化工具 Kubernetes Dashboard 和 Kuboard 二、Kubernetes Dashboard 2.1 部署dashboard dashboard Github地址&a…

【算法基础(2)】二分查找和斐波那契数列

二分查找 二分查找高效的前提是数据结构是有序的 思路&#xff1a; 1.排序 2.将数组折半&#xff0c;分成左右两个数组。 3.判断要查找的数和中间位置数值的大小&#xff0c;来判断要查找的数实在哪一半。 4.之后继续折半查找&#xff0c;直至找到这个数。 图解&#xff1a; 首…

SpringMVC看这一篇文章就够了

第一章 SpringMVC的简介 Spring框架版本 4.3.29.RELEASE SpringMVC是什么 1 2 3 4 5 61. Spring家族的一个部分 2. 是JavaWeb三层架构中控制器层的解决方案 3. 是基于MVC思想的框架-- Model-- View-- ControllerSpringMVC知识点大纲SpringMVC功能简述 1 2 3 4 5 6 7 8 9 101. 作…

WEB前端有必要学会docker吗?0基础-45分钟带你学会(包含视频笔记案例源代码)

文章目录一、为什么要使用docker二、Windows10/11系统安装Docker Desktop三、如何判断电脑已经安装好docker四、docker前端应用实战&#xff1a;将vue项目打包为docker镜像运行1、将vue的项目进行构建&#xff0c;输出dist2、准备镜像内容3、制作镜像4、启动镜像五、如何发布镜…

【Leetcode】面试题 01.02. 判定是否互为字符重排、面试题 01.04. 回文排列

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《Leetcode》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 面试题 01.02. 判定是否互为字符重排 面试题 01.04. 回文排列 面试题 …

水果店做微信活动推荐_分享水果店微信小程序制作步骤

试试做个小程序拯救你的店&#xff01;让你做出有效果的活动&#xff0c;每笔钱都花在刀刃上&#xff01;编辑第一&#xff0c;提升水果销量&#xff0c;降低损耗用水果店小程序做拼团、砍价、秒杀活动&#xff0c;并讲原本卖不完的水果&#xff0c;做成果盘吸引客人注册会员。…

点成分享|关于Grant水浴的一些FAQ

1、关于稳定性和均匀性 1&#xff09;稳定性&#xff0c;是水浴中任何一点在达到恒温时不同时间下的温度规律性波动程度的描述&#xff0c;是通过浴槽中心点测定的&#xff0c;并表示为测量值的正负一半。系同点不同时的温度特性描述。 例如&#xff1a;SAP恒温水浴设定温度为…

unreal engine建模模式建模研究

Create PolyExt 挤出(需要闭合) image.pngPathExt 具有宽度挤出 (无需闭合) 如下图绘制一个形状后按鼠标左键确定绘制完成再移动鼠标控制厚度按鼠标左键确定后端后再移动鼠标确定高度 image.pngimage.pngPathRev Draw and revolve polypaths to create new objects 画和旋转pol…

企业级监控项目Skywalking详细介绍,来看看呀

一. Skywalking概述一个优秀的项目&#xff0c;除了具有高拓展的架构、高性能的方案、高质量的代码之外&#xff0c;还应该在上线后具备多角度的监控功能。现在企业中的监控服务也有很多&#xff0c;Skywalking除了提供多维度、多粒度的监控之外&#xff0c;也提供了良好的图形…

Kotlin 元编程之 KSP 全面突破

什么是元编程 没想到吧&#xff0c;这世上除了元宇宙&#xff0c;还有元编程&#xff0c;如果没有接触过&#xff0c;可能会有点懵&#xff0c;不过没关系&#xff0c;简单的说就是用代码来生成代码。实现元编程的传统常见手段主要是使用 APT注解处理器 JavaPoet 组合拳&…

JAVA基础知识巩固训练

目录 1. 案例一&#xff1a;逢 7 跳过 2. 案例二&#xff1a;数组元素求和 3. 案例三&#xff1a;判断两个数组是否相同⭐ 4. 案例四&#xff1a;查找元素在数组中的索引 5. 案例五&#xff1a;数组元素反转 6. 案例六&#xff1a;评委打分 7. 案例七&#xff1a;随机产…

后端人眼中的Vue(五)

七、Vue生命周期 ​ Vue的生命周期指的是Vue实例在页面中创建到销毁整个过程。Vue提供了在各个生命周期的钩子&#xff0c;钩子也叫Vue生命周期函数。这些生命周期函数是伴随着Vue实例创建、销毁的过程中自动触发的&#xff08;不需要人为手动触发&#xff09;。Vue实例生命周期…

产业互联网:补齐互联网的「短板」,重启互联网的「进化」

尽管在互联网时代出现了诸多的乱象&#xff0c;但是&#xff0c;我们依然无法否认互联网时代给人们的生产和生活带来的影响和改变。即使如此&#xff0c;我们依然无法否认互联网本身其实是存在着诸多的问题和弊病的&#xff0c;这些问题和弊病所导致的一个最为直接的结果&#…

【opencv】二维面找角点/关键点 实现

every blog every motto: You can do more than you think. 0. 前言 二维面找角点/关键点 实现 1. 正文 1.1 前提 1.1.1 显示函数 def show(arr):plt.imshow(arr)plt.show()def cvshow(arr):cv2.namedWindow(a, 0)cv2.imshow(a, arr)cv2.waitKey(0)cv2.destroyAllWindows…

通关算法题之 ⌈链表⌋

链表 删除元素 203. 移除链表元素 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 示例&#xff1a; 输入&#xff1a;head [1,2,6,3,4,5,6], val 6 输出&#xff1a;[1,2,3,4,5]c…