Mybatis-Plus中update更新操作用法
目录
- 一、前言
- 二、update
- 1、关于修改的4个条件构造器
- 2、UpdateWrapper【用法示例】
- 3、LambdaUpdateWrapper【用法示例】
- 4、UpdateChainWrapper【 用法示例】
- 5、LambdaUpdateChainWrapper【 用法示例】
- 6、updateById 和 updateBatchById
- 7、Mybatis-plus设置某个字段值为null的方法总结
- 三、saveOrUpdate
- 1、saveOrUpdate 【用法示例】
- 2、saveOrUpdateBatch【用法示例】
- 3、批量插入优化
- 四、防全表更新与删除插件
一、前言
在Mybatis-Plus官网当中并没有对于update进行针对性的详细讲解以及其使用,很多初级小白都用不明白,包括我有时候都迷迷糊糊的,基于这个问题我也是下定决心好好整理一篇。本篇文章重点是通过多个案例来进行讲解,每一个案例执行出来的sql我都会放到文章当中,方便大家快速掌握并使用!
在实际开发当中我们一般都是将service的接口继承IService<T>
,然后serviceImpl继承ServiceImpl<M extends BaseMapper<T>, T>
,mapper接口继承BaseMapper<T>
BaseMapper相对来说方法比较少,一般都是通过service接口或者serviceImpl来使用,其update的相关方法有如下:
二、update
update方法主要有以下:
// 返回UpdateChainWrapper,主要用来链式调用
UpdateChainWrapper update();
// 返回LambdaUpdateChainWrapper ,同样是主要用来链式调用,只不过是基于Lambda的
LambdaUpdateChainWrapper lambdaUpdate();
// 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根据 whereWrapper 条件,更新记录
boolean update(T updateEntity, Wrapper<T> whereWrapper);
// 根据 ID 选择修改
boolean updateById(T entity);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根据ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);
参数说明
1、关于修改的4个条件构造器
Mybatis-Plus给我们提供了4个关于Java修改的条件构造器,这四个构造器的顶级父类都是Wrapper
- UpdateWrapper
UpdateWrapper<User> objectUpdateWrapper = new UpdateWrapper<>();
UpdateWrapper<User> update1 = Wrappers.update();
- LambdaUpdateWrapper:
LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper();
LambdaUpdateWrapper<User> updateWrapper = new UpdateWrapper().lambda();
LambdaUpdateWrapper<User> objectLambdaUpdateWrapper = Wrappers.lambdaUpdate();
- UpdateChainWrapper:可以new,但是必须传入BaseMapper参数或者是传入实体类的字节码,可以通过service来声明。
@Resource
private UserService userService;@Resource
private UserMapper userMapper;@Test
void contextLoads() {UpdateChainWrapper<User> update = userService.update();UpdateChainWrapper<User> userUpdateChainWrapper = new UpdateChainWrapper<>(User.class);UpdateChainWrapper<User> userUpdateChainWrapper1 = new UpdateChainWrapper<>(userMapper);
}
- LambdaUpdateChainWrapper:同UpdateChainWrapper一样,可以new,但是必须传入BaseMapper参数或者是传入实体类的字节码,可以通过service来声明,
LambdaUpdateChainWrapper<User> userLambdaUpdateChainWrapper = userService.lambdaUpdate();
UpdateChainWrapper和LambdaUpdateChainWrapper都继承了AbstractChainWrapper,而UpdateWrapper和LambdaUpdateWrapper都继承了AbstractWrapper。AbstractChainWrapper和AbstractWrapper都继承了Wrapper。
在上面我们也了解到了Mybatis-Plus给我们提供了好几个update方法,并且传参都离不开Wrapper,下面我们将通过不同的Wrapper和不同的方法进行结合起来,彻底了解清楚什么时候该用什么方法!
2、UpdateWrapper【用法示例】
UpdateWrapper当中主要这四个方法用的比较多一点
set(String column, Object val)
set(boolean condition, String column, Object val)
setSql(String sql)
setSql(boolean condition, String sql)
参数解释:
类型 | 参数名 | 描述 |
---|---|---|
String | column | 数据库当中的字段名称 |
Object | val | 需要修改的数据 |
boolean | condition | 判断条件,控制该sql是否用到条件当中,假如为true代表生效 |
String | sql | 拼接sql |
(1)使用场景一:
UpdateWrapper<User> updateWrapper = Wrappers.update();
// 修改表中name字段为指定的数据
updateWrapper.set("name", "123");
// 假如age不等于空,那么我就将age修改为我指定的参数
Integer age = 66;
updateWrapper.set(age != null, "age", age);
updateWrapper.set("email", "99999@qq.com");
// 修改条件为id=5的数据
updateWrapper.eq("id", 5);
// 假如修改失败返回值为false
boolean update = userService.update(updateWrapper);
日志打印出来的sql:
UPDATE user SET name='123',age=66,email='99999@qq.com' WHERE (id = 5)
使用 boolean update(Wrapper<T> updateWrapper);
修改,他本质上就是调用的update(T updateEntity, Wrapper<T> whereWrapper);
,只不过Entity传的为null!
(2)使用场景二:把所有set值全去掉,只使用UpdateWrapper作为修改的条件,然后通过Entity赋值
UpdateWrapper<User> updateWrapper = Wrappers.update();
// 修改条件为id=5的数据
updateWrapper.eq("id", 5);
User user = new User();
user.setName("wdawdwa");
user.setAge(888);
user.setEmail("dwadwad@qq.com");
// 假如修改失败返回值为false
boolean update = userService.update(user, updateWrapper);
日志打印出来的sql:
UPDATE user SET name='wdawdwa', age=888, email='dwadwad@qq.com' WHERE (id = 5)
(3)Entity之和UpdateWrapper两种赋值方式同时使用:
接下来我们进行测试看看boolean update(T updateEntity, Wrapper<T> whereWrapper);
假如同时使用两种赋值方式会是什么样的。
UpdateWrapper<User> updateWrapper = Wrappers.update();// 修改表中name字段为指定的数据
updateWrapper.set("name", "123");
// 假如age不等于空,那么我就将age修改为我指定的参数
Integer age = 66;
updateWrapper.set(age != null, "age", age);
updateWrapper.set("email", "99999@qq.com");
// 修改条件为id=5的数据
updateWrapper.eq("id", 5);User user = new User();
user.setName("wdawdwa");
user.setEmail("99999@qq.com");// 假如修改失败返回值为false
boolean update = userService.update(user, updateWrapper);
日志打印出来的sql:
UPDATE user SET name='wdawdwa', age=0, email='99999@qq.com', name='123222',age=66 WHERE (id = 5)
得出结论:
- updateWrapper和Entity同时对name进行赋值,很显然Entity根本没起到作用的哈!updateWrapper优先级要高于Entity。
- 最终查询出来的sql是updateWrapper和Entity两种赋值方式的并集。并不会因为使用了updateWrapper.set赋值就导致整个Entity失效!
(4)现在有一个疑问需要验证一下,new出来的user并没有对email字段赋值,那么他会不会将数据库当中的email赋值为null。
下面我们进行验证,我user表有好几个字段,我只修改了两个!
UpdateWrapper<User> updateWrapper = Wrappers.update();
updateWrapper.eq("id", 5);
User user = new User();
user.setName("wdawdwa");
user.setAge(888);
boolean update = userService.update(user, updateWrapper);
日志打印出来的sql:
UPDATE user SET name='wdawdwa', age=888 WHERE (id = 5)
得出结论:
- Mybatis-Plus会根据字段是否为null来判断条件是否生效,假如实体类当中使用的是基本类型,new出来的对象会赋初始值的,比如int默认就是0,这样就会导致我们并不想对他进行修改,但是最后却修改了。
(5)本质上假如我们不使用UpdateWrapper的set相关方法的话,其实也可以直接使用QueryWrapper的,如下:
QueryWrapper<User> objectQueryWrapper = new QueryWrapper<>();
updateWrapper.eq("id", 5);
User user = new User();
user.setName("wdawdwa");
user.setAge(888);
user.setEmail("dwadwad@qq.com");
boolean update = userService.update(user, objectQueryWrapper);
日志打印出来的sql同时用UpdateWrapper是一样的:
UPDATE user SET name='wdawdwa', age=0 WHERE (id = 5)
UpdateWrapper和QueryWrapper都继承了AbstractWrapper,AbstractWrapper主要用于生成 sql 的 where 条件
,AbstractWrapper又继承了Wrapper。他两个唯一的区别是:
- UpdateWrapper实现了Update接口,这个接口提供了一些set方法
- QueryWrapper实现了Query接口,这个接口提供了一些select方法
(6)假如我们不使用Entity也不使用UpdateWrapper的set,那sql打印出来是什么呢?
UpdateWrapper<User> updateWrapper = Wrappers.update();
// 修改条件为id=5的数据
updateWrapper.eq("id", 5);
// 假如修改失败返回值为false
boolean update = userService.update(null, updateWrapper);
运行结果:
得出结论:
- 直接就语法异常了:语法异常userService.update并不会返回false,而是线程直接就终止了!
3、LambdaUpdateWrapper【用法示例】
UpdateWrapper和LambdaUpdateWrapper其实是一样的,都能够实现彼此的功能,只是语法不同,LambdaUpdateWrapper所有的指定column参数不再是字符串,而是SFunction函数。
(1)使用场景:
LambdaUpdateWrapper<User> objectLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
// 修改条件为id=5的数据
objectLambdaUpdateWrapper.eq(User::getId, 5);
objectLambdaUpdateWrapper.set(User::getAge, 22);
objectLambdaUpdateWrapper.set(User::getName, "zhangsan");
objectLambdaUpdateWrapper.setSql("email='cece@qq.com'");User user = new User();
user.setAge(666);
boolean update = userService.update(user, objectLambdaUpdateWrapper);
日志打印出来的sql:
UPDATE user SET age=666, age=22,name='zhangsan',email='cece@qq.com' WHERE (id = 5)
(2)原理讲解
SFunction其实就是继承了Function函数。而Function是一个函数式(Functional)接口
Function三种使用方法:
public static void main(String[] args) {// 匿名内部类Function function = new Function<User, Object>() {@Overridepublic Object apply(User user) {return user.getAge();}};// lambdaFunction<User, Object> function1 = (a) -> a.getAge();// 方法引用Function<User, Object> function2 = User::getAge;
}
核心源码: 感兴趣的可以断点观察一下源码
(3)假如我们的get方法和表中的字段不对应,是否会出问题?
LambdaUpdateWrapper<User> objectLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
// 修改条件为id=5的数据
objectLambdaUpdateWrapper.eq(User::getId, 5);
objectLambdaUpdateWrapper.set(User::getSexaa, "男");
boolean update = userService.update(objectLambdaUpdateWrapper);
日志打印出来的sql:
UPDATE user SET sex='男' WHERE (id = 5)
得出结论:
- 实体字段名和数据库当中的列名称不一致,并不会影响赋值使用,他实际上是通过反射拿到的是@TableField当中指定的值!而并非只是简单的通过get方法名字来获取的。
4、UpdateChainWrapper【 用法示例】
(1)使用场景一:
// UpdateChainWrapper有三种创建方式
// UpdateChainWrapper<User> userUpdateChainWrapper = new UpdateChainWrapper<>(User.class);
// UpdateChainWrapper<User> update = new UpdateChainWrapper<>(userMapper);
User user = new User();
user.setAge(222);
UpdateChainWrapper<User> updateChainWrapper = userService.update();
updateChainWrapper.eq("id", 5).set("name", "张三").setSql("email='cece@qq.com'").setEntity(user).update();
日志打印出来的sql:
UPDATE user SET name='张三',email='cece@qq.com' WHERE age=222 AND (id = 5)
(2)使用场景二:
User user = new User();
user.setAge(222);
UpdateChainWrapper<User> updateChainWrapper = userService.update();
updateChainWrapper.eq("id", 5).update(user);
日志打印出来的sql:
UPDATE user SET age=222 WHERE (id = 5)
5、LambdaUpdateChainWrapper【 用法示例】
LambdaUpdateChainWrapper同UpdateChainWrapper一模一样,只不过参数是函数式表达式,这里就不再过多叙述了。
// LambdaUpdateChainWrapper有三种创建方式// LambdaUpdateChainWrapper<User> userUpdateChainWrapper = new LambdaUpdateChainWrapper<>(User.class);// LambdaUpdateChainWrapper<User> update = new LambdaUpdateChainWrapper<>(userMapper);User user = new User();user.setAge(222);LambdaUpdateChainWrapper<User> userLambdaUpdateChainWrapper = userService.lambdaUpdate();userLambdaUpdateChainWrapper.eq(User::getId,5).update(user);
日志打印出来的sql:
UPDATE user SET age=222 WHERE (id = 5)
6、updateById 和 updateBatchById
(1)updateById 使用场景:
在调用updateById方法前,需要在T entity(对应的实体类)中的主键属性上加上@TableId注解。
User user = new User();
user.setId(new Long(5));
user.setAge(555);
user.setEmail(null);
userService.updateById(user);
日志打印出来的sql:
UPDATE user SET age=555 WHERE id=5
(2)updateBatchById 使用场景:
User user = new User();
user.setId(new Long(5));
user.setAge(555);
user.setEmail(null);User user1 = new User();
user1.setId(new Long(4));
user1.setAge(666);
user1.setEmail(null);List<User> objects = new ArrayList<>();
objects.add(user);
objects.add(user1);
boolean b = userService.updateBatchById(objects);
日志打印出来的sql:
UPDATE user SET age=555 WHERE id=5
UPDATE user SET age=666 WHERE id=4
7、Mybatis-plus设置某个字段值为null的方法总结
Mybatis-Plus给我们提供的update根本没有全量修改的,都是只对不为空的进行修改,例如updateById和update使用Entity赋值的方法都是只对不为null的进行赋值修改。假如遇到需要将某个值赋为null这时候该怎么办?
方式一:在mapper.xml中写对应的sql语句
方式二:实体类对应字段添加注解
@TableField注解介绍:
- @TableField(insertStrategy = FieldStrategy.IGNORED) 添加该注解值的字段在Mybatis-plus生成insert sql时会忽略该字段值的判断
- @TableField(updateStrategy = FieldStrategy.IGNORED) 添加该注解值的字段在Mybatis-plus生成update sql时会忽略该字段值的判断
- @TableField(whereStrategy = FieldStrategy.IGNORED) 添加该注解值的字段在Mybatis-plus生成sql时的where条件中会忽略该字段值的判断
可以聚合三种进行同时使用:
@TableField(insertStrategy = FieldStrategy.IGNORED,updateStrategy = FieldStrategy.IGNORED,whereStrategy = FieldStrategy.IGNORED)
说明 FieldStrategy 的可选值:
- FieldStrategy.NOT_NULL:不为null则更新,也就是字段值为null则不生成到sql中不更新该字段,如果字段值为""(空字符串)也是会更新的
- FieldStrategy.NOT_EMPTY:不为空则更新,也就是该字段值为null或为""(空字符串)都不会更新
- FieldStrategy.DEFAULT:默认值,和全局配置保持一致
- FieldStrategy.IGNORED:忽略判断,该字段值不论是什么,都进行更新
- FieldStrategy.NEVER:不做更新操作,该字段值不论是什么,都不进行更新
在email字段中设置注解,加上该注解之后,Mybatis-plus会在对应的情况下生成sql时忽略掉该字段值的判断;即该字段值不论是什么都会生成在sql中,就可以设置字段值为null了;
@TableField(value = "email", updateStrategy = FieldStrategy.IGNORED)
测试添加注解后的效果:
User user = new User();
user.setId(new Long(5));
user.setAge(555);
user.setEmail(null);
userService.updateById(user);
日志打印出来的sql:
UPDATE user SET age=555, email=null WHERE id=5
方式三:通过条件构造器的set进行赋值
UpdateWrapper<User> updateWrapper = Wrappers.update();
updateWrapper.set("name", null);
updateWrapper.eq("id", 5);
boolean update = userService.update(updateWrapper);
方式四:Mybatis-plus 全局参数配置(yaml方式配置如下)
全局配置的值可选项和第二种方式 FieldStrategy 的可选项一致,全局配置默认值为 not_null
mybatis-plus:global-config:db-config:insert-strategy: ignoredupdate-strategy: ignoredselect-strategy: ignored
这种方式和第二种一样可能会使用不当导致字段值为null,数据丢失;并且该方式是全局配置,对所有表的实体类所有字段都生效,危害会更严重;如果同时配置了第二种,那么优先第二种生效。
三、saveOrUpdate
saveOrUpdate方法主要有以下:
// TableId 注解存在更新记录,否插入一条记录
boolean saveOrUpdate(T entity);
// 根据updateWrapper尝试更新,否继续执行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
参数说明:
下面进行一个一个讲解
1、saveOrUpdate 【用法示例】
方法一:
boolean saveOrUpdate(T entity);
这个方法我就不演示了哈,通过源码已经可以看的一清二楚了,如下:
方法二:
default boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper) {return this.update(entity, updateWrapper) || this.saveOrUpdate(entity);
}
User user = new User();
user.setId(new Long(5));
user.setAge(555);
user.setEmail(null);UpdateWrapper<User> updateWrapper = Wrappers.update();
updateWrapper.set("name", "123");
boolean b = userService.saveOrUpdate(user, updateWrapper);
日志打印出来的sql:
我把user.setId(new Long(5));这一行去掉之后也是打印出来的下面的sql
UPDATE user SET age=555, name='123'
通过上面示例好像说明不了其作用,我们再来看一个示例:
User user = new User();
user.setAge(555);
user.setEmail(null);UpdateWrapper<User> updateWrapper = Wrappers.update();
// 修改表中name字段为指定的数据
updateWrapper.set("name", "123");
// 假如不存在id为5的数据,这时候会进行新增
updateWrapper.eq("id",5);
boolean b = userService.saveOrUpdate(user, updateWrapper);
日志打印出来的sql:
UPDATE user SET age=555, name='123' WHERE (id = 5)
假如不存在id为5的数据,这时候打印出来的sql:
UPDATE user SET age=555, name='123' WHERE (id = 6)
INSERT INTO user ( id, age ) VALUES ( 1668194662817099777, 555 )
得出结论:
- 像我们平常使用的updateByid不就是根据id来判断是新增还是修改。而这个方法说白了他就是要以updateWrapper当中所组成的where条件来判断是新增还是修改。
2、saveOrUpdateBatch【用法示例】
方法三:
default boolean saveOrUpdateBatch(Collection<T> entityList) {return this.saveOrUpdateBatch(entityList, 1000);
}
测试代码:数据库当中只有id为5的数据,没有id为6的数据
User user = new User();
user.setId(new Long(5));
user.setAge(555);
user.setEmail(null);User user1 = new User();
user1.setId(new Long(6));
user1.setAge(666);
user1.setEmail(null);List<User> objects = new ArrayList<>();
objects.add(user);
objects.add(user1);boolean b = userService.saveOrUpdateBatch(objects);System.out.println("11111111111111111111");
System.out.println(b);
日志打印出来的sql:
SELECT id,name,age,email FROM user WHERE id=5
UPDATE user SET age=555 WHERE id=5
SELECT id,name,age,email FROM user WHERE id=6
INSERT INTO user ( id, age ) VALUES ( 6, 666 )
得出结论:
- 假如是批量的,能查到就修改,查不到就新增,每条数据都是相互隔离的,谁也不影响谁
方法四:
其实方法三就是掉用的方法四,设置了batchSize 为1000。 batchSize代表的是插入批次数量。
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
3、批量插入优化
如果大数据量(例如五千、一万)插入建议修改MySQL的JDBC连接的url为如下,开启rewriteBatchedStatements,可以优化插入速度。
url: jdbc:mysql://127.0.0.1:3306/text1?characterEncoding=UTF-8&useSSL=false&rewriteBatchedStatements=true
四、防全表更新与删除插件
在使用Mybatis-Plus的时候如果对API不是特别了解很容易导致重大事故,就拿下面的代码来说:
User user = new User();
user.setId(new Long(5));
user.setAge(555);
user.setEmail(null);UpdateWrapper<User> updateWrapper = Wrappers.update();
updateWrapper.set("name", "123");
boolean b = userService.saveOrUpdate(user, updateWrapper);
日志打印出来的sql:
UPDATE user SET age=555, name='123'
本来想着只修改id为5的数据,却不料最终执行的sql连where条件都没有,导致把整张表全给修改了。针对于这个问题我们可以添加如下配置进行防范:
这是官网给我们提供的:https://baomidou.com/pages/c571bc/#blockattackinnerinterceptor
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());return interceptor;}
}
然后这时候再执行sql会发现直接就异常了,原因是没有where条件!
相关文章:
Mybatis-Plus中update更新操作用法
目录 一、前言二、update1、关于修改的4个条件构造器2、UpdateWrapper【用法示例】3、LambdaUpdateWrapper【用法示例】4、UpdateChainWrapper【 用法示例】5、LambdaUpdateChainWrapper【 用法示例】6、updateById 和 updateBatchById7、Mybatis-plus设置某个字段值为null的方…...
16道JVM面试题
1.jvm内存布局 1.程序计数器:当前线程正在执行的字节码的行号指示器,线程私有,唯一一个没有规定任何内存溢出错误的情况的区域。 2.Java虚拟机栈:线程私有,描述Java方法执行的内存模型,每个方法运行时都会…...
HttpRunner 接口自动化测试框架实战,打造高效测试流程
简介 2018年python开发者大会上,了解到HttpRuuner开源自动化测试框架,采用YAML/JSON格式管理用例,能录制和转换生成用例功能,充分做到用例与测试代码分离,相比excel维护测试场景数据更加简洁。在此,利用业…...
手写一个webpack插件(plugin)
熟悉 vue 和 react 的小伙伴们都知道,在执行过程中会有各种生命周期钩子,其实webpack也不例外,在使用webpack的时候,我们有时候需要在 webpack 构建流程中引入自定义的行为,这个时候就可以在 hooks 钩子中添加自己的方…...
jvm常见面试题
0x01. 内存模型以及分区,需要详细到每个区放什么。 栈区: 栈分为java虚拟机栈和本地方法栈 重点是Java虚拟机栈,它是线程私有的,生命周期与线程相同。 每个方法执行都会创建一个栈帧,用于存放局部变量表࿰…...
TF-A 项目的长期支持介绍
引流关键词:Armv8-A, Armv9-A, Cortex-A, Cortex-A12, Cortex-A15, Cortex-A17, Cortex-A32, Cortex-A34, Cortex-A35, Cortex-A5, Cortex-A510, Cortex-A53, Cortex-A55, Cortex-A57, Cortex-A65, Cortex-A65AE, Cortex-A7, Cortex-A710, Cortex-A715, Cortex-A72, Cortex-A7…...
企业电子招标采购系统源码java 版本 Spring Cloud + Spring Boot
项目说明 随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及…...
7.Mysql 事务底层
一、事务的基础知识 mysql中的事务 分为 显式事务 和 隐式事务。 1.1 显式事务 显式事务就是我们手动开启事务,并且提交事务比如: -- 开启事务 begin; -- 执行查询语句 select *from where id = 1 for update ; -- 提交事务 commit;1.2 隐式事务 在 MySQL 中,隐式事务是…...
15.DIY可视化-拖拽设计1天搞定主流小程序-分类联动文章列表实时刷新
分类联动文章列表实时刷新 本教程均在第一节中项目启动下操作 分类联动文章列表实时刷新前言需求一:功能实现:点击首页分类,对应分类内容显示到当前页一、清空原分类界面:二. 设置选项卡三:设定展示内容字段:1.跨页面复制:文章分类组件到分类![在这里插入图片描述](https://img…...
【SpringCloud】二、服务注册发现Eureka与负载均衡Ribbon
文章目录 一、Eureka1、服务提供者与消费者2、Eureka原理分析3、搭建Eureka4、服务注册5、模拟多服务实例启动6、服务的发现 二、Ribbon1、负载均衡的原理2、源码分析3、负载均衡策略4、饥饿加载 一、Eureka 1、服务提供者与消费者 服务提供者:一次业务中…...
图形学实验(完整文件见上传)
CRect rect; this->GetClientRect(rect); pDC->Ellipse(rect); // DDALineView.cpp : implementation of the CDDALineView class // #include “stdafx.h” #include “DDALine.h” #include “DDALineDoc.h” #include “DDALineView.h” #ifdef _DEBUG #define new…...
Spark大数据处理学习笔记(3.2.1)掌握RDD算子
该文章主要为完成实训任务,详细实现过程及结果见【http://t.csdn.cn/FArNP】 文章目录 一、准备工作1.1 准备文件1. 准备本地系统文件2. 把文件上传到 1.2 启动Spark Shell1. 启动HDFS服务2. 启动Spark服务3. 启动Spark Shell 二、掌握转换算子2.1 映射算子 - map()…...
lammps初级:石墨烯、金属材料、纳米流体、热传导、多成分体系、金属、半导体材料的辐照、自建分子力场、MOFS、H2/CO2混合气体等模拟
1 LAMMPS的基础入门——初识LAMMPS是什么?能干什么?怎么用? 1.1 LAMMPS在win10和ubuntu系统的安装及使用 1.2 in文件结构格式 1.3 in文件基本语法:结合实例,讲解in文件常用命令 1.4 data文件格式 1.5 LAMMPS常见错误解…...
【MarkerDown】CSDN Markdown之时序图sequenceDiagram详解
CSDN Markdown之时序图sequenceDiagram详解 序列图 sequenceDiagram参与者与组参与者 participant拟人符号 actor别名 as组 box 消息(连线)激活/失活 activate/deactivate备注 Note循环 loop备选 Alt并行 par临界区 critical中断 break背景高亮 rect注释 %%转义字符的实体代码序…...
ReentrantLock实现原理-公平锁
在ReentrantLock实现原理(1)一节中,我们了解了ReentrantLock非公平锁的获取流程,在本节中我们来看下ReentrantLock公平锁的创建以及锁管理流程 创建ReentrantLock公平锁 创建公平锁代码如下: ReentrantLock reentrantLock new ReentrantL…...
掌握Scala数据结构(2)MAP、TUPLE、SET
一、映射 (Map) (一)不可变映射 1、创建不可变映射 创建不可变映射mp,用键->值的形式 创建不可变映射mp,用(键, 值)的形式 注意:Map是特质(Scala里的trait,相当于Java里的interface&#…...
flutter:文件系统目录、文件读写
参考 参考:老孟 文件存储和网络请求 数据存储 Dart的 IO 库包含了文件读写的相关类,它属于 Dart 语法标准的一部分,所以通过 Dart IO 库,无论是 Dart VM 下的脚本还是 Flutter,都是通过 Dart IO 库来操作文件的。但…...
计算机提示“找不到vcruntime140.dll,无法继续执行代码可”以这样子修复
首先,对于那些不熟悉的人来说,vcruntime140.dll是一个关键文件,用于在Windows操作系统上运行使用C语言编写的大型应用程序。如果你正在运行或安装这样的应用程序,但找不到vcruntime140.dll文件,那么你的应用程序可能无…...
深度学习pytorch实战五:基于ResNet34迁移学习的方法图像分类篇自建花数据集图像分类(5类)超详细代码
1.数据集简介 2.模型相关知识 3.split_data.py——训练集与测试集划分 4.model.py——定义ResNet34网络模型 5.train.py——加载数据集并训练,训练集计算损失值loss,测试集计算accuracy,保存训练好的网络参数 6.predict.py——利用训练好的网…...
Rust in Action笔记 第五章 深入理解数据
如果希望看到f32类型的数转换成整型数字u32类型,需要在unsafe包裹下调用std::mem::transmute(data),因为在安全的Rust语法中没有把整型数据按照bit转换成浮点数据的实现,如果想要看到浮点数的二进制输出(通过{:b})&…...
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码
Cocos creator实现飞机大战空中大战《战击长空》小游戏资源及代码 最近在学习Cocos Creator,作为新手,刚刚开始学习Cocos Creator,刚刚入门,这里记录一下飞机大战小游戏实现。 https://wxaurl.cn/VEgRy2eTMyi 一 安装CocosDashBo…...
2.4 逻辑代数的基本定理
学习目标: 如果我要学习逻辑代数的基本定理,我会采取以下步骤: 1. 学习基本概念:首先,我会花时间了解逻辑代数的基本概念,如逻辑运算符(合取、析取、否定等)、真值表、逻辑等价性等…...
适用于 Linux 的 Windows 子系统wsl文档
参考链接:https://learn.microsoft.com/zh-cn/windows/wsl/ 鸟哥的Linux私房菜:http://cn.linux.vbird.org/ http://cn.linux.vbird.org/linux_basic/linux_basic.php http://cn.linux.vbird.org/linux_server/ 目录 安装列出可用的 Linux 发行版列出已…...
C++特殊类的设计与类型转换
特殊类的设计与类型转换 特殊类的设计请设计一个类,只能在堆上创建对象请设计一个类,只能在栈上创建对象请设计一个类,只能创建一个对象(单例模式) C的类型转换 特殊类的设计 请设计一个类,只能在堆上创建对象 通过new创建的类就…...
如何通过关键词搜索API接口
如果你是一位电商运营者或者是想要进行1688平台产品调研的人员,你可能需要借助API接口来获取你所需要的信息。在这篇文章中,我们将会讨论如何通过关键词搜索API接口获取1688的商品详情。 第一步:获取API接口的授权信息 在使用API接口前&…...
智驾域控新战争打响,谁在抢跑?
智能驾驶域控制器赛道,已经成为了时下最为火热的市场焦点之一。 最近,头部Tier1均胜电子公布了全球首批基于高通Snapdragon Ride第二代芯片平台的智能驾驶域控制器产品nDriveH,在这一赛道中显得格外引人注意。 就在不久之前,均胜…...
Android 13无源码应用去掉无资源ID的按钮
Android Wifionly项目,客户要求去掉谷歌联系人里的 手机联系人按钮 需求分析 无应用源码,只能通过系统侧去修改 首先通过 Android Studio 工具 uiautomatorviewer 获取父控件资源ID chip_group ,然后通过遍历获取子控件去掉目标按钮 --- a/frameworks/base/core/java/andr…...
【SCI征稿】中科院2区(TOP),正刊,SCIEEI双检,进化计算、模糊集和人工神经网络在数据不平衡中应用
【期刊简介】IF:8.0-9.0,JCR1区,中科院2区(TOP) 【检索情况】SCIE&EI 双检,正刊 【数据库收录年份】2004年 【国人占比】22.78%(期刊国际化程度高) 【征稿领域】进化计算、模…...
Android Audio开发——AAudio基础(十五)
AAudio 是一个自 Android O 引入的新的 Android C API。它主要是为需要低延迟的高性能音频应用设计的。应用程序通过直接从流中读取或向流中写入数据来与 AAudio 通信,但它只包含基本的音频输入输出能力。 一、AAudio概述 AAudio 在应用程序和 Android 设备上的音频输入输出之…...
SDK接口远程调试【内网穿透】
文章目录 1.测试环境2.本地配置3. 内网穿透3.1 下载安装cpolar内网穿透3.2 创建隧道 4. 测试公网访问5. 配置固定二级子域名5.1 保留一个二级子域名5.2 配置二级子域名 6. 使用固定二级子域名进行访问 转发自cpolar内网穿透的文章:Java支付宝沙箱环境支付࿰…...
建设银行扬中网站/上海网站建设哪家好
String是Java.lang包下的final类,其值是不可以改变的。String类实现了java.io.Serializable,Comparable<String>,CharSequence 这三个接口。 java.io.Serializable 接口是 序列化接口,实现此接口的类,可以序列化和反序列化此类对象。 C…...
查看网站用什么语言做的/科学新概念seo外链平台
Javascript for循环例题(26道) for循环案例 JavaScript for循环 26题目录 转载注明出处Javascript for循环例题(26道) for循环案例1、输出1-1002、求1-100所有数的平均值3、求1-100所有奇数和偶数的和4、求1-100所有能被3整除的数字的和5、用户输入打印相对应行列的星星6、假如…...
goz建站/软文网
下面我们讲解登录功能。首先为了方便我们开发,我们在根目录(www目录)下建立一个项目文件夹,叫joke。接着在joke下建立两个文件夹,一个叫admin后台文件夹,另一个叫home前台文件夹(当然,你也可以使用别的名称,…...
哪个平台免费招人最快/搜索引擎优化的方式
参考链接: 11周精通python计划(完结) 总结: # 演示类的使用 # 1.类属性, 类对象的属性, 由所有实例对象所共享,通过(类名.属性)或者(实例名.属性)来访问 # 2.实例属性, 实例对象的属性, 由各实例对象所独享,通过(实例名.属性)来访问代码实验展示: # 演…...
药店网站建设相关费用/北京疫情消息1小时前
fork() 是Unix系统创建子进程的唯一方法,其他包或模块的底层都调fork。fork作用是复制克隆一个新进程(子进程),继续同时向下执行。 特点:fork被调用一次,返回两次,一次在父进程中返回子进程PID…...
手机网站app/宁波营销型网站建设优化建站
首先,判断是否存在水平渐近线 当x→∞时,y→A(A∈R),说明存在水平渐近线当x\to\infty时,y\to A(A\in R),说明存在水平渐近线当x→∞时,y→A(A∈R),说明存在水平渐近线 若不存在水平渐近线,再判断是否存在铅直渐近线 当x→A(A∈R)时,y→∞,说明存在铅直渐近线当x\to…...