不写Sql进行CRUD——MybatisPlus的基本用法

目录

使用步骤 

引入依赖

在XXXMapper接口里实现BaseMapper<>接口(找爸爸)

之后就可以在项目中直接使用XXXMapper内定义的crud方法了

使用mabatis-plus时常用的注解

常见配置

核心功能

条件构造器

查询数据 

 修改数据

条件构造器的用法:

使用Mybatis-plus时遵循分层架构原则的示例

Mapper层

Service层

 controller层

Service接口

MP的Service接口使用流程

Lambda方法实现复杂条件的查询与修改(lambdaQuery 和 lambdaUpdate)

查询 

修改

批量新增(rewriteBatchedStatements=true)

MybatisPlus插件

静态工具 

Db

逻辑删除

注意

枚举处理器

Json处理器 

分页查询插件

分页查询相关方法的封装 

使用步骤 

引入依赖

<!-- MybatisPlus -->  
<dependency>  
    <groupId>com.baomidou</groupId>  
    <artifactId>mybatis-plus-boot-starter</artifactId>  
    <version>3.5.3.1</version>  
</dependency>

MyBatisPlus官方提供了starter,其中集成了Mybatis和MybatisPlus的所有功能,并且实现了自动装配效果。因此我们可以用MybatisPlus的starter代替Mybatis的starter。

在XXXMapper接口里实现BaseMapper<>接口(找爸爸

package com.itheima.mp.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserMapper extends BaseMapper<User> {

    void saveUser(User user);

    void deleteUser(Long id);

    void updateUser(User user);

    User queryUserById(Long id);

    List<User> queryUserByIds(@Param("ids") List<Long> ids);
}
  • 泛型里的类名驼峰转下划线作为表名
  • 名为id的字段作为主键(所以设计的数据库表一定要有id主键)
  • 变量名驼峰转下划线作为表的字段名

之后就可以在项目中直接使用XXXMapper内定义的crud方法了

  void testQueryByIds() {
        List<User> users = userMapper.queryUserByIds(Arrays.asList(1L, 2L, 3L, 4L));
        users.forEach(System.out::println);
    }

使用mabatis-plus时常用的注解

注解配置 | MyBatis-Plus

MybatisPlus中比较常用的几个注解如下(这几个注解加到对应于数据库字段的实体类):

  • @TableName:用来指定表名

  • @TableId:用来指定表中的主键字段信息

    • ​​​​​IdType枚举:

      1. AUTO:数据库自增长

      2. INPUT:通过set方法自行输入

      3. ASSIGN_ID:分配 ID,将由IdentifierGenerator的方法nextId来生成id,默认实现是为DefaultIdentifierGenerator雪花算法

  • @TableField:用来指定表中的普通字段信息

    • 使用@TableField的常见场景:

      1. 成员变量名与数据库字段名不一致

      2. 成员变量名以is开头,且是布尔值

      3. 成员变量名与数据库关键字冲突

      4. 成员变量不是数据库字段

常见配置

mybatis-plus:  
  type-aliases-package: com.itheima.mp.domain.po  # 别名扫描包  
  mapper-locations: "classpath:/mapper/**/*.xml"  # Mapper.xml 文件地址,默认值  
  configuration:  
    map-underscore-to-camel-case: true  # 是否开启下划线转驼峰的映射  
    cache-enabled: false                  # 是否开启二级缓存  
  global-config:  
    db-config:  
      id-type: assign_id                  # id 为雪花算法生成,但是全局没有注解配置的级别高  
      update-strategy: not_null           # 更新策略:只更新非空字段

 以上配置除了type-aliases-package其他都是默认的,可以不用配置

使用配置 | MyBatis-Plus

核心功能

条件构造器

 条件构造器 | MyBatis-Plus 中文

  • 基本条件
    • eq(): 等于
    • ne(): 不等于
    • gt(): 大于
    • lt(): 小于
    • ge(): 大于等于
    • le(): 小于等于
  • 模糊查询
    • like(): 包含某个字符串
    • notLike(): 不包含某个字符串
  • 逻辑条件
    • or(): 或
    • and(): 与
  • 集合查询
    • in(): 在某个集合中
    • notIn(): 不在某个集合中

查询数据 

    @Test
    void testQueryWrapper() {
// 构造查询条件
        QueryWrapper<User> wrapper = new QueryWrapper<User>()
                .select("id", "info") // 指定要查询的字段
                .like("username", "o") // 指定查询条件的字段要求
                .like("info", "女");  // 指定查询条件的字段要求
        // 查询,传入查询条件
        List<User> users = userMapper.selectList(wrapper);
        for(User user : users){
            System.out.println(user);
        }
    }


    // lambda查询
    @Test
    void testlambdaQueryWrapper() {
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>()
                .select(User::getId, User::getInfo)
                .like(User::getUsername, "o")
                .like(User::getInfo, "女");
        // 查询
        List<User> users = userMapper.selectList(wrapper);
        for(User user : users){
            System.out.println(user);
        }
    }

 修改数据

    @Test
    void testUpdateWrapper() {
        List<Long> ids = Arrays.asList(2L, 3L, 4L);
        UpdateWrapper<User> wrapper = new UpdateWrapper<User>()
                .setSql("balance = balance - 200")
                .in("id", ids);
        userMapper.update(null,wrapper);
    }

    // 或者使用LambdaUpdateWrapper
    @Test
    void TestLambdaUpdateWrapper() {
        List<Long> ids = Arrays.asList(2L, 3L, 4L);
        LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<User>()
                .setSql("balance = balance - 200")
                .in(User::getId, ids);
        userMapper.update(null,wrapper);
    }

条件构造器的用法:

  • QueryWrapper和LambdaQueryWrapper 通常用来构建 selectdeleteupdate 的 where 条件部分。
  • UpdateWrapper和LambdaUpdateWrapper 通常只在 set 语句(修改数据)中比较特殊才使用。
  • 尽量使用 LambdaQueryWrapper 和 LambdaUpdateWrapper,避免直接写数据库里的字段名称。

使用Mybatis-plus时遵循分层架构原则的示例

Mapper层

  • 提供基础的数据库操作方法。

  • 不涉及业务逻辑。

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

Service层

  • 构造查询条件。

  • 调用 Mapper 层完成数据操作。

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User getUserByName(String name) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name); // 按姓名查找
        return userMapper.selectOne(queryWrapper); // 使用 selectOne 获取单个用户
    }
}

 controller层

  • 负责接收 HTTP 请求和参数。

  • 调用 Service 层。

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public User getUserByName(String name) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", name); // 按姓名查找
        return userMapper.selectOne(queryWrapper); // 使用 selectOne 获取单个用户
    }
}

