MybatisPlus基础入门以及入门案例

目录

一、MyBatisPlus简介

二、MyBatisPlus特性

三、MyBatisPlus支持的数据库

四、框架结构

五、入门案例

        1.开发环境

        2.创建数据库及表

        3.创建Spring Boot工程

        4.导入依赖

        5.项目结构

        6.配置application.yml

        7.配置SpringBoot启动类

        8.添加实体类

        9.添加mapper接口

        10.测试

六、BaseMapper类及注释

七、通用Service

        1.IService

        2.创建Service接口和实现类

        3.测试类


一、MyBatisPlus简介

        MyBatis-Plus (简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为 简化开发、提高效率而生Mybatis-Plus提供了通用的Mapper和Service,可以在不编写任何SQL语句的前提下,快速的实现单表的增删改查(CURD),批量,逻辑删除,分页等操作。

二、MyBatisPlus特性

无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑

损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防 误操作

三、MyBatisPlus支持的数据库

任何能使用MyBatis进行 CRUD, 并且支持标准 SQL 的数据库,具体支持情况如下:

MySQL Oracle  DB2  H2  HSQL SQLite  PostgreSQL SQLServer  Phoenix Gauss  ClickHouse Sybase OceanBase  Firebird Cubrid Goldilocks csiidb

达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据 库,瀚高数据库

四、框架结构

五、入门案例

        1.开发环境

        JDK:JDK8+

        构建工具:  maven 3.5.4

        MySQL版本:  MySQL 5.7

        2.创建数据库及表

CREATE DATABASE `mybatis_plus` /*!40100 DEFAULT CHARACTER SET utf8mb4 */; use `mybatis_plus`;
CREATE TABLE `user` (
`id` bigint(20) NOT NULL COMMENT '主键ID',
`name` varchar(30) DEFAULT NULL COMMENT '姓名 ',
`age` int(11) DEFAULT NULL COMMENT '年龄 ',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱 ',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');

        3.创建Spring Boot工程

        可以利用普通maven项目改造成Spring Boot项目。

        4.导入依赖

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

        利用lombok一定要引入lombok插件。

        5.项目结构

        6.配置application.yml

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

        7.配置SpringBoot启动类

package com.qcby;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.qcby.SpringBoot.mapper")
public class SpringBootApplication1 {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootApplication1.class, args);
    }
}

        8.添加实体类

package com.qcby.SpringBoot.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data //set和get方法
@AllArgsConstructor //全参构造器
@NoArgsConstructor  //无参构造器
public class User {
    //因为用到雪花算法,所以用Long属性
    private Long id;
    private String name;
    private Integer age;
    private String email;
}

        9.添加mapper接口

        BaseMapper是MyBatis-Plus提供的模板mapper,其中包含了基本的CRUD方法,泛型为操作的 实体类型。

package com.qcby.SpringBoot.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.qcby.SpringBoot.pojo.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

        10.测试

package com.qcby;

import com.qcby.SpringBoot.mapper.UserMapper;
import com.qcby.SpringBoot.pojo.User;
import com.qcby.SpringBoot.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.*;

@SpringBootTest
public class MybatisPlusTest {
    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelectList(){
        //selectList()根据MP内置的条件构造器查询一个list集合,null表示没有条件,即查询所有
        userMapper.selectList(null).forEach(System.out::println);
    }
    @Test
    public void testInsert(){
        User user = new User(null, "张三", 23, "zhangsan@atguigu.com");
        //INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
        int result = userMapper.insert(user);
        System.out.println("受影响行数:"+result);
        //1475754982694199298
        System.out.println("id自动获取:"+user.getId());
    }
    @Test
    public void testDeleteById(){
        //通过id删除用户信息
        //DELETE FROM user WHERE id=?
        int result = userMapper.deleteById(1760282394646028289L);
        System.out.println("受影响行数:"+result);
    }
    @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);
    }
    @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);
    }
    @Test
    public void testSelectById(){
        //根据id查询用户信息
        //SELECT id,name,age,email FROM user WHERE id=?
        User user = userMapper.selectById(4L);
        System.out.println(user);
    }
    @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);
    }
    @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);
    }
    @Test
    public void testSelectList2(){
        //查询所有用户信息
        //SELECT id,name,age,email FROM user
        List<User> list = userMapper.selectList(null);
        list.forEach(System.out::println);
    }
}

六、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);

    /**
    * 根据 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);
}

七、通用Service

        1.IService

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

        详情查看源码IServiceServiceImpl。

        2.创建Service接口和实现类

package com.qcby.SpringBoot.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.qcby.SpringBoot.pojo.User;

/**
 * UserService继承IService模板提供的基础功能
 */
