Mybatis-Plus(企业实际开发应用)

一、Mybatis-Plus简介

MyBatis-Plus是MyBatis框架的一个增强工具,可以简化持久层代码开发MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

官网:MyBatis-Plus

当前版本:

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus</artifactId><version>3.5.3.2</version>
</dependency>

MyBatis-Plus特性:

• 无侵入:只做增强不做改变,不会对现有工程产生影响

• 强大的 CRUD 操作:内置通用 Mapper,少量配置即可实现单表CRUD 操作

• 支持 Lambda:编写查询条件无需担心字段写错

• 支持主键自动生成

• 内置分页插件

开发方式:

• 单独使用 MyBatis-Plus

• 基于 Spring 使用 MyBatis-Plus

基于 SpringBoot 使用 MyBatis-Plus(最常用) 

二、CRUD接口

2.1环境搭建 

①:创建maven工程,并配置相关基础信息

②:配置pom文件

<?xml version="1.0" encoding="UTF-8"?>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.0</version><relativePath/></parent><groupId>com.itheima</groupId><artifactId>mp-demo</artifactId><version>0.0.1-SNAPSHOT</version><properties><java.version>11</java.version></properties><dependencies><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.4.3</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.16</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.12</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>

 ③:配置数据源(application.yml)

#数据源
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/mp?useSSL=false&serverTimezone=UTCusername: rootpassword: root
#mybatis-plus
mybatis-plus:mapper-locations: classpath:/mapper/*Mapper.xmlconfiguration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

⑤:创建实体类与表结构(类名与表名对应,属性名与字段名对应)

可以使用MybatisHelper插件自动生成实体类和Mapper

@TableName(value = "`user`")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {/*** 用户id*/@TableId(value = "id", type = IdType.INPUT)private Long id;/*** 用户名*/@TableField(value = "username")private String username;/*** 密码*/@TableField(value = "`password`")private String password;/*** 注册手机号*/@TableField(value = "phone")private String phone;/*** 详细信息*/@TableField(value = "info")private String info;/*** 使用状态(1正常 2冻结)*/@TableField(value = "`status`")private Integer status;/*** 账户余额*/@TableField(value = "balance")private Integer balance;/*** 创建时间*/@TableField(value = "create_time")private Date createTime;/*** 更新时间*/@TableField(value = "update_time")private Date updateTime;/*** 获取用户id** @return id - 用户id*/public Long getId() {return id;}/*** 设置用户id** @param id 用户id*/public void setId(Long id) {this.id = id;}/*** 获取用户名** @return username - 用户名*/public String getUsername() {return username;}/*** 设置用户名** @param username 用户名*/public void setUsername(String username) {this.username = username;}/*** 获取密码** @return password - 密码*/public String getPassword() {return password;}/*** 设置密码** @param password 密码*/public void setPassword(String password) {this.password = password;}/*** 获取注册手机号** @return phone - 注册手机号*/public String getPhone() {return phone;}/*** 设置注册手机号** @param phone 注册手机号*/public void setPhone(String phone) {this.phone = phone;}/*** 获取详细信息** @return info - 详细信息*/public String getInfo() {return info;}/*** 设置详细信息** @param info 详细信息*/public void setInfo(String info) {this.info = info;}/*** 获取使用状态(1正常 2冻结)** @return status - 使用状态(1正常 2冻结)*/public Integer getStatus() {return status;}/*** 设置使用状态(1正常 2冻结)** @param status 使用状态(1正常 2冻结)*/public void setStatus(Integer status) {this.status = status;}/*** 获取账户余额** @return balance - 账户余额*/public Integer getBalance() {return balance;}/*** 设置账户余额** @param balance 账户余额*/public void setBalance(Integer balance) {this.balance = balance;}/*** 获取创建时间** @return create_time - 创建时间*/public Date getCreateTime() {return createTime;}/*** 设置创建时间** @param createTime 创建时间*/public void setCreateTime(Date createTime) {this.createTime = createTime;}/*** 获取更新时间** @return update_time - 更新时间*/public Date getUpdateTime() {return updateTime;}/*** 设置更新时间** @param updateTime 更新时间*/public void setUpdateTime(Date updateTime) {this.updateTime = updateTime;}
}

