Mybatis 二级缓存应用 (21)
【MyBatis 二级缓存】
概述:一级缓存作用域为同一个SqlSession对象,而二级缓存用来解决一级缓存不能夸会话共享,作用范围是namespace级,可以被多个SqlSession共享(只要是同一个接口方法的相同方法,都可同享)。
- MyBatis默认支持一级二级缓存。在没有任何配置情况下,默认开启一级缓存,MyBatis 的一级缓存是在会话(SqlSession)层面进行缓存的;
- mybatis的二级缓存默认也是开启的,但由于他的作用域是namespace,所以还需要在mapper.xml中开启才能生效;
- 缓存优先级:通过mybatis发起的查询,作用顺序为:二级缓存->一级缓存->数据库 ,其中一二级缓存不为空将直接返回结果,否则查询数据库;
- 缓存失效:当在一个缓存作用域中发生了update、insert、delete 操作后,将会触发缓存失效,下一次查询将命中数据库,从而保证不会查到脏数据;
- MyBatis一级缓存范围是SqlSession内部。二级缓存为namespace,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement,即进行如下配置
1、【缓存解析说明】
有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议实际开发应用中设定缓存级别为Statement(工程pom文件中)。如下:
解释:Executor为顶级接口,SimpleExecutor、BatchExecutor和ReuseExecutor是具体组件实现类,而CachingExecutor是具体的装饰器。具体组件实现类有一个父类BaseExecutor,而这个父类是一个模板模式的典型应用,一级缓存的操作都在这个类中实现,具体的操作数据库的功能子类实现。客户端通过工厂实现调用配置文件最后调用数据读取BaseExecutor中Query方法,首先缓存对象,缓存存在直接从缓存中获得,不存在查询数据后再写入缓存。
(图一):操作缓存业务图
(图二):类关系图
二级缓存开启步骤
A、工程配置文件中增加二级缓存配置信息
B、xxxMapper.xml文件中开启全局二级缓存支持,如果不在某一个Mapper.xml文件中开启cache就不存在二级缓存。
<!-- 声明此namespace开启二级缓存,MyBatis自带的二级缓存 -->
<cache/>
【配置说明】:
A、配置后该namespace下所有 select 语句查询结果将会被缓存;
B、覆盖文件的所有 insert、update 和 delete 语句会刷新缓存;
C、缓存默认使用最近最少使用算法清除不需要缓存;
D、缓存默认不配置定时刷新;
E、缓存默认保存1024个引用;
【cache可以设置属性,举例说明】
<cache
eviction="FIFO"
flushInterval="60000"
/* 每隔 60 秒刷新, (刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新 */
size="2048"
/* 最多可以存储结果对象或列表的 2048 个引用, ,而且返回的对象被认为是只读因此对它们进行修改可能会在不同线程中的调用者产生冲突 */
readOnly="true"/>
/* readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false
*/
[清除策略]:
LRU :最近最少使用:移除最长时间不被使用的对象;
FIFO :先进先出:按对象进入缓存的顺序来移除它们;
SOFT :软引用:基于垃圾回收器状态和软引用规则移除对象;
WEAK :弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象;
C、二级缓存必然会引起脏读,实时性较高的操作可单独关闭关闭二级缓存(某一查询禁用二级缓存)
<select id="queryPersonById" parameterType="int" resultType="com.cache.bean.Person" useCache="false"/>
D、清理二级缓存
二级缓存清理与一级方法相同,使用commit()(执行增、删、改时会执行commit操作,会清理掉缓存,设计这个机制原因是为了防止脏读。注意:二级缓存中commit不能是查询本身的commit);
在select标签中,增加属性flushCache=”true”
E、注意
1)、二级缓存是事务性的。当 SqlSession 完成commit时或是回滚,但未执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新(但不能是同一个SqlSession的查询commit);
2)、MyBatis在多表查询时,极大可能会出现脏数据,设计上存在缺陷;
3)、在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本。使用Redis、Memcached等分布
式缓存可能成本更低,安全性也更高(后续博文发布);
4)、触发二级缓存的时机为session.close时;
5)、XxxMapper.xml文件中的实体类需要做序列化操作,级联类及父类也需要序列化操作;
应用实例:
1、 实体类
public class Person implements Serializable {
static final long serialVersionUID = 42L;
/* 人员ID */
private int id;
/* 人员名称 */
private String name;
/* 人员年龄 */
private int age;
/* 人员性别 */
private Boolean sex; public Person() {
}
public Person(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public Person(int id, String name, int age, Boolean sex) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
public Boolean getSex() {
return sex;
}
public void setSex(Boolean sex) {
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
2、 接口类
// 操作mybatis接口
public interface PersonMapper {
Person queryPersonById(int id);
}
3、 Mapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:该mapper.xml映射文件的唯一标识 -->
<mapper namespace="com.cache.mapper.PersonMapper">
<!- 开启二级缓存-->
<cache/>
<select id="queryPersonById" parameterType="int" resultType="com.cache.bean.Person">
select
id,name,age
from
t_person
where
id = #{id}
</select>
</mapper>
4、pom文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 开启日志,并制定使用的具体日志,LOG4J 对应 log4j.properties的文件名 -->
<!--<setting name="logImpl" value="LOG4J"/>-->
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 关闭立即加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 开启二级缓存,默认不开启 -->
<setting name="cacheEnabled" value="true"/>
<!--<setting name="localCacheScope" value="STATEMENT"/>-->
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis01"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/cache/mapper/personMapper.xml"/>
</mappers>
</configuration>
5、 测试类
/* 二级缓存 */
@Test
public void test001() throws Exception{ Reader reader = Resources.getResourceAsReader("mybatis-01.xml");
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader); SqlSession session01 = sessionFactory.openSession();
PersonMapper personMapper01 = session01.getMapper(PersonMapper.class);
Person person0101 = personMapper01.queryPersonById(1001);
System.out.println("Session01,第一次查询结果为:" + person0101);
session01.close(); // 进行缓存操作
SqlSession session02 = sessionFactory.openSession();
PersonMapper personMapper02 = session02.getMapper(PersonMapper.class);
Person person0201 = personMapper02.queryPersonById(1001);
System.out.println("Session02,第一次查询结果为:" + person0201);
Person person0202 = personMapper02.queryPersonById(1001);
System.out.println("Session02,第二次查询结果为:" + person0202);
Person person0203 = personMapper02.queryPersonById(1001);
System.out.println("Session02,第三次查询结果为:" + person0203);
session02.close(); // 进行缓存操作
}
6、测试结果
"C:\Program Files\Java\jdk1.8.0_25\bin\java" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Users\newsoft\AppData\Roaming\JetBrains\IntelliJ IDEA 2017.3.5\lib\idea_rt.jar=1045:C:\Users\newsoft\AppData\Roaming\JetBrains\IntelliJ IDEA 2017.3.5\bin" -Dfile.encoding=UTF-8 -classpath "C:\Users\newsoft\AppData\Roaming\JetBrains\IntelliJ IDEA 2017.3.5\lib\idea_rt.jar;C:\Users\newsoft\AppData\Roaming\JetBrains\IntelliJ IDEA 2017.3.5\plugins\junit\lib\junit-rt.jar;C:\Users\newsoft\AppData\Roaming\JetBrains\IntelliJ IDEA 2017.3.5\plugins\junit\lib\junit5-rt.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\junit\platform\junit-platform-launcher\1.5.2\junit-platform-launcher-1.5.2.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\apiguardian\apiguardian-api\1.1.0\apiguardian-api-1.1.0.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\junit\platform\junit-platform-engine\1.5.2\junit-platform-engine-1.5.2.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\opentest4j\opentest4j\1.2.0\opentest4j-1.2.0.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\junit\platform\junit-platform-commons\1.5.2\junit-platform-commons-1.5.2.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\junit\jupiter\junit-jupiter-engine\5.5.2\junit-jupiter-engine-5.5.2.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\junit\jupiter\junit-jupiter-api\5.5.2\junit-jupiter-api-5.5.2.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\junit\vintage\junit-vintage-engine\5.5.2\junit-vintage-engine-5.5.2.jar;D:\download\lib\mavenTollTransfer\mic-repository\junit\junit\4.12\junit-4.12.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar;D:\ideaworkspace\ProjectStudy\mybatis-cache-03\target\classes;D:\download\lib\mavenTollTransfer\mic-repository\org\hamcrest\hamcrest-core\2.1\hamcrest-core-2.1.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\hamcrest\hamcrest\2.1\hamcrest-2.1.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\mybatis\mybatis\3.4.5\mybatis-3.4.5.jar;D:\download\lib\mavenTollTransfer\mic-repository\mysql\mysql-connector-java\5.1.44\mysql-connector-java-5.1.44.jar;D:\download\lib\mavenTollTransfer\mic-repository\log4j\log4j\1.2.17\log4j-1.2.17.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\slf4j\slf4j-log4j12\1.7.12\slf4j-log4j12-1.7.12.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\slf4j\slf4j-api\1.7.30\slf4j-api-1.7.30.jar;D:\download\lib\mavenTollTransfer\mic-repository\cglib\cglib\3.3.0\cglib-3.3.0.jar;D:\download\lib\mavenTollTransfer\mic-repository\org\ow2\asm\asm\7.1\asm-7.1.jar;D:\download\lib\mavenTollTransfer\mic-repository\net\logstash\logback\logstash-logback-encoder\5.3\logstash-logback-encoder-5.3.jar;D:\download\lib\mavenTollTransfer\mic-repository\com\fasterxml\jackson\core\jackson-databind\2.10.3\jackson-databind-2.10.3.jar;D:\download\lib\mavenTollTransfer\mic-repository\com\fasterxml\jackson\core\jackson-annotations\2.10.3\jackson-annotations-2.10.3.jar;D:\download\lib\mavenTollTransfer\mic-repository\com\fasterxml\jackson\core\jackson-core\2.10.3\jackson-core-2.10.3.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit5 com.cache.test.test,test001
[lsjSso]2021-10-21 00:18:40,415-org.apache.ibatis.logging.LogFactory-0 [main]DEBUGorg.apache.ibatis.logging.LogFactory-Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
[lsjSso]2021-10-21 00:18:40,563-org.apache.ibatis.datasource.pooled.PooledDataSource-148 [main]DEBUGorg.apache.ibatis.datasource.pooled.PooledDataSource-PooledDataSource forcefully closed/removed all connections.
[lsjSso]2021-10-21 00:18:40,563-org.apache.ibatis.datasource.pooled.PooledDataSource-148 [main]DEBUGorg.apache.ibatis.datasource.pooled.PooledDataSource-PooledDataSource forcefully closed/removed all connections.
[lsjSso]2021-10-21 00:18:40,564-org.apache.ibatis.datasource.pooled.PooledDataSource-149 [main]DEBUGorg.apache.ibatis.datasource.pooled.PooledDataSource-PooledDataSource forcefully closed/removed all connections.
[lsjSso]2021-10-21 00:18:40,564-org.apache.ibatis.datasource.pooled.PooledDataSource-149 [main]DEBUGorg.apache.ibatis.datasource.pooled.PooledDataSource-PooledDataSource forcefully closed/removed all connections.
[lsjSso]2021-10-21 00:18:40,671-com.cache.mapper.PersonMapper-256 [main]DEBUGcom.cache.mapper.PersonMapper-Cache Hit Ratio [com.cache.mapper.PersonMapper]: 0.0
[lsjSso]2021-10-21 00:18:40,679-org.apache.ibatis.transaction.jdbc.JdbcTransaction-264 [main]DEBUGorg.apache.ibatis.transaction.jdbc.JdbcTransaction-Opening JDBC Connection
[lsjSso]2021-10-21 00:18:40,938-org.apache.ibatis.datasource.pooled.PooledDataSource-523 [main]DEBUGorg.apache.ibatis.datasource.pooled.PooledDataSource-Created connection 2009221452.
[lsjSso]2021-10-21 00:18:40,938-org.apache.ibatis.transaction.jdbc.JdbcTransaction-523 [main]DEBUGorg.apache.ibatis.transaction.jdbc.JdbcTransaction-Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@77c2494c]
[lsjSso]2021-10-21 00:18:40,942-com.cache.mapper.PersonMapper.queryPersonById-527 [main]DEBUGcom.cache.mapper.PersonMapper.queryPersonById-==> Preparing: select id,name,age from t_person where id = ?
[lsjSso]2021-10-21 00:18:40,984-com.cache.mapper.PersonMapper.queryPersonById-569 [main]DEBUGcom.cache.mapper.PersonMapper.queryPersonById-==> Parameters: 1001(Integer)
[lsjSso]2021-10-21 00:18:41,012-com.cache.mapper.PersonMapper.queryPersonById-597 [main]DEBUGcom.cache.mapper.PersonMapper.queryPersonById-<== Total: 1
Session01,第一次查询结果为:Person{id=1001, name='HuanCun', age=26}
[lsjSso]2021-10-21 00:18:41,017-org.apache.ibatis.transaction.jdbc.JdbcTransaction-602 [main]DEBUGorg.apache.ibatis.transaction.jdbc.JdbcTransaction-Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@77c2494c]
[lsjSso]2021-10-21 00:18:41,017-org.apache.ibatis.transaction.jdbc.JdbcTransaction-602 [main]DEBUGorg.apache.ibatis.transaction.jdbc.JdbcTransaction-Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@77c2494c]
[lsjSso]2021-10-21 00:18:41,017-org.apache.ibatis.datasource.pooled.PooledDataSource-602 [main]DEBUGorg.apache.ibatis.datasource.pooled.PooledDataSource-Returned connection 2009221452 to pool.
[lsjSso]2021-10-21 00:18:41,019-com.cache.mapper.PersonMapper-604 [main]DEBUGcom.cache.mapper.PersonMapper-Cache Hit Ratio [com.cache.mapper.PersonMapper]: 0.5
Session02,第一次查询结果为:Person{id=1001, name='HuanCun', age=26}
[lsjSso]2021-10-21 00:18:41,019-com.cache.mapper.PersonMapper-604 [main]DEBUGcom.cache.mapper.PersonMapper-Cache Hit Ratio [com.cache.mapper.PersonMapper]: 0.6666666666666666
Session02,第二次查询结果为:Person{id=1001, name='HuanCun', age=26}
[lsjSso]2021-10-21 00:18:41,020-com.cache.mapper.PersonMapper-605 [main]DEBUGcom.cache.mapper.PersonMapper-Cache Hit Ratio [com.cache.mapper.PersonMapper]: 0.75
Session02,第三次查询结果为:Person{id=1001, name='HuanCun', age=26} Process finished with exit code 0
结果分析说明:
Mybatis 二级缓存应用 (21)的更多相关文章
- mybatis二级缓存应用及与ehcache整合
mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓存. 1.开启mybatis的二级缓存 在核心配 ...
- 深入了解MyBatis二级缓存
深入了解MyBatis二级缓存 标签: mybatis二级缓存 2015-03-30 08:57 41446人阅读 评论(13) 收藏 举报 分类: Mybatis(51) 版权声明:版权归博主所 ...
- MyBatis二级缓存配置
正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 Mybatis二级缓存是SessionFactory,如果两次查询基于同一个SessionFactory,那么就从二级缓存 ...
- mybatis二级缓存
二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据放在同一个区域,如果使用mapper代理方法每个mapper的namespace都不同,此时可以理 ...
- 如何细粒度地控制你的MyBatis二级缓存(mybatis-enhanced-cache插件实现)
前几天网友chanfish 给我抛出了一个问题,笼统地讲就是如何能细粒度地控制MyBatis的二级缓存问题,酝酿了几天,觉得可以写个插件来实现这个这一功能.本文就是从问题入手,一步步分析现存的MyBa ...
- MyBatis 二级缓存全详解
目录 MyBatis 二级缓存介绍 二级缓存开启条件 探究二级缓存 二级缓存失效的条件 第一次SqlSession 未提交 更新对二级缓存影响 探究多表操作对二级缓存的影响 二级缓存源码解析 二级缓存 ...
- Springboot整合Ehcache 解决Mybatis二级缓存数据脏读 -详细
前面有写了一篇关于这个,但是这几天又改进了一点,就单独一篇在详细说明一下 配置 application.properties ,启用Ehcache # Ehcache缓存 spring.cache.t ...
- Spring Boot 入门(十):集成Redis哨兵模式,实现Mybatis二级缓存
本片文章续<Spring Boot 入门(九):集成Quartz定时任务>.本文主要基于redis实现了mybatis二级缓存.较redis缓存,mybaits自带缓存存在缺点(自行谷歌) ...
- redis与ssm整合(用 redis 替代mybatis二级缓存)
SSM+redis整合 这里主要是利用redis去做mybatis的二级缓存,mybaits映射文件中所有的select都会刷新已有缓存,如果不存在就会新建缓存,所有的insert,update操作都 ...
随机推荐
- Excel 列名转int索引(C#版)
/// <summary> /// 获取Excel实际列索引 /// </summary> /// <param name="columnName"& ...
- 这款打怪升级的小游戏,7 年前出生于 GitHub 社区,如今在谷歌商店有 8 万人打了满分
今天我在 GitHub 摸鱼寻找新的"目标"时,发现了一个开源项目是 RougeLike 类的角色扮演游戏「破碎版像素地牢」(Shattered Pixel Dungeon)类似魔 ...
- Robot Framework(7)- DateTime 测试库常用的关键字列表
如果你还想从头学起Robot Framework,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1770899.html 前言 所有关键字 ...
- SQL Server Management Studio --- SSMS语言更换
问题描述 在安装了En版后,想更换为中文版,但换了中文安装源还是英文. 解决方法 运行 SQL Server Management Studio 通过菜单选择你想要使用的语言: 中文版:"工 ...
- NIO.2中Path,Paths,Files类的使用
Java NIO Java NIO概述 Java NIO(New IO(新io),Non-Blocking IO(非阻塞的io))是从Java 1.4版本开始引入的一套新的IO API,可以替代标准的 ...
- 【转】shell中的$0 $n $# $* $@ $? $$ 变量 if case for while
shell中的$0 $n $# $* $@ $? $$ shell 编程 | shift 命令用法笔记 $0当前脚本的文件名 $n传递给脚本或函数的参数.n 是一个数字,表示第几个参数.例如,第一个 ...
- 10个实战及面试常用Linux Shell脚本编写
来自:http://blog.51cto.com/lizhenliang/1929044 注意事项 1)开头加解释器:#!/bin/bash 2)语法缩进,使用四个空格:多加注释说明. 3)命名建议规 ...
- [第十八篇]——Docker 安装 Node.js之Spring Cloud大型企业分布式微服务云架构源码
Docker 安装 Node.js Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境,是一个让 JavaScript 运行在服务端的开发平台. 1.查看可用的 N ...
- electron-vue 开发问题合集
(一)Found 'electron' but not as a devDependency, pruning anyway 原因:对electron没有严格要求的话可以忽略,不影响打包,但会影响第三 ...
- 1004. 最大连续1的个数 III
1004. 最大连续1的个数 III 给定一个由若干 0 和 1 组成的数组 A,我们最多可以将 K 个值从 0 变成 1 . 返回仅包含 1 的最长(连续)子数组的长度. 示例 1: 输入:A = ...