MyBatisPlus之基本CRUD、常用注解

news2024/10/6 18:29:51

文章目录

  • 前言
  • 一、MyBatisPlus简介
    • 1.简介
    • 2.特性
  • 二、基本CRUD
    • 1.依赖
    • 2.搭建基本结构
    • 3.BaseMapper
    • 4.使用
      • 插入
      • 删除
        • (1)通过id删除记录
        • (2)通过id批量删除记录
        • (3)通过map条件删除记录
      • 修改
      • 查询
        • (1)根据id查询用户信息
        • (2)根据多个id查询多个用户信息
        • (3)通过map条件查询用户信息
        • (4)查询所有数据
      • 通用Service
        • (1)IService
        • (2)创建Service接口和实现类
        • (3)测试查询记录数
        • (4)测试批量插入
  • 三、常用注解
    • 1.@TableName
    • 2. @TableId
      • @TableId的value属性
      • @TableId的type属性
    • 3.@TableField
    • 4.@TableLogic
  • 总结


前言

MyBatis-Plus基本CRUD操作和常用注解讲解。


一、MyBatisPlus简介

1.简介

MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变为简化开发、提高效率而生

2.特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由
    配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、
    Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、
    Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

二、基本CRUD

1.依赖

注意在idea安装Lombok插件:setting–>Plugins–>搜索Lombok安装

   <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </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.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
    </dependencies>

2.搭建基本结构

application.yaml:

spring:
  # 配置数据源信息
  datasource:
    # 配置数据源类型
    type: com.zaxxer.hikari.HikariDataSource
    # 配置连接数据库信息
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_plus
    username: root
    password: root
# 配置MyBatis日志
mybatis-plus:
  configuration:
	log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

1、驱动类driver-class-name
spring boot 2.0(内置jdbc5驱动),驱动类使用:
driver-class-name: com.mysql.jdbc.Driver
spring boot 2.1及以上(内置jdbc8驱动),驱动类使用:
driver-class-name: com.mysql.cj.jdbc.Driver
否则运行测试用例的时候会有 WARN 信息
2、连接地址url
MySQL5.7版本的url:
jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
MySQL8.0版本的url:
jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
否则运行测试用例报告如下错误:
java.sql.SQLException: The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or
represents more

启动类:

@SpringBootApplication
@MapperScan("com.dragon.mybatisplus.mapper")
public class MyBatisPlusApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyBatisPlusApplication.class, args);
    }

}

实体:

@Data //lombok注解
public class User {
private Long id;
private String name;
private Integer age;
private String email;
}

mapper:

public interface UserMapper extends BaseMapper<User> {
}

文件结构:
在这里插入图片描述

3.BaseMapper

MyBatis-Plus中的基本CRUD在内置的BaseMapper中都已得到了实现,我们可以直接使用,接口如下:

package com.baomidou.mybatisplus.core.mapper;
public interface BaseMapper<T> extends Mapper<T> {
/**
* 插入一条记录
* @param entity 实体对象
*/
int insert(T entity);
/**
* 根据 ID 删除
* @param id 主键ID
*/
int deleteById(Serializable id);
/**
* 根据实体(ID)删除
* @param entity 实体对象
* @since 3.4.4
*/
int deleteById(T entity);
/**
* 根据 columnMap 条件,删除记录
* @param columnMap 表字段 map 对象
*/
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
* 根据 entity 条件,删除记录
* @param queryWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where
语句)
*/
int delete(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 删除(根据ID 批量删除)
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends
Serializable> idList);
/**
* 根据 ID 修改
* @param entity 实体对象
*/
int updateById(@Param(Constants.ENTITY) T entity);
/**
* 根据 whereEntity 条件,更新记录
* @param entity 实体对象 (set 条件值,可以为 null)
* @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成
where 语句)
*/
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER)
Wrapper<T> updateWrapper);
/**
* 根据 ID 查询
* @param id 主键ID
*/
T selectById(Serializable id);
/**
* 查询(根据ID 批量查询)
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends
Serializable> idList);
/**
* 查询(根据 columnMap 条件)
* @param columnMap 表字段 map 对象
*/
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object>
columnMap);
/**
更多Java –大数据 – 前端 – UI/UE - Android - 人工智能资料下载,可访问百度:尚硅谷官网(www.atguigu.com)
* 根据 entity 条件,查询一条记录
* <p>查询一条记录,例如 qw.last("limit 1") 限制取一条记录, 注意:多条数据会报异常
</p>
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
default T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper) {
List<T> ts = this.selectList(queryWrapper);
if (CollectionUtils.isNotEmpty(ts)) {
if (ts.size() != 1) {
throw ExceptionUtils.mpe("One record is expected, but the query
result is multiple records");
}
return ts.get(0);
}
return null;
}
/**
* 根据 Wrapper 条件,查询总记录数
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
Long selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 entity 条件,查询全部记录
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T>
queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录
* <p>注意: 只返回第一个字段的值</p>
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 entity 条件,查询全部记录(并翻页)
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
<P extends IPage<T>> P selectPage(P page, @Param(Constants.WRAPPER)
Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录(并翻页)
* @param page 分页查询条件
* @param queryWrapper 实体对象封装操作类
*/
<P extends IPage<Map<String, Object>>> P selectMapsPage(P page,
@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}

