自定义模块

为什么要模块?模块化源代码能给我们带来什么好处?

试想一个巨无霸网购平台,在没有模块化的情况下,如果出现bug,程序员就要在几百万行代码里调试,导致后期维护成本上升,为了解决问题,模块化按功能切分,把大问题转换成小问题,让每个模块独立运营,通过接口对外开放,让程序统一调用,降低程序出错的风险,也能方便升级模块内部的代码,不影响全局

创建模块(计算器)

模拟巨无霸程序(现有两个js文件 app.js server.js)

如果没有模块化程序,那么server.js也想用这些功能的时候也必须将函数写一遍。就会出现代码重叠,如果要修改,就要全部进行修改

所以我们将这部分函数模块化

  1. 新建calculator.js,将 app.js 的函数剪贴到其中(此时再运行app.js会出错)

  2. 我们需要在 app.js 中引入我们新建的模块打印出来了一个 { } 空 Object 对象,️ 这是因为 calculator.js 里的函数是不会自动暴露或者被输出的,我们需要明确告诉NodeJS哪一个函数需要被输出,那样才能被其他程序引入和调用

  1. 模块使用 module.exports 语句,在运行 app.js console输出函数 add

  1. 那 subtract 怎么办呢,因为module.exports={ },我们可以往里添加新数据,我们只需要提供一对 key-value 即可

  1. console输出两个函数 add, subtract
// app.js
const calculator = require('./calculator.js'); console.log(calculator); let addResult = calculator.add(1,2); console.log(`1 + 2 = ${addResult}`);

const calculator = require('./calculator.js');

console.log(calculator);

let SubtractResult = calculator.subtract(5,2);

console.log(`5 - 2 = ${SubtractResult}`);

function add(num1,num2){
return num1 + num2;
} function subtract(num1,num2){
return num1-num2;
} //module.exports.add = add;
//module.exports.subtract = subtract; //exports.add = add;
//exports.subtract = subtract; module.exports = {
add, //add:add,
subtract //subtract:subtract
}

自定义模块小技巧

  • 如果我们有很多模块,重复输入 module.exports 是很麻烦的,NodeJS给我们提供了一个便利,直接把最前面的 module 去掉
  • 我们可以写成 module.exports = { 内容 } 的形式来简化,如果key-value相等,可以只写key

️ CMD终端的基本使用

sysdm.cpl  可快速打开计算机设置配置环境变量
md abc 创建目录 abc
rd abc 删除目录 abc
cd .. 进到上层目录 如果目录不是空的不能用rd删除目录,需要加两个参数
rd /s/q abc (sub-directory quiet) echo on a.txt 创建 a.txt
往里面覆盖内容
echo 123 > a.txt
往里面追加内容
echo 456 >> a.txt cat a.txt 输出文件内容 rm a.txt 删除文件 cat > hello.txt 覆盖(按ctrl c 退出)
cat >> hello.txt 追加内容(按ctrl c 退出) 在文件内按 Shift 右键 选择 在该目录下执行命令行

Node.JS 全局成员

console.log(123);

// 包含文名称的全路径
console.log(__filename);
// 文件的路径(不包含文件名称)
console.log(__dirname); // 定时函数
const a = setTimeout(()=>{
console.log(123);
},3000); setTimeout(()=>{console.log(123)},200);
clearTimeout(a); // process.argv 是一个数组,默认情况前两项数据分别是:Node.js的安装环境的路径,当前执行的js文件的全路径
// 从第三个参数开始表示命令行参数
console.log(process.argv);
console.log(process.argv0); // 打印当前系统的架构(x64, x86)
console.log(process.arch);

初识模块化(1-2)

