Month: April 2014

mysql – 只对一个字段做distinct

要在所有用户记录中做一次普通的查询,要求返回的结果中,对某一个“姓”只有一条记录。 比如,你的数据是这样 引用 ln  fn   陈  东 胡  西 陈  南 刘  北 我希望查出的是 引用 ln  fn 陈  东   // 或  “陈  南”,总之只返回一个姓陈的 胡  西 刘  北 sql要这样写: select * from user group by ln

mysql – 让in查询的结果按in参数列表排序

select * from t where id in (3,1,2) 结果可能是 1, xxx 2, xxx 3, xxx 或者其它,反正不确定 select * from t where id in (3,1,2) order by field(t.id 3, 1, 2) 就可以确定得到这样的排序结果 3, xxx 1, xxx 2, xxx 在ibatis里这样写: <select id="someSql" parameterClass="list" resultMap="resultMap"> select * from t where id in <iterate open="(" close=")" conjunction=","> #[]# </iterate> …

mysql – 让in查询的结果按in参数列表排序 Read More »

代码片断:安全的subList()方法

/** * 从类集中找到前几个元素,组成新的类集再返回。 <br/> * 1. 如果想要的元素个数超过了类集的大小,则返回该类集中的所有元素组成的类集 <br/> * 2. 原类集对象不会被修改<br/> * 3. 返回ArrayList,它可能为empty,但不会是null<br/> * * @param list * @param elementCount * 想要的元素个数; 如果个数不是正数,则返回空list * @return */ public static <T> ArrayList<T> selectTopElements(List<T> list, int elementCount) { ArrayList<T> resultList = new ArrayList<T>(); if (list == null) { return resultList; } if (elementCount <= 0) { return resultList; …

代码片断:安全的subList()方法 Read More »

逻辑删除一条记录时,最好删除相关的关系表中的记录

逻辑删除一条记录时,最好删除相关的关系表中的记录。 如果不这样做,会导致没必要的连接,在极端情况下会出现极其糟糕的性能。 今天就遇到这样一个实例。 有两个表,分别叫a表和b表,它们之间有一张a_b关系表, a可以逻辑删除。要查找b=123关联的前10个a记录,需要这样关联: select a.a_id from a_b join a on a_b.a_id = a.a_id where a_b.b_id = 123 and a.deleted = 0 order by a.a_id limit 0, 10 — a.deleted = 0 代表未删除 一般情况下,我们预期它会先根据a_b.b_id = 123找出相关的a_id,然后再根据a_id从a表中过滤中deleted = 0的记录。 然而今天发现一个奇怪的情况,如果b关联的a记录很多时,它会先按 deleted = 0扫描整个a表(deleted上有索引),然后再与a_b关联。性能极差。 数据的分布对执行计划的影响是很难捉摸的,最好的办法就是不做关联。 所以我们可以这样,当逻辑删除a记录时,清除a_b中的关系记录。这样就不用连接了: select a_b.a_id from a_b where a_b.b_id = 123 order by …

逻辑删除一条记录时,最好删除相关的关系表中的记录 Read More »

ibatis里存取enum类型

enum类型不是标准的jdbcType, 所以你要使用 type handler配置一下映射。数据库里使用varchar类型,存储enum字段的name . /** * ibatis内置了一个EnumTypeHandler, * 但它没有无参构造函数,直接使用它会导致java.lang.InstantiationException, 所以你要另建一个类,提供一个无参构造函数,并利用装饰器模式集成EnumTypeHandler的功能。 * ibatis内置的EnumTypeHandler还有一个缺点: 对于数据库里存储的脏数据即不在指定enum * name范围之内的数据,EnumTypeHandler在运行时会直接报异常; 但在一般的应用场景下,我们希望把这些脏数据解析成null就可以了。 * 所以,我们的新类里应该在这方面提供健壮性。 * * 用法:对每个具体的枚举,请继承一下本类 * * @author kent * */ @SuppressWarnings(“rawtypes”) public abstract class MyEnumTypeHandler extends BaseTypeHandler implements TypeHandler { private EnumTypeHandler delegate; public MyEnumTypeHandler() { Class type = this.getEnumType(); delegate = new EnumTypeHandler(type); } public abstract …

ibatis里存取enum类型 Read More »

关于unicode中的bmp

最早版本的unicode所允许的值是 U+0000 to U+FFFF 后来unicode扩充了,取值范围变成了U+0000 to U+10FFFF . 原先的 U+0000 to U+FFFF这个集合就称作BMP (Basic Multilingual Plane) 这个集合也是mysql utf8_general字符集所能支持的集合(三个字节); 所以,java在插入文字之前应该过滤掉non-bmp字符。 public static String removeNonBmpUnicode(String str) { if (str == null) { return null; } str = str.replaceAll("[^\\u0000-\\uFFFF]", ""); return str; } BMP之外的字符集合称为"supplementary characters". 由于Java里每个char都是用16位来表示的,一个supplementary character在java里就要用两个特殊的bmp字符来表示。这类特殊的bmp字符分别称作high-surrogates(\uD800-\uDBFF) 和 low-surrogates(\uDC00-\uDFFF). 要注意的是,把surrogates用在java6的正则中时,得到的结果会让人很意外: //\ud83d\udd12是一个unicode单字(”锁“的形状) "\ud83d\udd12".matches("\ud83d\udd12") == true //这个好理解 "\ud83d\udd12".matches("\\ud83d\\udd12") == false //为什么?java.util.regex.Pattern的javadoc不是说 …

关于unicode中的bmp Read More »

转:为spring mvc加上csrf防范的简单方案

官方文档建议你引入spring security,然后用一行简单的xml配置就可以搞定csrf防范。 但是引入spring security意味着你必须使用它的一套authentication & authorization机制,而且这玩意儿也不轻量。 网上搜了下,下面这个方案简单又可靠,你抄一些它的代码即可: http://blog.eyallupu.com/2012/04/csrf-defense-in-spring-mvc-31.html ======= 以上只对普通form提交方式有效 对于ajax方式,可以在页面任何一处写一个<form:form/>,就可以在页面源码中生成这样一个token; ajax在提交时,把这个token作为post的内容提交就可以了

单个数据库操作RT较大的原因

可能的原因: 1. sql未调优,比如没有走索引 2. 读写数据过多 3. 当前并发过高,DB已经吃不消 4. 并发锁 5. Java/Php程序中的连接池已经耗尽,新操作需要等待 待续 。。。