Service接口

MP的Service接口使用流程

  1. 自定义Service接口继承IService<>接口

    public interface IUserService extends IService<User> {}
  2. 自定义Service实现类,实现自定义接口并继承ServiceImpl<XXXMapper, XXX>类

    public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService 
    { // 实现具体的方法 }

    使用该接口

    @SpringBootTest
    class IUserServiceTest {
        @Autowired
        private IUserService iUserService;
    
        @Test
        void UserServiceTest(){
            List<Long> ids = Arrays.asList(2L, 3L, 4L);
            LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<User>()
                    .setSql("balance = balance - 200")
                    .in(User::getId, ids);
            iUserService.update(null,wrapper);
        }
    }

    Lambda方法实现复杂条件的查询与修改(lambdaQuerylambdaUpdate

由于是在service层的实现类里使用lambdaQuerylambdaUpdate方法,所以下面的类和接口有这些关系

以下的sql语句可以通过service层的lambda语句来实现

查询 

上面等价于 

@Override
    public List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {
        return lambdaQuery()
                .like(name != null, User::getUsername,name)
                .eq(status != null, User::getStatus,status)
                .ge(minBalance != null, User::getBalance, minBalance)
                .le(maxBalance != null, User::getBalance, maxBalance)
                .list();
    }

  Lambda 查询的最后,可以根据查询的结果类型和需求选择不同的方法:

查询单个对象:.one()

查询多个对象:.list()

分页查询:.page(Page<T> page)

查询总数:count()

查询是否存在:.count() 方法结合 > 0

修改

@Override
    @Transactional // 添加事务
    public void DedMoneyById(Long id, Integer money) {
        User user = getById(id);
        if(user.getStatus() == null || user.getStatus() == 2){
            throw new RuntimeException("账号状态异常");
        }
        if(user.getBalance() < money){
            throw new RuntimeException("余额不足");
        }
        Integer rest = user.getBalance() - money;
        lambdaUpdate()
                .set(User::getBalance, rest)
                .set(rest == 0,User::getStatus, 2)
                .eq(User::getId,id)
                .eq(User::getBalance, user.getBalance()) // 乐观锁
                .update(); // 最后加上update
    }

乐观锁通过在更新时检查记录的当前状态(如余额)来确保只有在数据未被其他线程修改的情况下才会进行更新。

批量新增(rewriteBatchedStatements=true

application.yml文件的url项最后加一个&rewriteBatchedStatements=true

启用此参数后,JDBC 驱动程序会将多个 SQL 语句批量重写为单个 SQL 语句,这样可以显著减少网络往返次数,从而提高性能,尤其是在执行大量插入或更新操作时。

MybatisPlus插件

下载完插件之后

工具选项中点击Config Database来使用

连接上数据库之后点开工具里的 Code Generator选项卡

点击生成文件和代码之后,项目内就生成了对应的entity、service、controller、mapper等 

静态工具 

Db

@Override
    public UserVO GetUsersAndAddressById(Long id) {
        // 查询用户
        User user = getById(id);
        if(user == null || user.getStatus() == 2){
            throw new RuntimeException("用户状态异常");
        }
        UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);
        // 查询地址(查询另一张数据库表)
        List<Address> addresses = Db.lambdaQuery(Address.class)
                .eq(Address::getUserId, id)
                .list();
        if(addresses == null){
            return userVO;
        }
        userVO.setAddressVOList(BeanUtil.copyToList(addresses, AddressVO.class));
        return userVO;
        
    }

//涉及查询另一张数据库表——使用Db.lambdaQuery(XXX.class)
List<Address> addresses = Db.lambdaQuery(Address.class)
                .eq(Address::getUserId, id)
                .list();

逻辑删除

逻辑删除是一种数据管理策略,用于标记数据为“已删除”而不是物理上从数据库中移除。这种方法通常在需要保持数据历史记录或避免数据丢失时使用。

yml文件中的配置

mybatis-plus:  
  global-config:  
    db-config:  
      logic-delete-field: flag  # 全局逻辑删除的实体字段名,字段类型可以是 boolean, integer  
      logic-delete-value: 1      # 逻辑删除的值(默认为 1)  
      logic-not-delete-value: 0   # 逻辑未删除值(默认为 0)

注意

逻辑删除本身也有自己的问题,例如:

  • 会导致数据库表垃圾数据越来越多,影响查询效率。
  • SQL 中全部需要对逻辑删除字段做判断,影响查询效率。

因此,我不太推荐采用逻辑删除功能,如果数据不能删除,可以采用把数据迁移到其它表的方法。

枚举处理器

yml中配置枚举处理器 

mybatis-plus:  
  configuration:  
    default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler

定义枚举类:新建enums文件添加UserStatus枚举类

@Getter
public enum UserStatus {
    NORMAL(1, "正常"),
    FROZEN(2, "异常"),;

    @EnumValue
    private final int value;
    @JsonValue // 加到谁身上就向前端返回什么数据
    private final String desc; // 返回“正常”or“异常”

    UserStatus(int value, String desc){
        this.value = value;
        this.desc = desc;
    }
}

 使用定义的枚举

@Override
    public List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {
            // user.getStatus() == UserStatus.FROZEN 注意枚举这样比较
       if(user == null || user.getStatus() == UserStatus.FROZEN){
            throw new RuntimeException("用户状态异常");
        }
        return lambdaQuery()
                .like(name != null, User::getUsername,name)
                 // 传入的Integer类型的status与数据库status字段对应的数值比较
                .eq(status != null, User::getStatus,status)
                .ge(minBalance != null, User::getBalance, minBalance)
                .le(maxBalance != null, User::getBalance, maxBalance)
                .list();
    }

Json处理器 

为了将后端数据库里的Json字段返回前端时不展现为一个字符串(带有引号的转义字符:/"),

而是具体展现为一个Json数据,

第一步,将实体类那个Json数据(String类型)改为实体类的类型,所以先创建这个实体类,注意加这三个注解 

@Data
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
public class UserInfo {
    private Integer age;
    private String intro;
    private String gender;
}

 第二步、将对应于数据库的实体类加上@TableName注解,同时在嵌套的实体类字段上加上@TableField(typeHandler = JacksonTypeHandler.class)注解

@Data  
@TableName(value = "user", autoResultMap = true)  
public class User {  
    private Long id;  
    private String username;  
    @TableField(typeHandler = JacksonTypeHandler.class)  
    private UserInfo info;  
}

第三步、返回给前端的VO类里改为实体类字段

@Data
@ApiModel(description = "用户VO实体")
public class UserVO {

    @ApiModelProperty("用户id")
    private Long id;

    @ApiModelProperty("用户名")
    private String username;

    @ApiModelProperty("详细信息")
    @TableField(typeHandler = JacksonTypeHandler.class)
    private UserInfo info;

    @ApiModelProperty("使用状态(1正常 2冻结)")
    private UserStatus status;
}

分页查询插件

首先配置分页查询的插件,创建config目录下的MybatisPlusConfig配置类

@Configuration  
public class MybatisConfig {  
    @Bean  
    public MybatisPlusInterceptor mybatisPlusInterceptor() {  
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();  

        // 1. 创建分页插件  
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);  
        // 2. 设置最大限制  
        paginationInnerInterceptor.setMaxLimit(1000L);  
        
        interceptor.addInnerInterceptor(paginationInnerInterceptor);  
        return interceptor;  
    }  
}
    @Test
    void testPageQuery() {
        // 查询第二页,每页两条
        int pageNo = 2, pageSize = 2;

        // 1. 准备分页条件
        // 1.1. 分页条件
        Page<User> page = Page.of(pageNo, pageSize);

        // 1.2. 排序条件
        page.addOrder(new OrderItem("balance",true));
        page.addOrder(new OrderItem("id", true));

        // 2. 分页查询
        Page<User> p = iUserService.page(page);

        // 3. 解析
        long total = p.getTotal();// 总条数
        System.out.println("total = " + total);
        long pages = p.getPages();// 总页数
        System.out.println("pages = " + pages);
        List<User> users = p.getRecords();
        users.forEach(System.out::println);
    }

业务中具体实现分页查询操作

@Override
    public PageDTO<UserVO> queryPageUsers(UserQuery query) {
        // 分页的页码,每页的数量
        Page<User> page = Page.of(query.getPageNo(), query.getPageSize());
        // 1.2. 排序条件
        if (page != null) {
            // 不为空   指定排序的字段和规则
            page.addOrder(new OrderItem(query.getSortBy(), query.getIsAsc()));
        } else {
            // 为空,默认为按更新时间排序
            page.addOrder(new OrderItem("update_time", false));
        }
        // 2. 分页查询
        Page<User> page1 = lambdaQuery()
                .like(query.getName() != null, User::getUsername, query.getName())
                .eq(query.getStatus() != null, User::getStatus, query.getStatus())
                .page(page);

        PageDTO<UserVO> pageDTO = new PageDTO<>(page1.getTotal(), page1.getPages(), BeanUtil.copyToList(page1.getRecords(), UserVO.class));
        return pageDTO;
    }

@Data
public class PageQuery {
    private Integer pageNo;
    private Integer pageSize;
     // 排序规则相关字段
    private String sortBy;
    private Boolean isAsc;
    // 如果还要添加排序规则,那么可以传入多个OrderItem对象
    public <T>  Page<T> toMpPage(OrderItem ... orders){
        // 1.分页条件
        Page<T> p = Page.of(pageNo, pageSize);
        // 2.排序条件
        // 2.1.先看前端有没有传排序字段
        if (sortBy != null) {
            p.addOrder(new OrderItem(sortBy, isAsc));
            return p;
        }
        // 2.2.再看有没有手动指定排序字段
        if(orders != null){
            p.addOrder(orders);
        }
        return p;
    }
    // 传入一个规则就可以这样
    public <T> Page<T> toMpPage(String defaultSortBy, boolean isAsc){
        return this.toMpPage(new OrderItem(defaultSortBy, isAsc));
    }

    // 以下是直接调用的默认方法
    public <T> Page<T> toMpPageDefaultSortByCreateTimeDesc() {
        return toMpPage("create_time", false);
    }

    public <T> Page<T> toMpPageDefaultSortByUpdateTimeDesc() {
        return toMpPage("update_time", false);
    }
}

分页查询相关方法的封装 

分页查询相关的实体类(如果某个实体类要做分页查询,那么这个实体类就继承PageQuery 这个类,对应于接收前端传来的数据格式

@Data
public class PageQuery {
    private Integer pageNo;
    private Integer pageSize;
     // 排序规则相关字段
    private String sortBy;
    private Boolean isAsc;
    // 如果还要添加排序规则,那么可以传入多个OrderItem对象
    public <T>  Page<T> toMpPage(OrderItem ... orders){
        // 1.分页条件
        Page<T> p = Page.of(pageNo, pageSize);
        // 2.排序条件
        // 2.1.先看前端有没有传排序字段
        if (sortBy != null) {
            p.addOrder(new OrderItem(sortBy, isAsc));
            return p;
        }
        // 2.2.再看有没有手动指定排序字段
        if(orders != null){
            p.addOrder(orders);
        }
        return p;
    }
    // 传入一个规则就可以这样
    public <T> Page<T> toMpPage(String defaultSortBy, boolean isAsc){
        return this.toMpPage(new OrderItem(defaultSortBy, isAsc));
    }

    // 以下是直接调用的默认方法
    public <T> Page<T> toMpPageDefaultSortByCreateTimeDesc() {
        return toMpPage("create_time", false);
    }

    public <T> Page<T> toMpPageDefaultSortByUpdateTimeDesc() {
        return toMpPage("update_time", false);
    }
}

 要做分页查询的实体类要继承PageQuery

 分页结果对应的实体类,分页的具体对象对应的类型要传入泛型。

@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel("分页结果")
public class PageDTO<V> {
    @ApiModelProperty("总条数")
    private Long total;
    @ApiModelProperty("总页数")
    private Long pages;
    @ApiModelProperty("列表")
    private List<V> list;

    /**
     * 返回空分页结果
     * @param p MybatisPlus的分页结果
     * @param <V> 目标VO类型
     * @param <P> 原始PO类型
     * @return VO的分页对象
     */
    public static <V, P> PageDTO<V> empty(Page<P> p){
        return new PageDTO<>(p.getTotal(), p.getPages(), Collections.emptyList());
    }

    /**
     * 将MybatisPlus分页结果转为 VO分页结果
     * @param p MybatisPlus的分页结果
     * @param voClass 目标VO类型的字节码
     * @param <V> 目标VO类型
     * @param <P> 原始PO类型
     * @return VO的分页对象
     */
    public static <V, P> PageDTO<V> of(Page<P> p, Class<V> voClass) {
        // 1.非空校验
        List<P> records = p.getRecords();
        if (records == null || records.size() <= 0) {
            // 无数据,返回空结果
            return empty(p);
        }
        // 2.数据转换
        List<V> vos = BeanUtil.copyToList(records, voClass);
        // 3.封装返回
        return new PageDTO<>(p.getTotal(), p.getPages(), vos);
    }

    /**
     * 将MybatisPlus分页结果转为 VO分页结果,允许用户自定义PO到VO的转换方式
     * @param p MybatisPlus的分页结果
     * @param convertor PO到VO的转换函数
     * @param <V> 目标VO类型
     * @param <P> 原始PO类型
     * @return VO的分页对象
     */
    public static <V, P> PageDTO<V> of(Page<P> p, Function<P, V> convertor) {
        // 1.非空校验
        List<P> records = p.getRecords();
        if (records == null || records.size() <= 0) {
            // 无数据,返回空结果
            return empty(p);
        }
        // 2.数据转换
        List<V> vos = records.stream().map(convertor).collect(Collectors.toList());
        // 3.封装返回
        return new PageDTO<>(p.getTotal(), p.getPages(), vos);
    }
}

    @Override
    public PageDTO<UserVO> queryPageUsers(UserQuery query) {
        String name = query.getName();
        Integer status = query.getStatus();

        // 1. 构建分页条件,默认传入前端的排序条件,同时按照更新顺序排列
        Page<User> page = query.toMpPageDefaultSortByUpdateTimeDesc();

        // 2. 分页查询
        Page<User> p = lambdaQuery()
                .like(name != null, User::getUsername, name)
                .eq(status != null, User::getStatus, status)
                .page(page);

        // 3. 封装VO结果:Page<User> ---> PageDTO<UserVO>
        return PageDTO.of(p, UserVO.class);
    }

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

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

相关文章

go-zero框架基本配置和错误码封装

文章目录 加载配置信息配置 env加载.env文件配置servicecontext 查询数据生成model文件执行查询操作 错误码封装配置拦截器错误码封装 接上一篇&#xff1a;《go-zero框架快速入门》 加载配置信息 配置 env 在项目根目录下新增 .env 文件&#xff0c;可以配置当前读取哪个环…

JavaScript学习笔记(1)

html 完成了架子&#xff0c; css 做了美化&#xff0c;但是网页是死的&#xff0c;我们需要给他注入灵魂&#xff0c;所以接下来我们需要学习 JavaScript&#xff0c;这门语言会让我们的页面能够和用户进行交互。 一、引入方式 1.内部脚本 将 JS 代码定义在 HTML 页面中 Jav…

FPGA自分频产生的时钟如何使用?

对于频率比较小的时钟&#xff0c;使用clocking wizard IP往往不能产生&#xff0c;此时就需要我们使用代码进行自分频&#xff0c;自分频产生的时钟首先应该经过BUFG处理&#xff0c;然后还需要进行时钟约束&#xff0c;处理之后才能使用。

(1)STM32 USB设备开发-基础知识

开篇感谢&#xff1a; 【经验分享】STM32 USB相关知识扫盲 - STM32团队 ST意法半导体中文论坛 单片机学习记录_桃成蹊2.0的博客-CSDN博客 USB_不吃鱼的猫丿的博客-CSDN博客 1、USB鼠标_哔哩哔哩_bilibili usb_冰糖葫的博客-CSDN博客 USB_lqonlylove的博客-CSDN博客 USB …

9、Docker环境安装Nginx

一、拉取镜像 docker pull nginx:1.24.0二、创建映射目录 作用&#xff1a;是将docker中nginx的相关配置信息映射到外面&#xff0c;方便修改配置文件 1、创建目录 # cd home/ # mkdir nginx/ # cd nginx/ # mkdir conf html log2、生成容器 docker run -p 80:80 -d --name…

linux 下tensorrt的yolov8的前向推理(c++ 版本)的实现

一、环境搭建 cuda 11.4 ubuntu 20.04 opencv-4.5.2 1.1 配置tensorrt 根据本机的硬件配置及cuda的版本&#xff0c;选择TensorRT-8.6.1.6的版本&#xff0c;下载网址为: TensorRT SDK | NVIDIA Developer 根据官网的说明&#xff0c;下载对应的压缩包即可。解压后&…

【前端】Hexo 建站指南

文章目录 前言生成站点本地测试部署云端参考 前言 更好的阅读体验&#xff1a;https://blog.dwj601.cn/FrontEnd/Hexo/build-your-own-website-with-hexo/ 笔记记多了&#xff0c;想要分享给同学们一起交流进步&#xff0c;该怎么办&#xff1f;想要搭建一个属于自己的知识库…

LetsWave脑电数据简单时频分析及画图matlab(二)

在笔记&#xff08;一&#xff09;中的文档链接&#xff0c;有很详细的介绍时频分析。这里简单描述&#xff0c;letswave7中有两种方法&#xff0c;一种是STFT&#xff08;短时傅里叶变换&#xff09;和CWT&#xff08;连续小波变换&#xff09;。&#xff08;一&#xff09;中…

【二叉树的深搜】二叉树剪枝

文章目录 814. 二叉树剪枝解题思路&#xff1a;深度优先遍历 后序遍历另一种写法 814. 二叉树剪枝 814. 二叉树剪枝 ​ 给你二叉树的根结点 root &#xff0c;此外树的每个结点的值要么是 0 &#xff0c;要么是 1 。 ​ 返回移除了所有不包含 1 的子树的原二叉树。 ​ 节点…

快速搭建深度学习环境(Linux:miniconda+pytorch+jupyter notebook)

本文基于服务器端环境展开&#xff0c;使用的虚拟终端为Xshell。 miniconda miniconda是Anaconda的轻量版&#xff0c;仅包含Conda和Python&#xff0c;如果只做深度学习&#xff0c;可使用miniconda。 [注]&#xff1a;Anaconda、Conda与Miniconda Conda&#xff1a;创建和管…

01-硬件入门学习/嵌入式教程-CH340C使用教程

前言 CH340C广泛应用于DIY项目和嵌入式开发中&#xff0c;用于USB数据转换和串口通信。本文将详细介绍CH340C的基本功能、引脚接线及使用方法。 CH340C简介 CH340C是一款USB转TTL电平转换器&#xff0c;可以将电脑的USB数据转换成串口数据&#xff0c;方便与单片机&#xff…

PID 控制算法(二):C 语言实现与应用

在本文中&#xff0c;我们将用 C 语言实现一个简单的 PID 控制器&#xff0c;并通过一个示例来演示如何使用 PID 控制算法来调整系统的状态&#xff08;如温度、速度等&#xff09;。同时&#xff0c;我们也会解释每个控制参数如何影响系统的表现。 什么是 PID 控制器&#xf…

C语言数组详解:从基础到进阶的全面解析

在C语言中&#xff0c;数组是一种基本的数据结构&#xff0c;用于存储多个相同类型的数据。数组的引入使得C语言能够高效地存储和操作大量数据。在任何一个C语言程序中&#xff0c;数组都发挥着极其重要的作用。无论是在算法实现、数据存储、还是在复杂程序的设计中&#xff0c…

vulfocus/fastjson-cnvd_2017_02833复现

漏洞概述 Fastjson 是阿里巴巴开发的一个高性能的 Java 库&#xff0c;用于将 Java 对象转换成 JSON 格式&#xff08;序列化&#xff09;&#xff0c;以及将 JSON 字符串转换回 Java 对象&#xff08;反序列化&#xff09;。 fastjson在解析json的过程中,支持使用type字段来指…

【unity游戏开发之InputSystem——05】PlayerInput组件的介绍(基于unity6开发介绍)

文章目录 前言一、认识PlayerInput1、PlayerInput是什么?2、主要工作原理:3、好处:二、添加PlayerInput组件三、PlayerInput参数相关1、Actions:行为2、Default Scheme:默认启用哪个控制方案3、Auto-Switch:自动切换控制方案4、Default Map:默认行为映射方案5、Ui Input…

Android GLSurfaceView 覆盖其它控件问题 (RK平台)

平台 涉及主控: RK3566 Android: 11/13 问题 在使用GLSurfaceView播放视频的过程中, 增加了一个播放控制面板, 覆盖在视频上方. 默认隐藏setVisibility(View.INVISIBLE);点击屏幕再显示出来. 然而, 在RK3566上这个简单的功能却无法正常工作. 通过缩小视频窗口可以看到, 实际…

【2024 - 年终总结】叶子增长,期待花开

写在前面&#xff1a;本博客仅作记录学习之用&#xff0c;部分图片来自网络&#xff0c;如需引用请注明出处&#xff0c;同时如有侵犯您的权益&#xff0c;请联系删除&#xff01; 文章目录 前言论博客创作保持2024的记录清单博客科研开源工作生活 总结与展望互动致谢参考 前言…

TangoFlux 本地部署实用教程:开启无限音频创意脑洞

一、介绍 TangoFlux是通过流匹配和 Clap-Ranked 首选项优化&#xff0c;实现超快速、忠实的文本到音频生成的模型。 本模型由 Stability AI 提供支持&#x1f680; TangoFlux 可以在单个 A40 GPU 上在 ~3 秒内生成长达 34.1kHz 的立体声音频。 二、部署 安装方式非常简单 1…

ThreeJS示例教程200+【目录】

Three.js 是一个强大的 JavaScript 库,旨在简化在网页上创建和展示3D图形的过程。它基于 WebGL 技术,但提供了比直接使用 WebGL 更易于使用的API,使得开发者无需深入了解 WebGL 的复杂细节就能创建出高质量的3D内容。 由于目前内容还不多,下面的内容暂时做一个占位。 文章目…

AIGC的企业级解决方案架构及成本效益分析

AIGC的企业级解决方案架构及成本效益分析 一,企业级解决方案架构 AIGC(人工智能生成内容)的企业级解决方案架构是一个多层次、多维度的复杂系统,旨在帮助企业实现智能化转型和业务创新。以下是总结的企业级AIGC解决方案架构的主要组成部分: 1. 技术架构 企业级AIGC解决方…