Mapper 

@Mapper
public interface UserMapper extends BaseMapper<User> {
}
2.2 新增操作

新增操作可以调用BaseMapper中提供的insert方法:

/*** 插入一条记录** @param entity 实体对象*/
int insert(T entity);

单元测试方法:

    /*** 新增数据*/
@Testpublic void testInsert(){User user = User.builder().username("老八1").password(Base64.getEncoder().encodeToString("123456".getBytes())).phone("18941199302").info("{\"age\": 20, \"intro\": \"青涩老八\", \"gender\": \"female\"}").createTime(Date.from(Instant.now())).updateTime(Date.from(Instant.now())).build();userMapper.insert(user);}

2.3 删除操作

删除操作可以调用BaseMapper中提供的deleteById和deleteBatchIds方法:

/*** 根据 ID 删除** @param id 主键ID*/
int deleteById(Serializable id);

单元测试方法:  

    /*** 删除数据*/@Testpublic void testDelete(){userMapper.deleteById(7L);}
/*** 删除(根据ID 批量删除)** @param idList 主键ID列表(不能为 null 以及 empty)*/
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

 单元测试方法:

//根据id批量删除数据int batchIds = userMapper.deleteBatchIds(1L,2L,3L);//可变参数System.out.println(batchIds);
2.4 修改操作
/*** 根据 ID 修改** @param entity 实体对象*/
int updateById(@Param(Constants.ENTITY) T entity);

 单元测试方法:

    /*** 根据Id修改*/@Testpublic void testUpdate(){User user = new User();user.setId(2L);user.setUsername("老六");userMapper.updateById(user);}

2.5 查询操作
/*** 根据 ID 查询** @param id 主键ID*/
T selectById(Serializable id);

单元测试:

    /*** 根据Id查找*/@Testpublic void testSelect(){User user = userMapper.selectById(1);System.out.println(user);}
/*** 查询(根据ID 批量查询)** @param idList 主键ID列表(不能为 null 以及 empty)*/
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);

 单元测试:

   //根据id批量查询数据List<User> users = userMapper.selectBatchIds(Arrays.asList(1625307405933957121L, 1625310776384380930L));System.out.println(users);
/*** 根据 entity 条件,查询全部记录(并翻页)** @param page         分页查询条件(可以为 RowBounds.DEFAULT)* @param queryWrapper 实体对象封装操作类(可以为 null)*/
<E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

注意如果要实现分页功能,需要配置MP框架的分页拦截器:

@Configuration
public class MPConfig {@Beanpublic MybatisPlusInterceptor  pageinitInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//乐观锁mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());//分页配置mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL) );return mybatisPlusInterceptor;}
}

 单元测试:

    /*** 分页查询*/@Testpublic void findPage(){IPage<User> page = new Page<>(1,3);userMapper.selectPage(page,null);System.out.println("总页数:" + page.getPages());System.out.println("总记录数:" + page.getTotal());System.out.println("当前页的页码:" + page.getCurrent());System.out.println("每页的数量:" + page.getSize());System.out.println("查到的当前页的内容:" + page.getRecords());}

三、常用注解

3.1 @TableName注解

通过@TableName注解可以映射实体类和表的对应关系。

  • 名称:@TableName

  • 类型:类注解

  • 位置:模型类上

  • 作用:设置当前类对应与数据库表关系

  • 范例:

@TableName("t_user") //当前实体类对应的表为t_user
public class User {private Long id;
}

注:如果类名和表名一致,MP可以自动进行映射,此时 @TableName 注解可以省略

3.2 @TableField注解

通过@TableField注解可以映射实体类的属性和表字段的对应关系。

  • 名称:@TableField

  • 类型:属性注解

  • 位置:模型类属性上

  • 作用:设置当前属性对应的数据库表中的字段关系

  • 相关属性:

    value:设置数据库表字段名称

    exist:设置属性在数据库表字段中是否存在,默认为true

  • 范例:

public class User {@TableField(value="pwd") //当前属性对应的字段为pwdprivate String password;@TableField(exist = false) //当前属性在表中没有对应的字段private String online;
}

如果属性名和字段名一致,MP可以自动进行映射,此时 @TableField 注解可以省略