4.使用

创建测试类:
在这里插入图片描述

插入

@Test
public void testInsert(){
User user = new User(null, "张三", 23, "zhangsan@dragon.com");
//INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
int result = userMapper.insert(user);
System.out.println("受影响行数:"+result);
//1712667990465859586
System.out.println("id自动获取:"+user.getId());
}

最终执行的结果,所获取的id为1712667990465859586(你们生成的肯定和我不一样)
这是因为MyBatis-Plus在实现插入数据时,会默认基于雪花算法的策略生成id
如果你设置了id就会按照你设置的插入。

删除

(1)通过id删除记录
@Test
public void testDeleteById(){
//通过id删除用户信息
//DELETE FROM user WHERE id=?
int result = userMapper.deleteById(1712667990465859586L);
//这个是上面插入数据的id,末尾L是告知是Long类型的,该数超过整型int了
System.out.println("受影响行数:"+result);
}
(2)通过id批量删除记录
@Test
public void testDeleteBatchIds(){
//通过多个id批量删除
//DELETE FROM user WHERE id IN ( ? , ? , ? )
List<Long> idList = Arrays.asList(1L, 2L, 3L);
int result = userMapper.deleteBatchIds(idList);
System.out.println("受影响行数:"+result);
}
(3)通过map条件删除记录
@Test
public void testDeleteByMap(){
//根据map集合中所设置的条件删除记录
//DELETE FROM user WHERE name = ? AND age = ?
Map<String, Object> map = new HashMap<>();
map.put("age", 23);
map.put("name", "张三");
int result = userMapper.deleteByMap(map);
System.out.println("受影响行数:"+result);
}

修改

@Test
public void testUpdateById(){
User user = new User(4L, "admin", 22, null);
//UPDATE user SET name=?, age=? WHERE id=?
int result = userMapper.updateById(user);
System.out.println("受影响行数:"+result);
}

查询

(1)根据id查询用户信息
@Test
public void testSelectById(){
//根据id查询用户信息
//SELECT id,name,age,email FROM user WHERE id=?
User user = userMapper.selectById(4L);
System.out.println(user);
}
(2)根据多个id查询多个用户信息
@Test
public void testSelectBatchIds(){
//根据多个id查询多个用户信息
//SELECT id,name,age,email FROM user WHERE id IN ( ? , ? )
List<Long> idList = Arrays.asList(4L, 5L);
List<User> list = userMapper.selectBatchIds(idList);
list.forEach(System.out::println);
}
(3)通过map条件查询用户信息
@Test
public void testSelectByMap(){
//通过map条件查询用户信息
//SELECT id,name,age,email FROM user WHERE name = ? AND age = ?
Map<String, Object> map = new HashMap<>();
map.put("age", 22);
map.put("name", "admin");
List<User> list = userMapper.selectByMap(map);
list.forEach(System.out::println);
}
(4)查询所有数据
@Test
public void testSelectList(){
//查询所有用户信息
//SELECT id,name,age,email FROM user
List<User> list = userMapper.selectList(null);
list.forEach(System.out::println);
}

在这里插入图片描述

通过观察BaseMapper中的方法,大多方法中都有Wrapper类型的形参,此为条件构造器,可针
对于SQL语句设置不同的条件,若没有条件,则可以为该形参赋值null,即查询(删除/修改)所
有数据。

通用Service

