小不的笔记

时间之外的往事

Hibernate dynamic-update dynamic-insert 作用及影响

dynamic-update 可选 默认false UPDATE SQL会在运行时生成且只包括值发生变化的列

dynamic-insert 可选 默认false INSERT SQL会在运行时生成且只包括值不为null的列1

配置方式:

Hibernate3:

@org.hibernate.annotations.Entity(
dynamicUpdate = true,
dynamicInsert = true
)

Hibernate4:

@DynamicUpdate(value=true)
@DynamicInsert(value=true)

性能影响:

Hibernate会为每一个entity缓存它的INSERT/SELECT/UPDATE SQL语句。这样我们在保存、查找、更新entity时,不需要再去动态的计算这些SQL。

然而,当我们使用dynamic-insert、dynamic-update时, Hibernate都要重新计算一次相应的SQL语句,在Hibernate层面会有性能损耗。

所以我们需要在数据库及Hibernate的开销上做权衡。

在我看来,只有表中有庞大的blog列或者有超多的列,dynamic insert、 dynamic update才有意义;否则我不认为它们会带来性能提升。2

使用效果

仅仅提供使用效果,但我不认同其作者对性能影响的评价。

Dynamic-insert

Dynamic-update

  1. http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/mapping.html
  2. http://stackoverflow.com/questions/3404630/hibernate-dynamic-update-dynamic-insert-performance-effects

Java字符串格式化String.Format

每当拼字符串的时候,就会思念C的printf,不过后来才发现Java也实现了类似功能。

示例

代码:String.format("Hello %s, you're the %03d visitor.", "xobo", 7);

输出:Hello xobo, you're the 007 visitor.

默认情况下,参数会依次替换格式说明符。当我们需要重复引用时,就需要对格式说明符进行编号。

代码: String.format("%1$s %1$s %1$s, you are over %2$.2fM tall .", "xobo", 1.0);

输出:xobo xobo xobo, you are over 1.00M tall .

解释

格式说明符

  • %s %03d %1$s %2$.2f等以%开始的字符串被称为格式说明符(format specifiers);

  • 格式说明符的定义为:

    %[argument_index$][flags][width][.precision]conversion_

  • []表示非必填项,也就是说最简单的格式说明符定义为%conversion。

%为格式说明符的起始标志,如果想在字符串中输出%,就需要写成%%;

  • argument_index 可选 是一个整数,它表示参数在参数列表的位置。注意它是从1开始的,第一个参数是1$,第二个参数是2$;

  • flags 可选 是可以改变输出格式的字符。​

    • 如果不提供flag默认格式为:

      • 输出按照width做右对齐
      • 负数以’-‘开始
      • 正数和零不带符号或者前置空格
      • 没有组分隔符​​​

      常用的flag:

      • ‘-‘ 左对齐 (通用)
      • ‘+’ 数字一直带有符号 (数字有效)
      • ‘0’ 用0补空白处 (数字有效)
      • ‘,’
  • width 可选 是一个非负整数​,表示输出的最小字符数。

  • precision 可选 是一个非负整数​,限制输出字符长度。

  • conversion 必填 一个字符,表明参数将如何被格式化。

Dorado、BDF EL表达式

隐式对象

Dorado隐式对象

Dorado共提供了14个隐式对象,我们不需要预先定义就可以直接使用这些隐式对象。

与线程无关

标识符 描述
null 表示null
env 表示获取系统环境变量。${env.JAVA_HOME}或${env[“JAVA_HOME”]}
system Java的系统属性,即System.getProperties()对象。${system.property1}或${system[“property1”]}
configure 用于获取Dorado7的配置信息。${configure[“runMode”]}

与线程有关

标识符 描述
argument 用于获取当前配置文件中的参数值,仅可用于View.xml
context 当前线程中的DoradoContext。
ctx 用于简化对DoradoContext的getAttribute方法的访问。${ctx[“foo”]}相当于${context.getAttribute(“foo”)}
util 基本工具类,见com.bstek.dorado.core.el.ExpressionUtilsObject的javadoc
request 当前的HttpServletRequest对象,与请求作用域属性的名称和值相关联的 Map 类
req 用于简化对request的getAttribute方法的访问。 ${req[“foo”]}相当于${request.getAttribute(“foo”)}

扩展

通过实现 ContextVarsInitializer 接口并通过XML注册到 Spring 上下文,我们就可以添加自定义的隐式对象。
下面一个例子就是注册一个名为dict的隐式对象,通过dict.item('xxx')快捷的调用dictionaryExpressionObject.items('xxx') 并返回结果。