/*
index.js
模块化开发 传统非模块化开发有如下的缺点:
1、命名冲突(团队开发)
2、文件依赖(文件引入与先后次序) 前端标准的模块化规范:
1、AMD - requirejs
2、CMD - seajs 后端标准的模块化规范:
1、CommonJS - Node.js 模块化相关的规则:
1、 如何定义模块:一个js文件就是一个模块,模块内部的成员都是相互独立的
2、 模块成员的导出和引入
*/ const a = function(a,b){
return parseInt(a) + parseInt(b);
} // 导出模块成员
//exports.sum = a; module.exports = a; //此时这个模块本身就是个方法
/*
a.js
引入模块
*/ const mod = require('./index.js'); console.log(mod); //var ret = mod.sum(12,13); var ret = mod(12,13); console.log(ret);

模块化细节补充

/*
index.js
模块成员的导出 global 已经加载的模块会缓存,如果内存中有同样的文件就不会加载(性能优化)
*/ console.log('hello'); var flag = 123; // 很少使用
global.flag = flag;
/*
a.js
模块文件的后缀3种情况: .js .json .node(C、C++)(不加后缀时加载顺序)
*/ //require('./index.js');
//require('./index.js');
//require('./index.js'); require('./index'); // 后缀可以直接省略 var data = require('./data') console.log(global.flag);
console.log(data);
// data.json
{
"username":"张三",
"age":12
}

ES6 let、const 使用规范

/*
声明变量 let和const
*/ // let 声明的变量不存在预解析
//console.log(flag);
// var flag = 123;
// let flag = 456; // let 声明的变量不允许重复(同一作用域)
//let flag = 123;
//let flag = 456;
//console.log(flag); // ES6 引入了块级作用域
// 块内部let定义的变量,在外部访问不到
// if(true){
// //var flag = 123;
// let flag = 123;
// }
/* -------------------------------------------------------------------------- */
{
// 这里是块级作用域
let flag = 123;
console.log(flag);
}
//console.log(flag);
/* -------------------------------------------------------------------------- */
for(let i = 0; i < 3; i++){
// for循环括号中let声明的变量只能在循环体中使用
console.log(i);
}
/* -------------------------------------------------------------------------- */
// 在块级作用域内部,变量只能先声明再使用,因为没有预解析
if(true){
//console.log(flag);
let flag = 123;
} /* ---------------------------------- const --------------------------------- */ // const用来声明常量,不允许重新赋值,一开始必须要初始化
// 上述规则对 const 同样适用
// const n = 1;
// n = 2;

ES6 变量解构赋值

/*
变量的解构赋值
*/ // var a = 1;
// var b = 2;
// var c = 3; // var a = 1,b = 2,c = 3; // * 数组的解构赋值,根据顺序,还可以添加默认值
//let [a,b,c] = [1,2,3]; //let [a=111,b,c] = [,123,]; //console.log(a,b,c); // * 对象的解构赋值
//let {foo,bar} = {foo:'hello',bar : 'hi'};
//let {foo,bar} = {bar : 'hi',foo:'hello'}; // * 对象属性别名(如果起了别名,那么原来的名字就无效了)
// let {foo:abc,bar} = {foo:'hello',bar : 'hi'} // console.log(typeof(abc),bar,abc); // * 对象的解构赋值设置默认值
let {foo:abc="hello",bar} = {bar : 'hi'};
console.log(abc,bar); // * 把对象当中的属性与名称的进行绑定
let {cos,sin,random} = Math; console.log(typeof cos,typeof sin,typeof random);
/* -------------------------------------------------------------------------- */
// * 字符串的解构赋值 let [a,b,c,d,e,length] = "hello";
console.log(a,b,c,d,e,length); let {length:len} = "hel"; console.log(len);

ES6 字符串扩展与模板字符串

