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操作都 ...
随机推荐
- Git使用教程三
2.远程仓库 线上仓库的操作学习以Github为例 2.1完成线上仓库创建 注意:仓库要求在当前账号下唯一 2.2 两种常规使用方式 2.2.1基于http协议 a.创建空目录,名称就称为shop ...
- git clone 设置临时的 proxy
export ALL_PROXY=socks5://127.0.0.1:1086 git clone --depth 1 https://github.com/xxx/xxx.git unset AL ...
- (二)Superset 1.3图表篇——Time-series Table
(二)Superset 1.3图表篇--Time-series Table 本系列文章基于Superset 1.3.0版本.1.3.0版本目前支持分布,趋势,地理等等类型共59张图表.本次1.3版本的 ...
- Python习题集(十五)
每天一习题,提升Python不是问题!!有更简洁的写法请评论告知我! https://www.cnblogs.com/poloyy/category/1676599.html 题目 请写一个函数,该函 ...
- LayoutControl控件使用
因默认外边距过大需要将外边距缩小用以下代码实现layoutControlGroup1.Padding = DevExpress.XtraLayout.Utils.Padding.Empty;是否允许只 ...
- Vue跨域问题解决
项目根目录下创建vue.config.js module.exports = { devServer: { proxy: { //配置跨域 '/api': { //这里是真实的后台接口 target: ...
- Spring Boot中有多个@Async异步任务时,记得做好线程池的隔离!
通过上一篇:配置@Async异步任务的线程池的介绍,你应该已经了解到异步任务的执行背后有一个线程池来管理执行任务.为了控制异步任务的并发不影响到应用的正常运作,我们必须要对线程池做好相应的配置,防止资 ...
- learn git(远程仓库github)
|由于本地Git仓库和GitHub仓库之间的传输是通过SSH加密的,所以,需要一点设置: 第1步:创建SSH Key.在用户主目录下,看看有没有.ssh目录,如果有,再看看这个目录下有没有id_rsa ...
- xml字符串转成数组(php)
1 $str = '<xml> 2 <ToUserName> <![CDATA[gh_fc0a06a20993]]> </ToUserName> 3 & ...
- Java面向对象系列(11)- instanceof和类型转换
instanceof 先看引用类型的类和instanceof比较的类有没有父子关系,有则可以编译,IDEA不报错 new一个对象,对象new所在的类和instanceof比较的类有没有父子关系,有则为 ...