如果属性名使用驼峰命名法命名,字段名使用对应的下划线分隔命名,MP可以自动进行映射,此时 @TableField 注解可以省略。

3.3 @TableId注解

 通过@TableId注解可以映射实体类的属性和表主键字段的对应关系,还可以设置主键的生成策略。

  • 名称:@TableId

  • 类型:属性注解

  • 位置:模型类中用于表示主键的属性上

  • 作用:映射类中属性和表中主键对应关系,设置主键的生成策略

  • 相关属性:

    value:设置数据库主键字段名称,如果属性名和字段名一致,可以省略此属性

    type:设置主键属性的生成策略,值参照IdType枚举值

  • 范例:

public class User {@TableId(type = IdType.AUTO) //当前id属性和表的主键字段id对应,并且设置主键生成策略为AUTOprivate Long id;
}

主键生成策略:

  • AUTO(0):使用数据库id自增策略控制id生成

  • NONE(1):不设置id生成策略

  • INPUT(2):用户手工输入id

  • ASSIGN_ID(3):雪花算法生成id(可兼容数值型与字符串型)

  • ASSIGN_UUID(4):以UUID生成算法作为id生成策略

为了简化开发,可以在application.yml中配置全局的主键生成策略:

mybatis-plus:global-config:db-config:id-type: assign_id #全局设置主键生成策略

注:配置了全局的主键生成策略,在实体类中就无须再配置主键生成策略了。

四、条件构造器

4.1 条件构造器介绍

通过条件构造器(Wrapper),可以控制最终生成的 SQL 语句的条件部分,如下:

  • select_____________ from table where_________ order by

  • update table set________ where_________

  • delete from table where___________

通过条件构造器,就可以控制上面SQL语句中位置的SQL片段,在项目开发过程中经常使用到。

BaseMapper中的很多方法,都需要条件构造器作为参数,如下:

条件构造器的顶级父类为Wrapper:

条件构造器的继承关系如下:

使用比较多的条件构造器:

  • QueryWrapper

  • LambdaQueryWrapper

  • UpdateWrapper

  • LambdaUpdateWrapper

4.2 QueryWrapper

 通过 QueryWrapper 条件构造器,可以控制最终生成的查询、删除类的SQL语句。