/*
字符串相关扩展
includes() 判断字符串中是否包含指定的子串(有的话返回true,否则返回false)
参数一:匹配的子串;参数二:从第几个字符开始匹配
startsWith() 判断字符串是否以特定的子串开始
endsWith() 判断字符串是否以特定的子串结束 模板字符串
*/ console.log('hello world'.includes('world',6)); let url = 'admin/index.php'; console.log(url.startsWith('admin'));
console.log(url.endsWith('php')); /* -------------------------------------------------------------------------- */
let obj = {
username : '李四',
age:'12',
gender: 'male'
}; let tag = '<div><span>'+obj.username+'</span><span>'+obj.age+'</span><span>'+obj.gender+'</span></div>';
// 反引号表示模板,模板中的内容可以有格式,通过 ${}方式填充数据
let fn = (x)=> x;
let tag2 = `
<div>
<span>${obj.username}</span>
<span>${obj.age}</span>
<span>${obj.gender}</span>
<span>${1+1}</span>
<span>${fn('nihao')}</span>
</div>
` console.log(tag);
console.log(tag2); // * 模板字符串后期维护方便

ES6 函数扩展

/*
函数扩展
- 参数默认值
- 参数解构赋值
- rest参数
- ...扩展运算符
*/ //参数默认值老式方法
function foo(param) {
let p = param || 'hello';
console.log(p);
}
foo(); function foo2(param = 'nihao') {
console.log(param);
} foo2();
foo2('123456'); /* -------------------------------------------------------------------------- */ function foo3(uname = 'list', age = 12) {
console.log(uname, age);
} foo3();
foo3('张三', 13); // * 参数解构赋值
function foo4({
uname = 'lisi',
age = 10
} = {}) {
console.log(uname, age);
} foo4(); //! 不传参会出问题,可以给函数参数一个默认值 {}
foo4({
uname: 'zhangsan',
age: 15
}); /* -------------------------------------------------------------------------- */
// * rest参数(剩余参数)...
function foo5(a, ...params) {
console.log(params);
} foo5(1, 2, 3, 4, 5); // 扩展运算符 ... function foo6(a, b, c, d, e, f){
console.log(a + b + c + d + e + f);
} foo6(1,2,3,4,5,6);
let arr = [1,2,3,4,5,6];
//foo6.apply(null,arr); foo6(...arr); // ! 扩展运算符 // 合并数组
let arr1 = [1,2,3];
let arr2 = [4,5,6];
let arr3 = [...arr1,...arr2];
console.log(arr3);

apply、call函数妙用

ES6 箭头函数

node执行调试完成之后进程退出,这时候去看它的打印内容就看不到了

需要看到他具体的值,在打印的地方加上断点即可
/*
箭头函数
*/ function foo(){
console.log('hello');
}
foo(); let foo2= () => console.log('hello');
foo2(); let foo3= x => x;
foo3(123); // * 多个参数必须用小括号包住
let foo4 = (a,b) => console.log(a+b);
foo4(1,2); let arr = [1,2,3];
arr.forEach(function(value,index){
console.log(value,index);
}); arr.forEach((value,index)=>console.log(value,index)); // ! 箭头函数的注意事项
// - 箭头函数中的this取决于函数的定义位置而不是调用位置
// - 箭头函数不可以 new
// - 箭头函数不可以使用 arguments 获取参数列表,可以使用rest参数代替
function foo5(){
// 使用call调用foo5时,这里的this其实就是call的第一个参数
console.log(this);
setTimeout(()=>{
console.log(this,this.num);
},1000);
} foo5();
foo5.call({num:1});
/* -------------------------------------------------------------------------- */
let foo6 = ()=> {this.num = 123;}
//new foo6();
/* -------------------------------------------------------------------------- */
let foo7 = (a,b) =>{
console.log(a,b,arguments); //这种方式获取不到实参列表
}
foo7(123,456); let foo8 = (...param) => { //rest参数
console.log(param);
}
foo8(123,456);

ES6 类与继承