public interface UserService extends IService<User> {
}
package com.qcby.SpringBoot.service.Impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qcby.SpringBoot.mapper.UserMapper;
import com.qcby.SpringBoot.pojo.User;
import com.qcby.SpringBoot.service.UserService;
import org.springframework.stereotype.Service;

/**
 * ServiceImpl实现了IService,提供了IService中基础功能的实现
 * 若ServiceImpl无法满足业务需求,则可以使用自定的UserService定义方法,并在实现类中实现
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

}

        3.测试类

package com.qcby;

import com.qcby.SpringBoot.mapper.UserMapper;
import com.qcby.SpringBoot.pojo.User;
import com.qcby.SpringBoot.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.*;

@SpringBootTest
public class MybatisPlusTest {

    @Autowired
    private UserService userService;

    @Test
    public void testGetCount(){
        long count = userService.count();
        System.out.println("总记录数:" + count);
    }

    @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);
            user.setEmail(i+"@qq.com");
        }
        //SQL:INSERT INTO t_user ( username, age ) VALUES ( ?, ? )
        userService.saveBatch(users);
    }
}

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

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

相关文章

vue后台管理添加水印简单方式watermark-package

详情参考:https://www.npmjs.com/package/watermark-package 示例方法 <el-button type"primary" click"AddWatermark">添加水印</el-button><el-button type"primary" click"RemoveWatermark">清除水印</el-but…

MKdocs添加顶部公告栏

效果如图&#xff1a; docs/overrides下新建main.html &#xff0c;针对main.html文件 树状结构如下: $ tree -a . ├── .github │ ├── .DS_Store │ └── workflows │ └── PublishMySite.yml ├── docs │ └── index.md │ └──overrides │…

领域驱动设计在互联网业务开发中的实践

至少30年以前&#xff0c;一些软件设计人员就已经意识到领域建模和设计的重要性&#xff0c;并形成一种思潮&#xff0c;Eric Evans将其定义为领域驱动设计&#xff08;Domain-Driven Design&#xff0c;简称DDD&#xff09;。在互联网开发“小步快跑&#xff0c;迭代试错”的大…

数字孪生城市及其他应用场景应用

数字孪生的“虚拟副本”让城市治理不再盲人摸象。 从城市治理的角度来看&#xff0c;数字孪生城市相当于真实世界的“操作系统”&#xff0c;有了它就可以远程对城市的每一个角落进行监测、智慧调度&#xff0c;无论是街道、社区&#xff0c;还是商场、变电站乃至城市排水系统…

使用 JMeter 生成测试数据对 MySQL 进行压力测试

博主历时三年精心创作的《大数据平台架构与原型实现&#xff1a;数据中台建设实战》一书现已由知名IT图书品牌电子工业出版社博文视点出版发行&#xff0c;点击《重磅推荐&#xff1a;建大数据平台太难了&#xff01;给我发个工程原型吧&#xff01;》了解图书详情&#xff0c;…

【C语言基础教程】getline函数与临时文件

文章目录 前言一、getline函数1.1 为什么需要这个函数1.2 getline函数的使用1.3 使用示例 二、临时文件2.1 临时文件的使用2.2 示例代码 总结 前言 在C语言编程中&#xff0c;处理文本文件是一个常见的任务。然而&#xff0c;有时候我们需要处理那些我们不想在磁盘上创建的临时…

Qwen-VL本地化部署及微调实践

Qwen-VL本地化部署及微调实践 创建虚拟环境模型部署下载模型文件下载项目代码安装python依赖环境修改web_demo_mm.py及openai_api.py的部分代码启动测试 模型微调环境部署数据准备微调 问题 创建虚拟环境 conda create -name vl python3.10.8模型部署 下载模型文件 https://…

React学习——快速上手

文章目录 初步模块思维 初步 https://php.cn/faq/400956.html 1、可以手动使用npm来安装各种插件&#xff0c;来从头到尾自己搭建环境。 如&#xff1a; npm install react react-dom --save npm install babel babel-loader babel-core babel-preset-es2015 babel-preset-rea…

从MATLAB到MWORKS,科学计算与系统建模仿真平台的中国选项

“中国需要自主的科学计算与系统建模仿真平台。” 工业软件是所有复杂系统研发设计、仿真验证和数字制造的必备工具&#xff0c;已经成为衡量一个国家工业竞争力的核心指标。在传统工业软件领域&#xff0c;我们一直处于落后状态&#xff0c;尤其是研发设计类工业软件&#xff…

uniapp开发微信小程序跳转到另一个小程序中

注意&#xff1a;一开始我的云上务工模块是单独的tabbar界面&#xff0c;但是小程序跳转好像不能直接点击tabbar进行&#xff0c;所以我将这里改成了点击首页中的按钮进行跳转 点击这里进行小程序跳转 目录 基础讲解 uniapp小程序跳转的两个方法 调用说明&#xff08;半屏跳转…

助力国产BMS管理芯片品牌发展,世强硬创获迈巨微电子授权代理

作为电池的核心半导体器件&#xff0c;BMS电池管理芯片在电动化时代的需求持续旺盛&#xff0c;并迎来了快速迭代的时期。 为满足电动自行车、AGV等市场对BMS电池管理芯片的需求&#xff0c;世强先进&#xff08;深圳&#xff09;科技股份有限公司&#xff08;下称“世强先进”…

记阿里云mysql丢表丢数据的实践记录

第一时间挂工单&#xff0c;联系工程师指引&#xff0c;现在回过来想&#xff0c;第一时间要确认发生时间。 1.通过性能视图&#xff08;马后炮的总结&#xff0c;实际凭记忆恢复了三四次才找到数据&#xff09; 2.先恢复数据 通过Navicat工具&#xff0c;结构同步&#xff0…

动态绑定样式,uniapp,用三元运算动态绑定多个class类样式,动态绑定的样式可以和原始样式共存

介绍 | uni-app官网 vue、uniapp中动态添加绑定style、class 9种方法实现_vue style动态绑定-CSDN博客 uniapp使用三元运算符动态绑定元素的style样式_uniapp style动态绑定-CSDN博客 对象写法,可以写多个class类 class类的名字&#xff1a;判断条件&#xff0c;最后结果只有…

元宵佳节到,互动礼品,该怎么邮寄最便宜呢?

家人们&#xff0c;一年一度的元宵佳节就要到了&#xff0c;大家吃汤圆了没&#xff0c;朋友之间是不是可以相互寄送点礼物啊&#xff0c;但是该怎么邮寄呢&#xff1f;用什么方式寄快递最便宜呢&#xff1f;客官别着急&#xff0c;听我慢慢说给你听。 首先&#xff0c;先说说各…

NPS配置内网穿透-Windows,PVE

Windows和PVE的区别就是下载客户端的时候一个选windows-amd64(64位的电脑)另一个选 linux-amd64(64位电脑),386对应的是32位的电脑. Releases ehang-io/nps (github.com) PVE的安装参考的是以下视频安装.利用PVE虚拟机&#xff0c;来打造属于自己的All In One系统吧&#xf…

谷歌掀桌子!开源Gemma:可商用,性能超过Llama 2!

2月22日&#xff0c;谷歌在官网宣布&#xff0c;开源大语言模型Gemma。 Gemma与谷歌最新发布的Gemini 使用了同一架构&#xff0c;有20亿、70亿两种参数&#xff0c;每种参数都有预训练和指令调优两个版本。 根据谷歌公布的测试显示&#xff0c;在MMLU、BBH、GSM8K等主流测试…

大型语言模型的语义搜索(一):关键词搜索

关键词搜索(Keyword Search)是文本搜索种一种常用的技术&#xff0c;很多知名的应用app比如Spotify、YouTube 或 Google map等都会使用关键词搜索的算法来实现用户的搜索任务&#xff0c;关键词搜索是构建搜索系统最常用的方法&#xff0c;最常用的搜索算法是Okapi BM25&#x…

两种动态代理(可以看到代理类的样子,方便理解)

这里写目录标题 jdk动态代理例子CGlib动态代理例子手写spring中的事务部分自定义注解版aop实现方式 Spring的两大重点&#xff0c;IOC和AOP&#xff0c;今天我们就来学AOP&#xff0c;众所周知AOP的底层是动态代理&#xff0c;让我们看一下这两种动态代理的区别。 例子&#x…

软件压力测试:测试方法与步骤详解

随着软件应用的不断发展&#xff0c;用户对系统性能的要求也逐渐提高。在不同的负载条件下&#xff0c;系统必须能够保持稳定、高效的运行。软件压力测试是一种验证系统在各种负载情况下性能表现的关键手段。本文将详细探讨软件压力测试的方法和步骤。 1. 明确测试目标 在进行压…

数字化转型:八大关键词揭示企业增长新引擎

导语&#xff1a; 在数字化浪潮的席卷下&#xff0c;企业正面临前所未有的转型挑战与增长机遇。为了把握这一时代的脉搏&#xff0c;我们需要深入剖析数字化转型的核心要素。本文将通过“洞察不确定性、驾驭复杂系统、重塑竞争边界、数据驱动决策、智能软件崛起、技术架构重塑…
最新文章