MyBatis 注意点
#{ } 和 ${ } 的区别
#{ }
表示一个占位符号,通过 #{ }
可以在 preparedStatement 实现向占位符中设置值,自动进行 Java 类型和 Jdbc 类型转换,可以有效防止 SQL 注入。
可以让 #{ }
接收简单类型值或 POJO 属性值(通过 OGNL 读取对象中的值,属性.属性.属性..方式获取对象属性值)。如果在 parameterType 传输单个简单类型值,#{ }
括号中可以是 value 或其它名称。
#{ }
表示一个占位符号,通过 #{ }
可以在 preparedStatement 实现向占位符中设置值,自动进行 Java 类型和 Jdbc 类型转换,可以有效防止 SQL 注入。
可以让 #{ }
接收简单类型值或 POJO 属性值(通过 OGNL 读取对象中的值,属性.属性.属性..方式获取对象属性值)。如果在 parameterType 传输单个简单类型值,#{ }
括号中可以是 value 或其它名称。
基类不同:HashTable 基于 Dictionary 类;HashMap 基于 AbstractMap。
null:HashTable 中的 key 和 value 都不允许为 null;HashMap 允许存在一个 key 为 null 和任意个 value 为 null 的键值对。
线程安全:Hashtable 线程安全;HashMap 线程不安全。同样,线程的安全与否会影响性能。
遍历不同:Hashtable 支持 Iterator 和 Enumeration 两种遍历方式;HashMap 仅支持 Iterator 的遍历方式。
HashMap 不能保证随着时间的推移 Map 中的元素次序是不变的(重新哈希时可能移动元素)。
可以通过下面的语句使得 HashMap 同步:
1 | Map map = Collections.synchronizeMap(hashMap); |
关于 HashMap 线程不安全,《Java并发编程的艺术》中写道:
HashMap 在并发执行 put 操作时会引起死循环,导致 CPU 利用率接近 100%。
因为多线程会导致 HashMap 的 Node 链表形成环形数据结构,一旦形成环形数据结构,Node 的 next 节点永远不为空,就会在获取 Node 时产生死循环。
可以使用自定义的对象作为 key 吗?
可以使用任何对象作为键,只要它遵守了 equals() 和 hashCode() 方法的定义规则,并且当对象插入到 Map 中之后将不会再改变了。
如果需要读 Java 源码,默认点查看读的是 Idea 反编译的文件,没有注释,参数名也被简化了。
所以如果需要更好的读源码,需要添加 src.zip 源码包。
从搜索结果看,都说是直接添加 JDK 目录下的 src.zip,但是我的 JDK8 怎么都找不到。只好去官网下载整个 JDK,然后拿出我想要的源码包。
JDK8 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
里面有 src.zip 源码包,放到 JDK 目录下。
如果 Idea 读取的 SDK 就是你当前使用的 JDK 版本,它会自动帮你添加。
File => Project Structure => SDKs,将 JDK 设置成刚才的 JDK 目录。
单点登录(Single Sign On)严格上来说和 OAuth2 没太大关系,只是 SSO 可以通过 OAuth2 实现。本文延续 OAuth2 初识的模式,看完原理写 Demo,在上一个 Demo 的基础上加以改造。
认证中心仍然是 QQ,然后子系统是 QQ 邮箱 + QQ 游戏,两个子系统除了配置上有少许差别外,基本一样。
代码:GitHub
原理参考单点登录原理,内容上有删改。
前提知识:
OAuth2 可以方便第三方应用获取用户在其他应用的信息。
比如用 QQ 账户登录优酷,优酷就会先让用户登录 QQ,然后让用户确认授权优酷访问 QQ 上的信息,确认后优酷就获得了 QQ 的 OAuth 服务器返回的 token,之后就可以通过 token 访问到权力范围内的用户相关信息。
共同点:装配 Bean,写在字段或 setter 方法上。
@Autowired
Spring 的注解,来自 org.springframework.beans.factory.annotation.Autowired
默认按类型装配,也可以使用名称装配,但要配合 @Qualifier 注解。
依赖对象必须存在,如果要允许 null 值,可以设置 @Autowired(required=false)