/*
类与继承
*/
// function Animal(name){
// this.name = name;
// } // Animal.prototype.showName = function(){
// console.log(this.name);
// }
// var a = new Animal('Tom');
// a.showName();
// var b = new Animal('Jerry');
// a.showName();
/* -------------------------------------------------------------------------- */ class Animal{
// * 静态方法(静态方法只能通过类名调用,不可以使用实例对象调用)
static showInfo(){
console.log('hello');
}
// * 构造函数
constructor(name){
this.name = name;
}
showName(){
console.log(this.name);
}
}
let a = new Animal('spike');
a.showName();
Animal.showInfo();
/* -------------------------------------------------------------------------- */
// 类的继承 extends
class Dog extends Animal{
constructor(name,color){
super(name); // super用来调用父类
this.color = color;
}
ShowColor(){
console.log(this.color);
}
} let d = new Dog('doudou','yellow');
d.showName();
d.ShowColor();
Dog.showInfo();

Buffer基本操作

console.log(Buffer.isEncoding('utf8'));
console.log(Buffer.isEncoding('gbk')); let buf = Buffer.from('hello');
console.log(buf);
console.log(Buffer.isBuffer(buf));
console.log(Buffer.isBuffer({})); let buf2 = Buffer.from('中国','ascii');
console.log(Buffer.byteLength(buf2));
console.log(buf2.toString()); let buf31 = Buffer.alloc(3);
let buf32 = Buffer.alloc(5);
let buf33 = Buffer.concat([buf31,buf32]);
console.log(Buffer.byteLength(buf33)); /* -------------------------------------------------------------------------- */
// 实例方法 let buf4 = Buffer.alloc(5);
buf4.write('hello',2,2); // * 向buffer对象中写入内容 [from] - counts
console.log(buf4); let buf51 = Buffer.from('hello');
let buf52 = buf51.slice();
console.log(buf51==buf52); // ! 两个不同的buffer对象
buf52 = buf51.slice(1,3); // * 截取buffer对象的内容 [from] - (to)
console.log(buf52.toString()); // ! toJSON方法不需要显式调用,当JSON.stringify方法调用的时候会自动调用toJSON方法
const buf6 = Buffer.from('hello');
const json = JSON.stringify(buf6); // * 将buffer对象转成JSON,对应的十进制
console.log(json);

Node.JS 路径操作

