Immutable.js API 简介
- Immutable-js
- 这个库的实现是深拷贝还是浅拷贝?
- immutable 来源
- immutable.js三大特性:
- 持久化数据结构
- 结构共享
- 惰性操作
- Immutable.js 的几种数据类型
- immutable 使用
- 使用 npm 安装 immutable:
- 常用API介绍
- Map
- List
- List.isList() 和 Map.isMap()
- set() / setIn()
- get() / getIn()
- size
- includes()
- first() 、 last()
- is()
- merge , concat
- concat()
- updateIn() 回调函数更新 – 用法参考setIn()
- toJS()
- fromJS()
- 总结:增删改查(所有操作都会返回新的值,不会修改原来值)
- Immutable-js 优缺点
- 优点:
- 降低mutable带来的复杂度
- 节省内存
- 历史追溯性(时间旅行)
- 缺点:
- 需要重新学习api
- 资源包大小增加(源码5000行左右)
- 容易与原生对象混淆:由于api与原生不同,混用的话容易出错。
- 优点:
Immutable-js
Immutable.js,
github地址:https://github.com/immutable-js/immutable-js
每次修改一个 Immutable 对象时都会创建一个新的不可变的对象
,在新对象上操作并不会影响到原对象的数据
这个库的实现是深拷贝还是浅拷贝?
Immutable ([ɪˈmjuːtəbl] 不变的;不可变的;不能变的) 是 Facebook 开发的不可变数据集合
。
不可变数据一旦创建就不能被修改,使得应用开发更简单,允许使用函数式编程技术,比如惰性评估。
Immutable JS 提供一个惰性 Sequence,允许高效的队列方法链,类似 map 和 filter ,不用创建中间代表。
immutable 通过惰性队列
和哈希映射
提供 Sequence, Range, Repeat, Map, OrderedMap, Set 和一个稀疏 Vector。
immutable 来源
Immutable.js出自Facebook,是最流行的不可变数据结构的实现之一。
它实现了**完全的
持久化
数据结构
**,通过使用像tries这样的先进技术来实现结构共享。
所有的更新操作都会返回新的值
,但是在内部结构是共享
的,来减少内存占用(和垃圾回收的失效)。
immutable.js三大特性:
- Persistent data structure (持久化数据结构)
- structural sharing (结构共享)
- support lazy operation (惰性操作)
持久化数据结构
这里说的持久化是用来描述一种数据结构
,
指一个数据,在被修改时,仍然能够保持修改前的状态,即不可变类型。
immutable.js提供了十余种
不可变的类型(List,Map,Set,Seq,Collection,Range等)
结构共享
Immutable使用先进的tries(字典树)技术
实现结构共享来解决性能问题.
当我们对一个Immutable对象进行操作的时候
ImmutableJS会只clone该节点以及它的祖先节点
,其他保持不变,这样可以共享相同的部分,大大提高性能。
惰性操作
const oddSquares = Immutable.seq.of(1, 2, 3, 4, 5, 6, 7, 8).filter(item => {console.log('immutable对象的filter执行');return item % 2;}).map(x => x * x);console.log(oddSquares.get(1)); // 9const jsSquares = [1, 2, 3, 4, 5, 6, 7, 8].filter(item => {console.log('原生数组的filter执行');return item % 2;}).map(x => x * x);console.log(jsSquares[1]); // 9
用seq创建的对象,其实代码块没有被执行,只是被声明了,
代码在get(1)的时候才会实际被执行,取到index=1的数之后,后面的就不会再执行了,
所以在filter时,第三次就取到了要的数,从4-8都不会再执行。
如果在实际业务中,数据量非常大,一个array的长度是几百,要操作这样一个array,如果应用惰性操作的特性,会节省非常多的性能。
Immutable.js 的几种数据类型
List: 有序索引集
,类似JavaScript中的Array。Map: 无序索引集
,类似JavaScript中的Object。OrderedMap: 有序的Map
,根据数据的set()进行排序。Set: 没有重复值的集合
。OrderedSet: 有序的Set
,根据数据的add进行排序。Stack: 有序集合
,支持使用unshift()和shift()添加和删除。Record: 一个用于生成Record实例的类
。类似于JavaScript的Object,但是只接收特定字符串为key,具有默认值。Seq: 序列
,但是可能不能由具体的数据结构支持。Collection: 是构建所有数据结构的基类
,不可以直接构建。
用的最多就是List
和Map
这两种数据类型。
immutable 使用
使用 npm 安装 immutable:
npm install immutable
```js 每个模块都要包括:```js
var Immutable = require('immutable');
var map = Immutable.Map({a:1, b:2, c:3});
常用API介绍
Map
Map(): 原生object转Map对象 (只会转换第一层,注意和fromJS区别)
作用:用来创建一个新的Map对象
代码实现:
var obj = { name: 'demo', age: 100 }
var oldImmutableObj = Map(obj)
console.log(oldImmutableObj)//Map
Immutable.Map(); // 空Map
Immutable.Map({ a: '1', b: '2' });
List
List(): 原生array转List对象 (只会转换第一层,注意和fromJS区别)
作用:用来创建一个新的List对象
代码实现:
const { List } = require('immutable');
const list1 = List([ 1, 2 ]);
const list2 = list1.push(3, 4, 5);
const list3 = list2.unshift(0);
const list4 = list1.concat(list2, list3); assert.equal(list1.size, 2);
assert.equal(list2.size, 5);
assert.equal(list3.size, 6);
assert.equal(list4.size, 13);
assert.equal(list4.get(0), 1);
push
, set
, unshift
or splice
都可以直接用,返回一个新的immutable对象
List.isList() 和 Map.isMap()
作用:判断一个数据结构是不是List/Map类型
用法:
List.isList([]); // false
List.isList(List()); // trueMap.isMap({}) // false
Map.isMap(Map()) // true
set() / setIn()
set()修改immutalble的值:设置第一层key、index的值
用法:
var NewImmutableObj = oldImmutableObj.set('name' , 'demo2')const originalList = List([ 0 ]);
// List [ 0 ]
originalList.set(1, 1);
// List [ 0, 1 ]
originalList.set(0, 'overwritten');
// List [ "overwritten" ]
originalList.set(2, 2);
// List [ 0, undefined, 2 ]const originalMap = Map()
const newerMap = originalMap.set('key', 'value')
const newestMap = newerMap.set('key', 'newer value')
List在使用的时候,将index为number值设置为value。
Map在使用的时候,将key的值设置为value。
在List中使用时,若传入的number为负数,则将index为size+index的值设置为value,
例,若传入-1,则将size-1的值设为value。
若传入的number的值超过了List的长度,则将List自动补全为传入的number的值,将number设置为value,其余用undefined补全。
注:跟js中不同,List中不存在空位,[,],List中若没有值,则为undefined。
setIn()修改immutalble的值:设置深层结构中某属性的值
用法:
const originalMap = Map({subObject: Map({subKey: 'subvalue',subSubObject: Map({subSubKey: 'subSubValue'})})
})const newMap = originalMap.setIn(['subObject', 'subKey'], 'ha ha!')
// Map {
// "subObject": Map {
// "subKey": "ha ha!",
// "subSubObject": Map { "subSubKey": "subSubValue" }
// }
// }
const newerMap = originalMap.setIn(['subObject', 'subSubObject', 'subSubKey'],'ha ha ha!'
)// Map {
// "subObject": Map {
// "subKey": "subvalue",
// "subSubObject": Map { "subSubKey": "ha ha ha!" }
// }
// }
用法与set()一样,只是第一个参数是一个数组,代表要设置的属性所在的位置
get() / getIn()
get()获取immutalble 获取一级属性
的值
//获取List索引的元素
ImmutableData.get(0);// 获取Map对应key的value
ImmutableData.get('a');oldImmuObj.get("name")
newImmuObj.get("name")
案例
import React, { Component } from 'react'
import { Map } from 'immutable' export default class App extends Component {state = {info: Map({name: 'demo',age: 100})}render() {return (<div> this.state.info.get('name') -- {this.state.info.get('name')} <br/>this.state.info.get('age') -- {this.state.info.get('age')} <br/><button onClick={()=>{this.setState({info: this.state.info.set('name','32333').set('age', 1000)})}}>修改</button></div>)}
}
getIn()获取immutalble 获取多级属性
的值
// 获取嵌套数组中的数据
ImmutableData.getIn([1, 2]);// 获取嵌套map的数据
ImmutableData.getIn(['a', 'b']); const { Map } = require('immutable');
const map1 = Map({ a: 1, b: 2, c: 3 });
const map2 = map1.set('b', 50);
map1.get('b') + " vs. " + map2.get('b'); // 2 vs. 50
多重对象情况
import React, { Component } from 'react'
import { Map } from 'immutable'export default class App extends Component { state = {info: Map({name: 'demo',select: 'aa',fliter: Map({text: '',up: true,down: false})})}componentDidMount() {// console.log(this.state.info)}render() {return (<div><button onClick={() => {this.setState({info: this.state.info.set('name', 'dsdsdd')})}}>change</button> <br />this.state.info.get('name') -- {this.state.info.get('name')} <br /><Child fliter={this.state.info.get('filter')}></Child</div>)}
}class Child extends Component {shouldComponentUpdate(nextProps, nextState) {if (this.props.filter === nextProps.filter) { // 注意此处:判断是否变化return false}return true}render() {return (<div>Child -- {this.props.fliter}</div>)}componentDidUpdate() {console.log('componentDidUpdate')}
}
size
作用:属性,获取List/Map的长度,等同于ImmutableData.count();
用法:
// 查看List或者map大小
immutableData.size 或者immutableData.count()
```js ### has() 、 hasIn()**作用**:判断是否存在某一个key**用法**: ```js
Immutable.fromJS([1,2,3,{a:4,b:5}]).has('0'); //true
Immutable.fromJS([1,2,3,{a:4,b:5}]).has('0'); //true
Immutable.fromJS([1,2,3,{a:4,b:5}]).hasIn([3,'b']) //true
includes()
作用:判断是否存在某一个value
用法:
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes(2); //true
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes('2'); //false 不包含字符2
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes(5); //false
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes({a:4,b:5}) //false
Immutable.fromJS([1,2,3,{a:4,b:5}]).includes(Immutable.fromJS({a:4,b:5})) //true
first() 、 last()
作用:用来获取第一个元素或者最后一个元素,若没有则返回undefined
代码:
Immutable.fromJS([1,2,3,{a:4,b:5}]).first()//1
Immutable.fromJS([1,2,3,{a:4,b:5}]).last()//{a:4,b:5}Immutable.fromJS({a:1,b:2,c:{d:3,e:4}}).first() //1
Immutable.fromJS({a:1,b:2,c:{d:3,e:4}}).first() //{d:3,e:4}
is()
作用:对两个对象进行比较
用法:is(map1,map2)
简介:
和js中对象的比较不同,在js中比较两个对象比较的是地址,
但是在Immutable中比较的是这个对象hashCode和valueOf,只要两个对象的hashCode相等,值就是相同的,避免了深度遍历,提高了性能
代码实现:
import { Map, is } from 'immutable'
const map1 = Map({ a: 1, b: 1, c: 1 })
const map2 = Map({ a: 1, b: 1, c: 1 })
map1 === map2 //false
Object.is(map1, map2) // false
is(map1, map2) // true// is(): 判断两个immutable对象是否相等
const objA = { name: 'graceji', age: 18 };
const objB = { name: 'graceji', age: 18 };
const imA = immutable.Map({ name: 'graceji', age: 18 });
const imB =immutable.Map({ name: 'graceji', age: 18 });
objsA === objB // false; 比较的是地址
immutable.is(imA, imB); // true; hashcode相同
merge , concat
merge
作用:浅合并,新数据与旧数据对比,旧数据中不存在的属性直接添加,就数据中已存在的属性用新数据中的覆盖
mergrWith
作用:自定义浅合并,可自行设置某些属性的值
mergeIn
作用:对深层数据进行浅合并
mergeDeep
作用:深合并,新旧数据中同时存在的的属性为新旧数据合并之后的数据
mergeDeepIn
作用:对深层数据进行深合并
mergrDeepWith
作用:自定义深合并,可自行设置某些属性的值 ’
代码实现:
const { Map, List } = require('immutable');
const map1 = Map({ a: 1, b: 2, c: 3, d: 4 });
const map2 = Map({ c: 10, a: 20, t: 30 });
const obj = { d: 100, o: 200, g: 300 };const map3 = map1.merge(map2, obj);
// Map { a: 20, b: 2, c: 10, d: 100, t: 30, o: 200, g: 300 }
这里用一段示例彻底搞懂merge,此示例为Map结构,List与Map原理相同
const Map1 = Immutable.fromJS({a:111,b:222,c:{d:333,e:444}});
const Map2 = Immutable.fromJS({a:111,b:222,c:{e:444,f:555}});
const Map3 = Map1.merge(Map2);
//Map {a:111,b:222,c:{e:444,f:555}}const Map4 = Map1.mergeDeep(Map2);
//Map {a:111,b:222,c:{d:333,e:444,f:555}}const Map5 = Map1.mergeWith((oldData,newData,key)=>{ if(key === 'a'){ return 666; }else{ return newData }
},Map2);
//Map {a:666,b:222,c:{e:444,f:555}}
concat()
作用:对象的拼接,用法与js数组中的concat()相同,返回一个新的对象。
用法:const List = list1.concat(list2)
代码实现:
const list1 = List([ 1, 2, 3 ]);
const list2 = List([ 4, 5, 6 ]);
const array = [ 7, 8, 9 ];
const list3 = list1.concat(list2, array);
// List [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
updateIn() 回调函数更新 – 用法参考setIn()
//updateIn 回调函数更新
const nested3 = nested2.updateIn([ 'a', 'b', 'd' ], value => value + 1);
console.log(nested3);
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ], d: 7 } } }const nested4 = nested3.updateIn([ 'a', 'b', 'c' ], list => list.push(6));
// Map { a: Map { b: Map { c: List [ 3, 4, 5, 6 ], d: 7 } } }
toJS()
toJS(): immutable数据转原生js类型的数据 (深度转换,会将内部嵌套的Map和List全部转换成原生js)
用法:value.toJS()
代码实现:
const { Map, List } = require('immutable');
const deep = Map({ a: 1, b: 2, c: List([ 3, 4, 5 ]) }); console.log(deep.toObject()); // { a: 1, b: 2, c: List [ 3, 4, 5 ] }
console.log(deep.toArray()); // [ 1, 2, List [ 3, 4, 5 ] ]
console.log(deep.toJS()); // { a: 1, b: 2, c: [ 3, 4, 5 ] }
JSON.stringify(deep); // '{"a":1,"b":2,"c":[3,4,5]}'
toJS() mmutable===>普通对象
oldImmuObj.toJS()
newImmuObj.toJS()
案例
import React, { Component } from 'react'
import { Map } from 'immutable' export default class App extends Component {state = {info: {name: 'demo',age: 100}}render() {return (<div> this.state.info.name -- {this.state.info.name} <br/>this.state.info.age -- {this.state.info.age} <br/><button onClick={()=>{var old = Map(this.state.info)var newData = old.set('name','32333').set('age', 1000)this.setState({info: newData.toJS()})}}>修改</button></div>)}
}
fromJS()
fromJS(): 原生js转immutable对象 (深度转换,会将内部嵌套的对象和数组全部转成immutable)
用法:fromJS(value, converter)
简介:value是要转变的数据,converter是要做的操作。第二个参数可不填,默认情况会将数组准换为List类型,将对象转换为Map类型,其余不做操作
const { fromJS } = require('immutable');
const nested = fromJS({ a: { b: { c: [ 3, 4, 5 ] } } });
// Map { a: Map { b: Map { c: List [ 3, 4, 5 ] } } } const obj = fromJS({a:'123',b:'234'},function (key, value, path) {console.log(key, value, path)return isIndexed(value) ? value.toList() : value.toOrderedMap())
})
总结:增删改查(所有操作都会返回新的值,不会修改原来值)
代码实现
// 增删改查(所有操作都会返回新的值,不会修改原来值)
const immutableData = immutable.fromJS({a: 1,b: 2,c: {d: 3}
});
const data1 = immutableData.get('a') // data1 = 1
const data2 = immutableData.getIn(['c', 'd']) // data2 = 3; getIn用于深层结构访问
const data3 = immutableData.set('a' , 2); // data3中的 a = 2
const data4 = immutableData.setIn(['c', 'd'], 4); // data4中的 d = 4
const data5 = immutableData.update('a' , function(x) { return x+4 }) // data5中的 a = 5
const data6 = immutableData.updateIn(['c', 'd'], function(x) { return x+4 }) // data6中的 d = 7
const data7 = immutableData.delete('a') // data7中的 a 不存在
const data8 = immutableData.deleteIn(['c', 'd']) // data8中的 d 不存在
案例
import React, { Component } from 'react'
import { fromJS } from 'immutable'
export default class App extends Component { // state = {// info:Map({// name:"demo",// location:Map({// province:"辽宁",// city:"大连"// }),// favor:List(["读书","看报","写代码"])// })// }// 使用 fromJS 转换成 immutable对象state = {info:fromJS({ // 注意这里 fromJS -- 转换成 immutable对象name:"demo", location:{province:"辽宁",city:"大连"},favor:["读书","看报","写代码"]})
} render() {return (<div><h1>个人信息修改</h1> <div>{this.state.info.get('name')} <button onClick={()=>{this.setState({info: this.state.info.set('name','demo33').setIn(['location','city'],'wuhan') // 注意这里 setIn(['location','city'],'wuhan')})}}>修改</button></div><div>{this.state.info.get('location').get('province')} -- {this.state.info.get('location').get('city')}</div><ul>{this.state.info.get('favor').map((item,index)=><li key={index}>{item} <button onClick={()=>{this.setState({info: this.state.info.updateIn(["favor"],(list)=>list.splice(index,1)) // 注意这里 updateIn(["favor"],(list)=>list.splice(index,1))})}}>删除</button></li>)}</ul></div>)}
}
Immutable-js 优缺点
优点:
降低mutable带来的复杂度
节省内存
历史追溯性(时间旅行)
时间旅行指的是,每时每刻的值都被保留了,想回退到哪一步只要简单的将数据取出就行。
如果现在页面有个撤销的操作,撤销前的数据被保留了,只需要取出就行,这个特性在redux或者flux中特别有用
- 拥抱函数式编程:immutable本来就是
函数式编程
的概念,纯函数式编程的特点就是,只要输入一致,输出必然一致,相比于面向对象,这样开发组件和调试更方便
缺点:
需要重新学习api
资源包大小增加(源码5000行左右)
容易与原生对象混淆:由于api与原生不同,混用的话容易出错。
相关文章:
Immutable.js API 简介
Immutable-js 这个库的实现是深拷贝还是浅拷贝?immutable 来源immutable.js三大特性: 持久化数据结构结构共享惰性操作 Immutable.js 的几种数据类型 immutable 使用 使用 npm 安装 immutable: 常用API介绍 MapListList.isList() 和 Map.isMa…...
HLSL 入门(一)
HLSL High Level Shader Language 高级着色语言,是Direct3D中用来编写Shader的语言。其语法类似于C语言。 虽然其主要作用是用来编写例如顶点着色器,像素着色器。但本质是对图形并行管线进行编程,因此也能用来编写用于计算的着色器ÿ…...
【Docker】挂载数据卷
一、Docker数据卷说明及操作 在Docker中挂载数据卷是一种将数据持久化保存的方法,以便容器之间或容器与主机之间共享数据。以下是如何在Docker中挂载数据卷的步骤: 1、创建数据卷 首先,您需要创建一个数据卷。可以使用以下命令创建一个数据卷…...
[技术干货]spring 和spring boot区别
Spring 和 Spring Boot 都是 Java 框架,用于构建企业级应用程序。Spring 是一个完整的框架,提供各种功能,包括依赖注入、事务管理、数据访问、Web 开发等。Spring Boot 是一个基于 Spring 的框架,旨在简化 Spring 应用程序的开发和…...
【hudi】数据湖客户端运维工具Hudi-Cli实战
数据湖客户端运维工具Hudi-Cli实战 help hudi:student_mysql_cdc_hudi_fl->help AVAILABLE COMMANDSArchived Commits Commandtrigger archival: trigger archivalshow archived commits: Read commits from archived files and show detailsshow archived commit stats: …...
RK3588 添加ROOT权限
一.ROOT简介 ROOT权限是Linux和Unix系统中的超级管理员用户帐户,该帐户拥有整个系统的最高权利,可以执行几乎所有操作。ROOT就是获取安卓系统中的最高用户权限,以便执行一些需要高权限才能执行的操作(包括卸载系统自带程序、刷机、备份、还原…...
【云原生】k8s-----集群调度
目录 1.k8s的list-watch机制 1.1 list-watc机制简介 1.2 根据list-watch机制,pod的创建流程 2.scheduler的调度策略 2.1 scheduler的调度策略简介 2.2 Scheduler预选策略的算法 2.3 Scheduler优选策略的算法 3. k8s中的标签管理及nodeSelector和nodeName的 调…...
一键集成prometheus监控微服务接口平均响应时长
一、效果展示 二、环境准备 prometheus + grafana环境 参考博文:https://blog.csdn.net/luckywuxn/article/details/129475991 三、导入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter...
2023/9/13 -- C++/QT
作业: 1> 将之前定义的栈类和队列类都实现成模板类 栈: #include <iostream> #define MAX 40 using namespace std;template <typename T> class Stack{ private:T *data;int top; public:Stack();~Stack();Stack(const Stack &ot…...
mybatis mapper.xml转建表语句
从网上下载了代码,但是发现没有DDL建表语句,只能自己手动创建了,感觉太麻烦,就写了一个工具类 将所有的mapper.xml放入到一个文件夹中,程序会自动读取生成建表语句 依赖的jar <dependency><groupId>org.d…...
封装使用Axios进行前后端交互
Axios是一个强大的HTTP客户端,用于在Vue.js应用中进行前后端数据交互。本文将介绍如何在Vue中使用Axios,并通过一个企业应用场景来演示其实际应用。 Axios简介 公众号:Code程序人生,个人网站:https://creatorblog.cn A…...
SOA、分布式、微服务
SOA: SOA是一种软件设计架构,用于构建分布式系统和应用程序。它将应用程序拆分为一系列松耦合的服务,这些服务通过标准化的接口进行通信,并能够以可编程方式组合和重用。SOA的目标是提高系统的灵活性、可扩展性和可维护性。 特点&…...
json数据传输压缩以及数据切片分割分块传输多种实现方法,大数据量情况下zlib压缩以及bytes指定长度分割
json数据传输压缩以及数据切片分割分块传输多种实现方法,大数据量情况下zlib压缩以及bytes指定长度分割。 import sys import zlib import json import mathKAFKA_MAX_SIZE 1024 * 1024 CONTENT_MIN_MAX_SIZE KAFKA_MAX_SIZE * 0.9def split_data(data):"&q…...
移动端APP测试-如何指定测试策略、测试标准?
制定项目的测试策略是一个重要的步骤,可以帮助测试团队明确测试目标、测试范围、测试方法、测试资源、测试风险等,从而提高测试效率和质量。本篇是一些经验总结,理论分享。并不是绝对正确的,也欢迎大家一起讨论。 文章目录 一、测…...
【Redis】深入探索 Redis 主从结构的创建、配置及其底层原理
文章目录 前言一、对 Redis 主从结构的认识1.1 什么是主从结构1.2 主从结构解决的问题 二、主从结构创建2.1 配置并建立从节点2.2.1 从节点配置文件2.2.2 启动并连接 Redis 主从节点2.2.3 SLAVEOF 命令2.2.4 断开主从关系 2.2 查看主从节点的信息2.2.1 INFO REPLICATION 命令2.…...
CSS 滚动驱动动画 scroll-timeline ( scroll-timeline-name ❤️ scroll-timeline-axis )
scroll-timelinescroll-timeline-name❤️scroll-timeline-axis 解决问题语法 animation-timeline-nameanimation-timeline-axis scroll-timeline ( scroll-timeline-name ❤️ scroll-timeline-axis ) 在 scroll() 的最后我们遇到了因为定位问题导致滚动效果失效的情况, 当…...
9.19号作业
2> 完成文本编辑器的保存工作 widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QFontDialog> #include <QFont> #include <QMessageBox> #include <QDebug> #include <QColorDialog> #include <QColor&g…...
Mybatis学习笔记9 动态SQL
Mybatis学习笔记8 查询返回专题_biubiubiu0706的博客-CSDN博客 动态SQL的业务场景: 例如 批量删除 get请求 uri?id18&id19&id20 或者post id18&id19&id20 String[] idsrequest.getParameterValues("id") 那么这句SQL是需要动态的 还…...
element表格 和后台联调
1.配置接口 projectList:/api/goods/xxx,//产品列表2.请求接口(get请求默认参数page) // 产品列表 pageprojectList(params){return axios.get(base.projectList,{params})}3.获取数据 直接放到created里边去了 刷新页面就可以看到 async projectList(page){let res await t…...
基于SSM的智慧城市实验室主页系统的设计与实现
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用Vue技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目&#x…...
怒赞,阿里P8推荐的Java面试宝典:41个专题PDF(史上最全+面试必备)
《尼恩Java面试宝典》 40岁老架构师 尼恩 经过对大量 Java面试题 的不断梳理、迭代, 编著成5000页的《尼恩Java面试宝典》,致力于体系化, 系统化,形象化 梳理,形成一个大的知识体系,从而帮助大家 进大厂&a…...
线程池各个参数设置说明
1. corePoolSize 核心线程数 看处理业务属于IO密集型还是属于cpu密集型IO密集型: 通常设置为N1,还有一个计算公式:线程数 cpu数*(线程等待时间/线程总的处理时间) 但是由于服务器除了这个服务可能还部署有其他服务,…...
springBoot对接多个mq并且实现延迟队列---未完待续
mq调用流程 创建消息转换器 package com.wd.config;import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; import org.springframework.amqp.support.converter.MessageConverter; import org.springframework.context.annotation.Bean; import o…...
Pytorch从零开始实战04
Pytorch从零开始实战——猴痘病识别 本系列来源于365天深度学习训练营 原作者K同学 文章目录 Pytorch从零开始实战——猴痘病识别环境准备数据集模型选择模型训练数据可视化其他模型图片预测 环境准备 本文基于Jupyter notebook,使用Python3.8,Pytor…...
北大C++课后记录:文件读写的I/O流
前言 文件和平常用到的cin、cout流其实是一回事,可以将文件看作一个有限字符构成的顺序字符流,基于此,也可以像cin、cout读键盘数据那样对文件进行读写。 读写指针 输入流的read指针 输出流的write指针 注:这里的指针并不是普…...
详解Linux的grep命令
2023年9月19日,周二晚上 先写这么多吧,以后有空再更新,还要一些作业没写完.... 目录 概述查看grep命令的所有选项grep的常用选项选项-i选项-v选项-n选项-c编辑选项-l组合使用 概述 grep命令在Linux系统中是一个很重要的文本搜索工具和过…...
spark6. 如何设置spark 日志
spark yarn日志全解 一.前言二.开启日志聚合是什么样的2.1 开启日志聚合MapReduce history server2.2 如何开启Spark history server 三.不开启日志聚合是什么样的四.正确使用log4j.properties 一.前言 本文只讲解再yarn 模式下的日志配置。 二.开启日志聚合是什么样的 在ya…...
glibc: strlcpy
https://zine.dev/2023/07/strlcpy-and-strlcat-added-to-glibc/ https://sourceware.org/git/?pglibc.git;acommit;h454a20c8756c9c1d55419153255fc7692b3d2199 https://linux.die.net/man/3/strlcpy https://lwn.net/Articles/612244/ 从这里看,这个strlcpy、st…...
如何在 Buildroot 中配置 Samba
在 Buildroot 中配置 Samba 在 Buildroot 中配置 Samba 可以通过以下步骤完成: 1. 进入 Buildroot 的根目录。 2. 执行 make menuconfig 命令,打开 Buildroot 的配置菜单。 3. 在配置菜单中,使用键盘导航到 "Target packages" 选…...
SSM02
SSM02 此时我们已经做好了登录模块接下来可以做一下学生管理系统的增删改查操作 首先,我们应当有一个登录成功后的主界面 在webapp下新建 1.main.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…...
wordpress首页无法找到/郑州百度公司地址
跨域问题主要在header上下功夫 首先提供一个w3c的header定义 http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html 再提供一个网友提供的header详解 http://kb.cnblogs.com/page/92320/ 这两个有助于帮助大家理解header的类型和作用, 但是遗憾的是跨域相关的两…...
焦作 做 网站/seo教程网站优化
我司(东识科技DONWIT)RFID文件管理系统是依托互3D技术、云计算、大数据、RFID技术、数据库技术、AI、视频分析技术对RFID智能仓库进行统一管理、分析的信息化、智能化、规范化的系统。 近年来,电子化、网络化长足进步,电子政务不…...
外贸商城网站制作/哈尔滨百度网络推广
定义头部文件,防止写中文时乱码 header("content-type:text/html;charsetutf-8");接收数据$username $_POST["uname"];$userpwd $_POST["upwd"];处理数据:将接收到的用户名和密码 添加到数据库的user表中1--连接数据源 mysql_con…...
网站ui/360推广怎么收费
【科技犬】华为6月2日发布会上会公布鸿蒙系统第一批升级名单,并且会在5月31号开始归档,6月2日同步升级,后续再逐步公布各批次升级时间,其中首批名单包括:Mate40、Mate40 Pro、Mate40 Pro、Mate40 RS、MateX2、nova8、n…...
余姚网站建设的公司/培训学校加盟费用
大家好,我是老赵一. 介绍FACE-UI 基于前后端分离Web端项目,主要实现了网页版的人脸登录,通过调取前端摄像头拍照,传入后台进行跟数据库人脸库的相似度比对。技术点:Springboot,Mysql,JWT&#x…...
海口小程序开发/正规seo关键词排名网络公司
文章目录公共字段自动填充问题分析基本功能实现思路分析代码实现功能测试功能完善思路分析ThreadLocal操作步骤代码实现功能测试思维导图总结新增分类需求分析数据模型前端页面分析代码实现功能测试分类信息分页查询需求分析前端页面分析代码实现功能测试思维导图总结删除分类需…...