说明:

  • 通用 Service CRUD 封装IService接口,进一步封装 CRUD 采用 get 查询单行 remove 删
    除 list 查询集合 page 分页 前缀命名方式区分 Mapper 层避免混淆
  • 泛型 T 为任意实体对象
  • 建议如果存在自定义通用 Service 方法的可能,请创建自己的 IBaseService 继承
    Mybatis-Plus 提供的基类
  • 官网地址:https://baomidou.com/pages/49cc81/#service-crud-%E6%8E%A5%E5%8F%
    A3
(1)IService

MyBatis-Plus中有一个接口 IService和其实现类 ServiceImpl,封装了常见的业务层逻辑
详情查看源码IService和ServiceImpl

(2)创建Service接口和实现类
/**
* UserService继承IService模板提供的基础功能
*/
public interface UserService extends IService<User> {
}
/**
* ServiceImpl实现了IService,提供了IService中基础功能的实现
* 若ServiceImpl无法满足业务需求,则可以使用自定的UserService定义方法,并在实现类中实现
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements
UserService {
}

在这里插入图片描述

(3)测试查询记录数
@Autowired
private UserService userService;
@Test
public void testGetCount(){
long count = userService.count();
System.out.println("总记录数:" + count);
}
(4)测试批量插入
@Test
public void testSaveBatch(){
// SQL长度有限制,海量数据插入单条SQL无法实行,
// 因此MP将批量插入放在了通用Service中实现,而不是通用Mapper
ArrayList<User> users = new ArrayList<>();
for (int i = 0; i < 5; i++) {
User user = new User();
user.setName("ybc" + i);
user.setAge(20 + i);
users.add(user);
}
//SQL:INSERT INTO t_user ( username, age ) VALUES ( ?, ? )
userService.saveBatch(users);
}

三、常用注解

经过以上的测试,在使用MyBatis-Plus实现基本的CRUD时,我们并没有指定要操作的表,只是在Mapper接口继承BaseMapper时,设置了泛型User,而操作的表为user表。
由此得出结论,MyBatis-Plus在确定操作的表时,由BaseMapper的泛型决定,即实体类型决定,且默认操作的表名和实体类型的类名一致。

1.@TableName

若实体类类型的类名和要操作的表的表名不一致
如表中是t_user,实体类是User,在实体类类型上添加@TableName(“t_user”),标识实体类对应的表,即可成功执行SQL语句

在这里插入图片描述

在开发的过程中,我们经常遇到以上的问题,即实体类所对应的表都有固定的前缀,例如t_或tbl_
此时,可以使用MyBatis-Plus提供的全局配置,为实体类所对应的表名设置默认的前缀,那么就不需要在每个实体类上通过@TableName标识实体类对应的表。

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      # 配置MyBatis-Plus操作表的默认前缀
      table-prefix: t_

2. @TableId

经过以上的测试,MyBatis-Plus在实现CRUD时,会默认将id作为主键列,并在插入数据时,默认
基于雪花算法的策略生成id。
若实体类和表中表示主键的不是id,而是其他字段,例如uid,在实体类中uid属性上通过@TableId将其标识为主键,即可成功执行SQL语句

在这里插入图片描述

@TableId的value属性

若实体类中主键对应的属性为id,而表中表示主键的字段为uid,此时若只在属性id上添加注解
@TableId,则抛出异常Unknown column ‘id’ in ‘field list’,即MyBatis-Plus仍然会将id作为表的
主键操作,而表中表示主键的是字段uid
此时需要通过@TableId注解的value属性,指定表中的主键字段,@TableId(“uid”)或@TableId(value=“uid”)

@TableId的type属性

type属性用来定义主键策略

常用的主键策略:

描述
IdType.ASSIGN_ID(默
认)基于雪花算法的策略生成数据id,与数据库id是否设置自增无关
IdType.AUTO使用数据库的自增策略,注意,该类型请确保数据库设置了id自增,否则无效

配置全局主键策略:

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      table-prefix: t_
      # 配置MyBatis-Plus的主键策略
      id-type: auto

3.@TableField

若实体类中的属性使用的是驼峰命名风格,而表中的字段使用的是下划线命名风格
例如实体类属性userName,表中字段user_name
此时MyBatis-Plus会自动将下划线命名风格转化为驼峰命名风格
相当于在MyBatis中配置

若实体类中的属性和表中的字段不满足下划线
例如实体类属性name,表中字段username
此时需要在实体类属性上使用@TableField(“username”)设置属性所对应的字段名

在这里插入图片描述

4.@TableLogic

逻辑删除

  • 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据
  • 逻辑删除:假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录
  • 使用场景:可以进行数据恢复
  • 数据库中创建逻辑删除状态列(is_deleted),设置默认值为0
  • 实体类中添加逻辑删除属性(TableLogic)
    在这里插入图片描述
    @Test
    public void testDeleteById(){
        //通过id删除用户信息
        //DELETE FROM user WHERE id=?
        int result = userMapper.deleteById(1712702194062888961L);
        System.out.println("受影响行数:"+result);
    }

在这里插入图片描述
数据库中并未删除,只是is_deleted属性值变为1。


总结

以上就是MyBatisPlus的有关讲解。

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

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

相关文章

python 爬虫与协同过滤的新闻推荐系统 计算机竞赛

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python 爬虫与协同过滤的新闻推荐系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&…

opencv跨平台arm交叉编译之ubuntu

目录 1. 安装交叉编译工具链2. 安装依赖3. 配置工具链3.1 新建build目录3.2 安装cmake-gui3.3 工具链配置界面进行配置3.3.1 终端输入以下命令3.3.2 点击Configure&#xff0c;弹出编译方式选择对话框&#xff1a;3.3.3 点击Next3.3.4 点击Finish3.3.5 点击Configure。3.3.6 Ge…

SAP PP cs62 提示 输入更改号 - BOM 有历史需求

以上是业务操作人员的 账户 但是IT aLL 这边是warning 不是error 遂去查OSS suim 找 C_STUE_NOH权限对象 赋予权限后 解决了

交通物流模型 | T-GCN:用于交通流预测的时序图卷积网络

交通物流模型 | T-GCN:用于交通流预测的时序图卷积网络 为了同时捕获空间和时间依赖性,本文提出了一种新的基于神经网络的交通流预测方法——时间图卷积网络(T-GCN)模型,该模型将图卷积网络(GCN)和门控循环单元(GRU)相结合。具体来说,GCN用于学习复杂拓扑结构以获取空间相关…

SystemVerilog Assertions应用指南 第一章(1.22章节 and运算符)

1.22“and”构造 进制运算符“and”可以用来逻辑地组合两个序列。当两个序列都成功时整个属性才成功。两个序列必须具有相同的起始点,但是可以有不同的结束点。检验的起始点是第一个序列的成功时的起始点,而检验的结束点是使得属性最终成功的另一个序列成功时的点。 序…

接口自动化测试_L2

目录&#xff1a; 接口请求体-文件 文件上传接口场景使用 requests 如何上传接口请求体-form表单 ​​​​​​​什么是 FORM 请求如何使用&#xff1f;接口请求体-xml​​​​​​​xml响应断言 ​​​​​​​​​​​​​​什么是 XMLXML 断言XPath 断言XML 解析cookie处理…

网络安全渗透测试工具AWVS14.6.2的安装与使用(激活)

AWVS介绍 Acunetix Web Vulnerability Scanner&#xff08;AWVS&#xff09;是一款用于检测网站和Web应用程序中安全漏洞的自动化工具。它的主要功能包括&#xff1a; 漏洞扫描&#xff1a;AWVS能够自动扫描目标网站和Web应用程序&#xff0c;以发现各种安全漏洞&#xff0c;如…

水质在线监测解决方案:数据采集终端的应用

​ 随着社会的发展,河流、湖泊等水环境的保护日益受到关注。但是传统的人工采样检测水质的方法低效且监测数据不连续,无法实时全面掌握水质动态。采用水质在线监测系统,可以实时监测水质参数,并将数据通过无线网络实时传输,以便水务部门监控水质变化,并快速采取应对措施,保护水…

网工配置命令基础总结(2)----VRRP配置

目录 1.配置VRRP主备备份 2.配置VRRP负载分担 3.配置VRRP域BFD联动实现快速切换 VRRP 虚拟路由冗余协议 VRRP&#xff08;Virtual Router Redundancy Protocol&#xff09;通过把几台路由设备联合组成一台虚拟的路由设备&#xff0c;将虚拟网关设备的 IP 地址作为用户的默认…

推荐一款正在用的配音软件(免费)~

最近在做账号&#xff0c;遇到的最大的难题就是&#xff0c;口播的能力一般&#xff0c;用电脑收声以后&#xff0c;总有许多语气词&#xff0c;发音不标准或吞字的情况&#xff0c;而且念稿也是个非常消耗时间的事儿。身边的朋友给我推荐了悦音配音这款AI配音软件&#xff0c;…

向量化操作简介和Pandas、Numpy示例

Pandas是一种流行的用于数据操作的Python库&#xff0c;它提供了一种称为“向量化”的强大技术可以有效地将操作应用于整个列或数据系列&#xff0c;从而消除了显式循环的需要。在本文中&#xff0c;我们将探讨什么是向量化&#xff0c;以及它如何简化数据分析任务。 什么是向量…

appium---如何判断原生页面和H5页面

目前app中存在越来越多的H5页面了&#xff0c;对于一些做app自动化的测试来说&#xff0c;要求也越来越高&#xff0c;自动化不仅仅要支持原生页面&#xff0c;也要可以H5中进行操作自动化&#xff0c; webview是什么 webview是属于android中的一个控件&#xff0c;也相当于一…

GFD233A103 3BHE022294R0103 串行和并行通信的区别

GFD233A103 3BHE022294R0103 串行和并行通信的区别 串行通信和并行通信的关键区别在于&#xff0c;在串行通信中&#xff0c;一条通信链路用于将数据从一端传输到另一端。与并行通信相反&#xff0c;使用多个并行链路同时传输每位数据。 由于只有一条通信链路&#xff0c;串行…

到底什么是5G-R?

近日&#xff0c;工信部向中国国家铁路集团有限公司&#xff08;以下简称“国铁集团”&#xff09;批复5G-R试验频率的消息&#xff0c;引起了行业内的广泛关注。 究竟什么是5G-R&#xff1f;为什么工信部会在此时批复5G-R的试验频率&#xff1f; 今天&#xff0c;小枣君就通过…

win10取消ie浏览器自动跳转edge浏览器

建议大家看完整篇文章再作操作 随着windows10 日渐更新&#xff0c;各种不同的操作&#xff0c;规避IE浏览器跳转Edge浏览器的问题 算了&#xff0c;找了台云机装的server 有自带的IE 1.&#xff08;失败&#xff09;思路 协助Edge浏览器 管理员身份打开 PowerShell 一般e…

一个有趣的观点:用To C的思路来做To B

大数据产业创新服务媒体 ——聚焦数据 改变商业 在传统商业模式中&#xff0c;B端市场和C端市场被视为截然不同的两个领域&#xff0c;各自有各自的战略和运营模式。但随着技术的迅速发展和市场环境的变化&#xff0c;这两个领域之间的界限正在逐渐模糊。 尽管B端软件的目标客…

外卖跑腿系统的关键功能和技术要点

1. 用户注册和登录 首先&#xff0c;用户需要能够注册新账户并登录。以下是使用Python和Django框架的代码示例&#xff0c;展示如何创建用户注册和登录功能。 # Django视图代码 from django.contrib.auth import login, authenticate from django.contrib.auth.forms import…

需求评审如何一次过?

需求评审是产品经理一项绕不过去的工作&#xff0c;但对于产品新人来说&#xff0c;可能不是一件简单的事情&#xff0c;方案准备的是否充分&#xff0c;能否经受住项目其他成员的灵魂拷问&#xff0c;都极大的考验着产品经理的技能和抗压能力&#xff0c;今天就来说说如何做好…

kettle应用-数据库表插入/更新

本文介绍从pg数据库中抽取数据&#xff0c;插入/更新到另一个表中 数据流转逻辑设计 【表输入】--》【增加序列】--》【插入/更新】 一、表输入&#xff1a;关联多表查询获取数据 “核心对象”区域--“输入”中&#xff0c;拖入“表输入” 二、增加序列&#xff1a;生成序列…

我的创作日

目录 机缘 收获 日常 成就 憧憬 机缘 《AR助教奇迹人总结》这是最开始大佬叫我写的文章&#xff0c;大佬说写完发到CSDN&#xff0c;刚开始我还纳闷什么叫CSDN呢&#xff0c;无意间我看到我的码龄竟然是两年&#xff0c;哈哈可能是无意间自己注册的吧&#xff0c;连我自己…