/*
路径操作
*/
const path = require('path'); // * 获取路径的最后一部分
console.log(path.basename('/foo/bar/baz/asdf/quux.html'));
console.log(path.basename('/foo/bar/baz/asdf/quux.html','.html')); // * 获取路径
console.log(__dirname);
console.log(path.dirname('/abc/qq/www/aabc.txt')); // * 获取文件扩展名
console.log(path.extname('index.html')); // * 路径的格式化处理
// path.format() obj->string
// path.parse() string->obj let obj = path.parse(__filename);
console.log(obj); /*
{
root: 'F:\\', 文件根路径
dir: 'F:\\Node.JS\\Codes\\1031\\NodeJS基础\\2-1 路径操作', 文件全路径
base: 'index.js', 文件名称
ext: '.js', 文件扩展名
name: 'index' 文件名称
}
*/ let objpath = {
root: 'd:\\',
base: 'abc.txt',
dir : 'd:\\aaaaa\\cccc\\',
ext: '.txt',
name: 'abc',
};
let strPath = path.format(objpath);
console.log(strPath); // * 判断是否为绝对路径
path.isAbsolute('C:/foo/..'); // * 拼接路径,在连接路径的时候会格式化
console.log(path.join('/foo','bar','baz/asdf','quux','../../')); // ! 两个点是上层路径,一个点表示当前路径 // * 规范化路径
console.log(path.normalize('/foo/bar//baz/asdf/quux/..'))
console.log(path.normalize('C:\\temp\\\\foo\\bar\\..\\')); // * 从两个绝对路径换算出来相对路径
console.log(path.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb')); // * 解析路径
console.log(path.resolve('wwwroot', 'static_files/png/', '../gif/image.gif')); // * 两个特殊属性
console.log(path.delimiter); // * 环境变量分隔符 windows 是 ; linux 是 :
console.log(path.sep); // * 路径分隔符,windows 是 \ LINUX是 /

异步I/O

/*
异步I/O input/output
- 文件操作
- 网络操作 在浏览器中也存在异步操作:
- 定时任务
- 事件处理
- Ajax回调处理 js的运行是单线程的
引入了事件队列机制 Node.js中的事件模型与浏览器中的事件模型类似
单线程+事件队列 Node.js中异步执行的任务:
1、文件I/O
2、网络I/O 基于回调函数的编码风格
*/

文件操作

文件状态

/*
文件状态
*/
const fs = require('fs');
console.log(1);
fs.stat(`${__dirname}/data.txt`,(err,stat)=>{
// ! 一般回调函数的第一个参数是错误对象,如果err为null,表示没有错误,否则表示报错了
if(err) return;
console.log(stat);
if(stat.isFile()){
console.log('文件');
}
else if(stat.isDirectory()){
console.log('目录');
}
/*
atime 访问时间
mtime 文件数据发生变化的时间
ctime 文件状态信息发生变换的时间(比如文件的权限)
birthtime 文件创建的时间
*/
});
console.log(2); // 同步操作
// console.log(1);
// let ret = fs.statSync(`${__dirname}/data.txt`);
// console.log(ret);
// console.log(2); // ! 当主线程执行完了才会空闲,去把事件队列中的任务取出来

读文件

/*
读文件操作
*/
const fs = require('fs');
const path = require('path'); let strPath = path.join(__dirname,'data.txt'); fs.readFile(strPath,(err,data)=>{
if(err) return;
console.log(data); // * 打印出字节数组
console.log(data.toString());
}); // * 第二个参数可以指定编码,得到的数据是字符串
// * 如果没有第二个参数,那么得到的就是Buffer实例对象
fs.readFile(strPath,'utf8',(err,data)=>{
if(err) return;
console.log(data); // * 打印出字符串
}); // ! 同步操作,不需要回调函数
let ret = fs.readFileSync(strPath,'utf8');
console.log(ret);

写文件

/*
写文件操作
*/
const fs = require('fs');
const path = require('path'); let strpath = path.join(__dirname,'data.txt');
// * 默认编码方式 encoding : utf 8
// fs.writeFile(strpath,'hello cat',(err)=>{
// if(err) throw err;
// else {
// console.log('文件写入成功');
// }
// })
// ! 多次写入需要使用数据流的方式 // let buf = Buffer.from('world');
// fs.writeFile(strpath,buf,(err)=>{
// if(err) throw err;
// else {
// console.log('文件写入成功');
// }
// }) // ! 同步操作
fs.writeFileSync(strpath,'tom and jerry');

文件流式操作(针对大文件)

/*
大文件操作(流式操作)
fs.createWriteStream(path[, options])
fs.createReadStream(path[, options])
*/
const path = require('path');
const fs = require('fs'); let sPath = path.join(__dirname,'../files','file.zip');
let dPath = path.join('P:\\','file.zip'); let readStream = fs.createReadStream(sPath);
let writeStream = fs.createWriteStream(dPath); // 基于事件的处理方式
// * 举例
// $('input[type=button]').on('click',function(){
// console.log('hello');
// }); // * 在NodeJS中无DOM操作,所以没有点击事件 // let num = 0;
// readStream.on('data',(chunk)=>{ // ! data 是固定的事件,每读取一部分就触发
// num++;
// writeStream.write(chunk);
// }); // readStream.on('end',()=>{ // ! end 是固定的事件
// console.log(num);
// console.log('文件处理完成');
// }) /* -------------------------------------------------------------------------- */ // * 另外一种方式,pipe的作用直接把输入流(从磁盘加载到内存)与输出流(从内存写入到磁盘)
readStream.pipe(writeStream); /* -------------------------------------------------------------------------- */ fs.createReadStream(sPath).pipe(fs.createWriteStream(dPath));

目录操作

/*
目录操作
- 创建目录
fs.mkdir(path[, options], callback)
fs.mkdirSync(path[, options])
- 读取目录
fs.readdir
fs.readdirSync */ const path = require('path');
const fs = require('fs'); // fs.mkdir(path.join(__dirname,'../files','abc'),(err)=>{
// console.log(err);
// }); // fs.mkdirSync(path.join(__dirname,'../files','abc'));
/* -------------------------------------------------------------------------- */
// 读取目录下的目录与文件
// fs.readdir(path.join(__dirname,'..'),(err,files)=>{
// console.log(err,files);
// files.forEach((item,index)=>{
// fs.stat(path.join(__dirname,'..',item),(err,stat)=>{
// if(stat.isFile()){
// console.log(item,'文件');
// }
// else if(stat.isDirectory()){
// console.log(item,'目录');
// }
// })
// })
// }); // ! 同步操作
// let files = fs.readdirSync(path.join(__dirname,'..'));
// files.forEach((item,index)=>{
// fs.stat(path.join(__dirname,'..',item),(err,stat)=>{
// if(stat.isFile()){
// console.log(item,'文件');
// }
// else if(stat.isDirectory()){
// console.log(item,'目录');
// }
// })
// }) // ! 删除目录
fs.rmdir(path.join(__dirname,'../files','abc'),(err)=>{
console.log(err);
}); fs.rmdirSync(path.join(__dirname,'../files','abc'));

文件实操案例(初始化目录与文件)

/*
文件操作案例(初始化目录结构)
*/ const path = require('path');
const fs = require('fs'); let root = 'P:\\'
let fileContent = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
欢迎访问
</body>
</html>
`; // 初始化数据
let initData = {
projectName : 'mydemo',
data : [{
name : 'img',
type : 'dir'
},{
name : 'js',
type : 'dir'
},{
name : 'css',
type : 'dir'
},{
name : 'index.html',
type : 'file'
}]
}; // 创建项目根路径
fs.mkdir(path.join(root,initData.projectName),(err)=>{
if(err) return;
// 创建子目录和文件
initData.data.forEach((item)=>{
if(item.type == 'dir'){
// * 创建子目录
fs.mkdirSync(path.join(root,initData.projectName,item.name));
}
else if(item.type == 'file'){
fs.writeFileSync(path.join(root,initData.projectName,item.name),fileContent);
}
})
});

我的Vue之旅、02 ES6基础、模块、路径、IO的更多相关文章

  1. ES6 基础

    转载自:ES6 基础 一.新的变量声明方式 let/const 与var不同,新的变量声明方式带来了一些不一样的特性,其中最重要的两个特性就是提供了块级作用域与不再具备变量提升. 通过2个简单的例子来 ...

  2. 新手必看ES6基础

    ES6 基础 一.新的变量声明方式 let/const 与var不同,新的变量声明方式带来了一些不一样的特性,其中最重要的两个特性就是提供了块级作用域与不再具备变量提升. 通过2个简单的例子来说明这两 ...

  3. ES6基础入门之let、const

    作者 | Jeskson来源 | 达达前端小酒馆 01 首先呢?欢迎大家来学习ES6入门基础let,const的基础知识内容.初始ECMA Script6. ESMAScript与JavaScript ...

  4. vue框架入门和ES6介绍

    vue框架入门和ES6介绍 vue-mvvm模式,vue是一种轻量级的前端框架,主要为模板渲染,数据同步,组件化,模块化,路由等. https://cn.vuejs.org/ 源码:https://g ...

  5. php从入门到放弃系列-02.php基础语法

    php从入门到放弃系列-02.php基础语法 一.学习语法,从hello world开始 PHP(全称:PHP:Hypertext Preprocessor,即"PHP:超文本预处理器&qu ...

  6. 数据分析02 /pandas基础

    数据分析02 /pandas基础 目录 数据分析02 /pandas基础 1. pandas简介 2. Series 3. DataFrame 4. 总结: 1. pandas简介 numpy能够帮助 ...

  7. [Vue入门及介绍,基础使用、MVVM架构、插值表达式、文本指令、事件指令]

    [Vue入门及介绍,基础使用.MVVM架构.插值表达式.文本指令.事件指令] 1)定义:javascript渐进式框架 ​ 渐进式:可以控制一个页面的一个标签,也可以控制一系列标签,也可以控制整个页面 ...

  8. 我的Vue之旅、04 CSS媒体查询完全指南(Media Quires)

    什么是SCSS Sass: Sass Basics (sass-lang.com) SCSS 是 CSS 的预处理器,它比常规 CSS 更强大. 可以嵌套选择器,更好维护.管理代码. 可以将各种值存储 ...

  9. 我的Vue之旅 06 超详细、仿 itch.io 主页设计(Mobile)

    第二期 · 使用 Vue 3.1 + TypeScript + Router + Tailwind.css 仿 itch.io 平台主页. 我的主题 HapiGames 是仿 itch.io 的 in ...

随机推荐

  1. Python 中多线程共享全局变量的问题

    写在前面不得不看的一些P话: Python 中多个线程之间是可以共享全局变量的数据的. 但是,多线程共享全局变量是会出问题的. 假设两个线程 t1 和 t2 都要对全局变量g_num (默认是0)进行 ...

  2. 《深入理解java虚拟机》读书笔记-第二章Java内存区域和内存溢出异常

    java1.7和java8的jvm存在差异,本文先按照<深入理解java虚拟机>的讲解内容总结,并将java8的改变作为附录放在文末 一丶运行时数据区域 ​ 图:java虚拟机运行时数据区 ...

  3. CSS Houdini:用浏览器引擎实现高级CSS效果

    vivo 互联网前端团队-Wei Xing Houdini被称之为Magic of styling and layout on the web,看起来十分神秘,但实际上,Houdini并非什么神秘组织 ...

  4. Idea 的Test测试报错:java.lang.IllegalStateException: Failed to load ApplicationContext

    因为在Test里面使用了注解@Autowired 引入来至bean.xml文件的内容 ,而在Test没有没有办法自动引入,需要在Test类上加上注解 @ContextConfiguration(loc ...

  5. 009 面试题 SQL语句各部分的执行顺序

    SQL语句各部分的执行顺序 select distinct...from t1 (left/right) join t2 on t1.xx=t2.xx where t1.xx=? and t2.xx= ...

  6. 4-5 Spring Boot

    1. 关于Spring Boot Spring Boot是Spring官方的一个产品,其本质上是一个基于Maven的.以Spring框架作为基础的进阶框架,很好的支持了主流的其它框架,并默认完成了许多 ...

  7. 小红书携手HMS Core,畅玩高清视界,种草美好生活

    在相同流量消耗的情况下,540p可秒变1080p?这不是魔法,通过视频超分辨率技术(简称视频超分),就能让视频变得更清晰. 7月20日,在小红书最新版本7.48的App中,用户就能体验到这项技术带来的 ...

  8. python 操作json数据

    简介 JSON(JavaScript Object Notation, JS对象简谱)是一种轻量级的数据交换格式,通常是以键值对的方式呈现,其简洁和清晰的层次结构使得JSON成为理想的数据交换语言,而 ...

  9. html的基础01

    1.什么是网页 2.常用的浏览器有哪些 3.web标准是什么  1.什么是网页  2.常用的浏览器 360.百度那些都是国产浏览器,内核一样,以上六个都是国际浏览器,不同厂商生产(但IE和Edge都是 ...

  10. YII学习总结4(cookie操作)

    cookie操作 <?php namespace app\controllers; use yii\web\Controller; use yii\web\Cookie; class Hello ...