SQL结构:

  • select ___ from table where ___ order by ___

  • delete from table where ___

  /*** 根据条件动态查询*/@Testpublic void selectList(){QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select("id","username","password","info") //设置查询字段.like("username","浩") //模糊查询.orderByDesc("id"); //排序条件List<User> userList = userMapper.selectList(queryWrapper);System.out.println(userList);}

分页查询

    /*** 分页查询*/@Testpublic void findPage() {IPage<User> page = new Page<>(1, 3);userMapper.selectPage(page, null);System.out.println("总页数:" + page.getPages());System.out.println("总记录数:" + page.getTotal());System.out.println("当前页的页码:" + page.getCurrent());System.out.println("每页的数量:" + page.getSize());System.out.println("查到的当前页的内容:" + page.getRecords());}

 配置分页拦截器

/*** TODO 类描述** @author Aaron.* @date 2023/10/24 11:18*/
@Configuration
public class MPConfig {@Beanpublic MybatisPlusInterceptor  pageinitInterceptor(){MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();//乐观锁mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());//分页配置mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL) );return mybatisPlusInterceptor;}
}

4.3 LambdaQueryWrapper

LambdaQueryWrapper的作用和QueryWrapper相同,都是控制最终生成的查询、删除类的SQL语句。不同点在于语法层面。QueryWrapper是通过字段名来设置条件,LambdaQueryWrapper是通过Lambda语法来设置条件,可以做到在编译期就能够发现错误。

    @Testpublic void testLambdaQueryByQueryWrapper() {LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<User>().like(User::getUsername, "o").gt(User::getBalance, 2000);List<User> users = userMapper.selectList(lambdaQueryWrapper);for (User user : users) {System.out.println(user);}}

项目开发中建议使用 LambdaQueryWrapper 来代替 QueryWrapper。

4.4 UpdateWrapper

 通过 UpdateWrapper 条件构造器,可以控制最终生成的更新类的SQL语句。

SQL结构:

  • update table set ___ where ___

BaseMapper中的如下方法可以传入UpdateWrapper对象:  

    //将Id为1、5、7的人员工资扣200@Testpublic void testUpdateWrapper() {UpdateWrapper<User> wrapper = new UpdateWrapper<User>().setSql("balance = balance - 200").in("id", 1L, 5L, 7L);userMapper.update(null, wrapper);}

使用 BaseMapper 的 update 方法设置 set 条件时,既可以通过第一个参数(实体对象)设置,也可以通过第二个参数(UpdateWrapper)设置。

注:使用UpdateWrapper设置条件时,是通过字符串指定字段名,如果字段名有误,在编译阶段无法发现错误,在程序运行阶段会抛出异常。

4.5 LambdaUpdateWrapper

 LambdaUpdateWrapper的作用和UpdateWrapper相同,都是控制最终生成的更新类的SQL语句。不同点在于语法层面。UpdateWrapper是通过字段名来设置条件,LambdaUpdateWrapper是通过Lambda语法来设置条件,可以做到在编译期就能够发现错误。

    //使用LambdaWrapper进行查询@Testpublic void testSelectWithLambdaWrapper() {//select username,info from user where status = 1 order by balance DescLambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.select(User::getUsername, User::getInfo).eq(User::getStatus, 1).orderByDesc(User::getBalance);userMapper.selectList(wrapper);}
4.6 润物无声

已经使用了MP,还能够使用 mybatis 进行 SQL 定义吗?

注意:MP只是对 mybatis 框架进行增强,不会改变 mybatis 框架的使用方法。也就是说原来怎么使用 mybatis 的,现在还可以按照原来的方式使用即可,如下:

为了进一步增强 mybatis 的功能,我们还可以在 Mapper 中声明方法时,方法的参数使用MP提供的Wrapper条件构造器对象,例如:

上面Mapper中声明的findByCondition方法,参数为 Wrapper类型,即条件构造器对象。并且通过@Param注解修饰,为其指定了别名为ew,这样就可以在SQL语句中通过 ${ew.customSqlSegment} 来获取到对应的SQL片段,这个SQL片段就是通过当前Wrapper对象解析成的。

注意,customSqlSegment为固定写法,底层会调用Wrapper对象的getCustomSqlSegment方法来获取对应的SQL片段。下面是Wrapper类的部分源码:

  

在单元测试方法中测试findByCondition方法  

五、扩展功能

5.1 逻辑删除

删除数据库中的数据,可以通过物理删除,也可以通过逻辑删除。

  • 物理删除 指的是直接将数据从数据库中删除,执行的是delete语句

  • 逻辑删除 指的是修改数据的某个字段,使其表示为已删除状态,执行的是update语句

如下是逻辑删除的效果,在表中增加deleted字段,标识数据是否被删除(例如:1表示删除,0表示未删除)。

注意:对于重要的、后期可能需要恢复的数据,可以考虑使用逻辑删除

由于在项目开发过程中经常会使用到逻辑删除,所以MP框架已经对逻辑删除提供了实现,我们直接使用即可。

具体使用步骤如下:

第二步:在application.yml中配置逻辑删除相关配置项

      logic-delete-field: deleted #指定用于标记数据被删除的字段名logic-delete-value: 1 #表示已删除logic-not-delete-value: 0 #表示未删除

 第三步:在实体类中加入逻辑删除属性(和表中的逻辑删除字段对应),并加入 @TableLogic 注解

加入逻辑删除后,再次调用BaseMapper的删除方法和查询方法,发出的SQL语句已经发生了变化。

删除数据时发出的SQL为update语句,将deleted字段的值改为1,表示当前数据被删除了。

查询数据时发出的SQL语句自动追加上查询条件 deleted=0,表示查询的数据是未删除的数据。

5.2 MP对于Service层的支持

MP 框架除了可以简化持久层代码开发,还为 Service 层提供了业务接口和实现类,可以简化 Service 层的开发。

MP提供的业务接口:

MP提供的业务层实现类:

5.3 代码生成器

MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

安装方法:打开 IDEA,进入 File -> Settings -> Plugins -> Browse Repositories,输入 mybatisx 搜索并安装,如下所示:

代码生成器的操作步骤:

① 在IDEA的DataBase窗口中配置数据源

 ② 通过代码生成器提供的菜单项生成代码

选中表,然后点右键,在弹出的菜单中点击 MybatisX-Generator,此时会弹出如下窗口:

module path:指定代码生成到哪个模块中

base-package:指定代码生成的包结构

ignore table prefix:忽略表名前缀,例如表名为t_user,此时指定当前输入框为t_,则生成的实体类名就是User,否则生成的实体类名为TUser

ignore field prefix:忽略字段名前缀,例如字段名为f_name,此时指定当前输入框为f_,则生成的属性名就是name,否则生成的属性名为fName

通过代码生成器,就可以根据表结构,反向生成对应的实体类、Mapper、Service等,可以简化开发,提供开发效率。

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

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

相关文章

Python深度学习实战-基于class类搭建BP神经网络实现分类任务(附源码和实现效果)

实现功能 上篇文章介绍了用Squential搭建BP神经网络&#xff0c;Squential可以搭建出上层输出就是下层输入的顺序神经网络结构&#xff0c;无法搭出一些带有跳连的非顺序网络结构&#xff0c;这个时候我们可以选择类class搭建封装神经网络结构。 第一步&#xff1a;import ten…

基于情感词典的情感分析方法

计算用户情绪强弱性&#xff0c;对于每一个文本都可以得到一个情感分值&#xff0c;以情感分值的正负性表示情感极性&#xff0c;大于0为积极情绪&#xff0c;小于0反之&#xff0c;绝对值越大情绪越强烈。 基于情感词典的情感分析方法主要思路&#xff1a; 1、对文本进行分词…

影响光源的因素

影响光源的因素 对比度 1.对比度 均匀性 2.均匀性 色彩还原性 3.色彩还原性 其他因素&#xff1a; 4. 亮度 &#xff1a; 光源 亮度是光源选择时的重要参考&#xff0c;尽量选择亮度高的光源。 5. 鲁棒性 &#xff1a; 鲁棒性是指光源是否对部件的位置敏感度最小 。 6. 光…

不同设备的请求头信息UserAgent,Headers

一、电脑端 【设备名称】&#xff1a;电脑 Win10 【应用名称】&#xff1a;win10 Edge 【浏览器信息】&#xff1a;名称:(Chrome)&#xff1b;版本:(70.0) 【请求头信息】&#xff1a;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Ch…

企业如何安全跨国传输30T文件数据

对于一些对数据敏感性比较高的企业&#xff0c;如IT企业和国企等&#xff0c;跨国数据传输是当今企业面临的一个重要挑战&#xff0c;尤其是当数据量达到30T这样的规模时&#xff0c;如何保证数据的速度、安全和合规性&#xff0c;就成为了企业必须考虑的问题。本文将从以下几个…

【Java题】输出基本数据类型的最大值和最小值,以及float和double的正无穷大值和负无穷大值

一&#xff1a;代码 public class Test {public static void main(String[] args) {//输出byte型的最大值与最小值System.out.println(Byte.MAX_VALUE);System.out.println(Byte.MIN_VALUE);//输出short型的最大值与最小值System.out.println(Short.MAX_VALUE);System.out.pri…

RTE(Runtime Environment)

RTE&#xff08;Runtime Environment&#xff09;是一个运行时环境&#xff0c;在这个环境里&#xff0c;你可以实现的功能是&#xff1a; 作为一个缓冲buffer给应用层和BSW层的接口&#xff08;例如COM&#xff09;用来存储数据&#xff0c;也就是说定义一个全局变量供上层和下…

Django实战项目-学习任务系统-任务管理

接着上期代码框架&#xff0c;开发第3个功能&#xff0c;任务管理&#xff0c;再增加一个学习任务表&#xff0c;用来记录发布的学习任务的标题和内容&#xff0c;预计完成天数&#xff0c;奖励积分和任务状态等信息。 第一步&#xff1a;编写第三个功能-任务管理 1&#xff0…

二、BurpSuite Decoder解码器

一、编码解码 解释&#xff1a;BurpSuite 可以用这个模块来轻松进行编码解码&#xff0c;下面是支持的类型 URL HTML Base64 ASCIIhex Hex Octal Binary Gzip 注意&#xff1a;特别注意的是URL编码&#xff0c;一般的在线网站都无法对比如‘abc’的文本编码&#xff0c;burps…

目标检测及锚框、IoU

1. 目标检测 物体检测&#xff08;目标检测&#xff09;是计算机视觉和数字图像处理的热门方向&#xff0c;意在判断一幅图像上是否存在感兴趣物体&#xff0c;并给出物体分类及位置等&#xff08;What and Where&#xff09;。本文主要进行物体检测研究背景、发展脉络、相关算…

禁止chrome浏览器更新方式

1、禁用更新服务 WinR调出运行&#xff0c;输入services.msc&#xff0c;进入服务。 在服务中有两个带有Google Update字样&#xff0c;双击打开后禁用&#xff0c;并把恢复选项设置为无操作。 2、删除计划任务 运行taskschd.msc&#xff0c;打开计划任务程序库&#xff0c;在…

SDRAM学习笔记(MT48LC16M16A2,w9812g6kh)

一、基本知识 SDRAM : 即同步动态随机存储器&#xff08;Synchronous Dynamic Random Access Memory&#xff09;, 同步是指其时钟频率与对应控制器&#xff08;CPU/FPGA&#xff09;的系统时钟频率相同&#xff0c;并且内部命令 的发送与数据传输都是以该时钟为基准&#xff…

【C#】LIMS实验室信息管理系统源码

一、系统概述 LIMS(Laboratory Information Management System)即实验室信息管理系统,是通过对样品检验流程、分析数据及报告、实验室资源和客户信息等要素的综合管理,按照标准化实验室管理规范,建立符合实验室业务流程的质量体系,实现实验室信息化管理。是实验室提高分析水平…

CSS 滚动驱动动画与 @keyframes 新语法

CSS 滚动驱动动画与 keyframes 在 CSS 滚动驱动动画相关的属性出来之后, keyframes 也迎来变化. 以前, keyframes 的值可以是 from, to, 或者百分数. 现在它多了一种属性的值 <timeline-range-name> <percentage> 建议先了解 animation-range 不然你会对 timeli…

[RISC-V]verilog

小明教IC-1天学会verilog(7)_哔哩哔哩_bilibili task不可综合&#xff0c;function可以综合

4+非肿瘤纯生信。氧化应激+WGCNA+药物预测筛序关键基因

今天给同学们分享一篇非肿瘤氧化应激WGCNA的生信文章“Identification of oxidative stress-related biomarkers associated with the development of acute-on-chronic liver failure using bioinformatics”&#xff0c;这篇文章于2023年10月10日发表在Scientific Reports期刊…

数据库数据恢复—Oracle数据库报错ORA-01110错误的数据恢复案例

Oracle数据库故障&#xff1a; 北京某公司一台运行oracle数据库的服务器&#xff0c;机房意外断电导致该服务器重启&#xff0c;重启后发现oracle数据库报错。该Oracle数据库没有备份。 Oracle数据库数据恢复过程&#xff1a; 1、北亚企安数据恢复工程师检查该oracle数据库的数…

input改造文件上传,el-table的改造,点击上传,拖拽上传,多选上传

第一个input标签效果 第二个input标签的效果 el-table的改造效果 <template><div class"outerBox"><div class"analyze" v-if"status"><div class"unFile"><div class"mainBox"><img clas…

黔院长 | 黄帝内经:人有四经十二从!

"人有四经十二从"这句话出自《黄帝内经素问》&#xff0c;“四经”指的是与四时相应的正常脉象&#xff0c;也是指四个主要经络&#xff1a;太阳经、少阳经、太阴经和少阴经。在中医理论当中这些经络被认为是人体气血运行的通道。 而“十二从”则表示人体的十二个经脉…

计算机毕设 基于CNN实现谣言检测 - python 深度学习 机器学习

文章目录 1 前言1.1 背景 2 数据集3 实现过程4 CNN网络实现5 模型训练部分6 模型评估7 预测结果8 最后 1 前言 Hi&#xff0c;大家好&#xff0c;这里是丹成学长&#xff0c;今天向大家介绍 一个深度学习项目 基于CNN实现谣言检测 1.1 背景 社交媒体的发展在加速信息传播的…