1
2
3
4
5
<bean parent="dorado.expressionVarsInitializerRegister">
<property name="contextInitializer">
<bean class="org.malagu.panda.coke.context.CokeContextVarsInitializer" />
</property>
</bean>
1
2
3
4
5
6
7
8
9
10
11
public class DictionaryContextVarsInitializer implements ContextVarsInitializer {

@Autowired
private DictionaryExpressionObject dictionaryExpressionObject;

@Override
public void initializeContext(Map<String, Object> vars) throws Exception {
vars.put("dict", dictionaryExpressionObject);
}

}
1
2
3
4
5
6
7
8
9
10
@Component
public class DictionaryExpressionObject {

@Autowired
private DictionaryService dictionaryService;

public List<DictionaryItem> items(String code) {
return dictionaryService.getDictionaryItemsBy(code);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package com.bstek.dorado.core.el;

import java.util.Map;

/\*\*
\* EL上下文中隐式变量集合的初始化器。
\* <p>
\* EL上下文中的隐式变量常常被理解为EL表达式的前缀。<br>
\* 例如,假设我们将一个{@link java.util.Date}以<code>Date</code>的前缀放入到隐式变量集合中, 即
\*
\* <pre>
\* vars.put(&quot;Date&quot;, new java.util.Date(););
\* </pre>
\*
\* 。<br>
\* 而后,我们就可以在EL表达式中这样来使用该Date对象了
\*
\* <pre>
\* ${Date.toLocaleString()}
\* </pre>
\*
\* 。
\* </p>
\* @author Benny Bao (mailto:benny.bao@bstek.com)
\* @since Mar 4, 2007
\*/
public interface ContextVarsInitializer {
/\*\*
\* 初始化隐式变量。
\* @param vars 隐式变量映射集合。其中Map的键值为隐式变量的变量名,Map的值为隐式变量自身。
\*/
void initializeContext(Map<String, Object> vars) throws Exception;
}

Reference

DictionaryContextVarsInitializer.java
https://github.com/cellbang/panda/blob/develop/panda-parent/panda-dictionary-ui/src/main/java/org/malagu/panda/dictionary/ui/el/DictionaryContextVarsInitializer.java

Ingress the account xxx@gmail cannot be used

手机科学联网,使用wifi时正常,使用3G的时候就会提示“the account xxx@gmail.com cannot be used”. Ingress运行时,会使用Google账号同步信息,所以我们要保证Google账号同步可用。 我这个情况就是因为流量防火墙禁止了”Google Play服务”在3G下访问网络。 启用之后游戏可以正常运行了。 地址:https://groups.google.com/forum/#!topic/ingress-discuss/E3S6jVMkoTk 源文: We suspect this error occurs for two reasons: 1. [Specified already above] You’re not actively synced to your Google account at the time you launch the app. Visit Menu > Settings > Accounts & sync and make sure your Google account is syncing successfully. You can usually test that sync is on and working by signing into the Google Talk app. 2. A network- or carrier-level issue. For #2, I’d recommend contacting your carrier for troubleshooting/resolution. -Bernini

由SQL where 1=1想到的字符串处理方法

字符串拆成集合简单,集合再合成字符串就有点麻烦. 对于Javascript,一个join方法就可以解决问题,可惜Java的集合没有提供join的方法. 不过强大的Java的三方库提供了类似的功能,例如

//Commons Lang:
org.apache.commons.lang.StringUtils.join(list, conjunction);

//Spring:
org.springframework.util.StringUtils.
collectionToDelimitedString(list, conjunction);

当然也可以自己写一个实现,常见的写法为

public static String join(Collection c, String delim) {
if (c == null c.size()==0) {
return “”;
}
StringBuilder sb = new StringBuilder();
Iterator it = c.iterator();
int i = 0;
while (it.hasNext()) {
if (i++ > 0) {
sb.append(delim);
}
sb.append(it.next());
}
return sb.toString();
}

总觉得循环中的if很别扭,很想把它干掉,于是有了稍稍优雅的写法:

public static String join(String delimiter, Iterable<? extends Object> objs) {
if (objs == null !objs.hasNext()) {
return “”;
}
Iterator<? extends Object> iter = objs.iterator();
StringBuilder buffer = new StringBuilder();
buffer.append(iter.next());
while (iter.hasNext()) {
buffer.append(delimiter).append(iter.next());
}
return buffer.toString();
}

双网卡按指定网卡上网

本机环境: win7 64 场景描述: 在客户公司,可以使用无线网通过http代理上外网,但不能访问内网,有线可以访问内网但是无法访问代理服务器。 代理服务器: 172.16.80.8 需要访问内网数据库:172.16.80.40 有线网网关:192.168.133.254 无线网网关:192.168.127.254 为了实现上外网的同时访问内网数据库,我打起了windows自身的route的主意。 由于代理服务器跟数据库属于同一网段,所以要给他们再划分一下子网。 8,40.我很自然的想到了32. 利用通过主机数计算子网掩码的方法可以得出224,也就是255.255.255.224. 1. 把默认路由删掉。(双网卡,所以有两条默认路由记录) route delete 0.0.0.0 2. 再添加默认路由(如果路由表中没有记录就走这个无线) route add 0.0.0.0 mask 0.0.0.0 192.168.127.254 3. 为数据库添加路由(访问172.16.80.31~172.16.80.63时使用有线) route add 172.16.80.32 mask 255.255.255.224 192.168.133.254 这样就实现同时访问内网数据库及外网。

网页转发及referrer信息

测试环境: Win7 64, IE 9.0, Chrome 21.0.1180.89 m, Firefox 15.0.1 同事制作了一个导航站, 失效点任何链接,都会返回自己的主页,而相同的代码放到本地可以正确导航.由此猜测他的域名被屏蔽了. 这种屏蔽应该是利用浏览器提供的referrer信息以实现的. 只要在网页跳转时把referrer信息清空就好了. 客户端网页跳转方法 1. meta

http://xobo.org”;
or
window.location.replace=”http://xobo.org”;

3. link(a)

jump

方法一,方法二可以轻松在IE及Firefox中, 甩掉referrer信息. 对于Chrome来说, 真是克忠职守,不管我怎么跳转它都记录下正确的referrer信息. 还好Chrome HTML5的rel = “noreferrer”属性, 使浏览器不记录referrer值. 然而IE及Firefox又不支持”noreferrer”这么一属性.把这两种综合一个,就可以了.

卸载千月(BlueSoleil)后,win7 无线网络图标变成红叉叉

蓝牙管理软件本身就不多, windows自身功能又弱, 也就无疑问的尝试了一下千月(BlueSoleil). 但是在一次偶然的卸载操作,千月(BlueSoleil)给我带来了无尽的痛苦–无线网络图标变成红叉叉. 对于功能来说没有任何影响但是就看着那个叉叉不爽, 一定要把它处理掉, 系统还原又被我关掉了. 只能硬处理了. 本以为我卸载了,它出这个叉叉,我再装回去就好了,装回去也不成. 问百度,知道上有人说是重建一下图标缓存.依旧不成. 中文无解去google.com/ncr搜英文,说什么删除设备管理器中的隐藏驱动,依旧无解. … 经无数次尝试均不成, 最后只好重装系统了. 那差不多是年前的事儿了,今天我又手贱的安装了千月(BlueSoleil)又卸载了,红叉叉又出现了,系统还原还是没有开启. 这次发现在千月有用户提出同样的问题,千月的客服回答说这个跟蓝牙个人局域网服务有关, 他们测试的时候没有问题.虽然对问题没有帮助,至少了解到是因为跟什么东西有关了. 继续问Google, 有人说删除驱动就可以了,”将非本地网卡、网线网卡的适配器全部右键卸载掉,可能包括蓝牙、1394、虚拟网卡都逐一卸载掉”.蓝牙的驱动,本地网卡驱动,无线网卡驱动,我早不知删除重装多少遍了.但是虚拟网上的驱动我一直没有动过, 总不会跟这个有关吧. 我本机装有virtualbox及vmware两个虚拟机, 用试试看的方法, 先卸载了virtualbox的网卡驱动. 无线图标闪了闪变了回正常的了.终于好了,再把virtualbox的虚拟网卡安装进来,图标依然正常.重启电脑,也没有复发.原来这个跟虚拟网卡有关. 总结: 1. 永远不要关系统盘的系统还原 2. 尝试卸载虚拟网卡 猜测: 中招的是不是都是virtualBox用户

windows7功能服务慎关闭

Q:windows7开始菜单里的搜索框怎么找回来 A:”控制面板”->”程序”->”程序和功能”->”打开或者关闭windows功能”->选中”Windows Search”,点”确定”保存设置.