fastquery 1.0.11 发布了。
fastquery 1.0.11 最新特性:
SQL中的变量用命名式
@Query("select name,age from UserInfo u where u.name = :name or u.age = :age") UserInfo[] findUserInfoByNameOrAge(@Param("name") String name, @Param("age")Integer age);
其中:name对应@Param("name")所指定的方法变量值;:age对应@Param("age")所指定的方法变量值.当然SQL中的变量也可以用?N(N={正整数})的形式来表达,且不用标识@Param.
select name,age from UserInfo u where u.name = :name or u.age = :age
最终会编译成
select name,age from UserInfo u where u.name=? or u.age=?
因此很好地解决了SQL注入问题.
SQL中的变量采用${name}表达式
实现原样替换.不过请注意避免SQL注入问题.
@Query("select * from `userinfo` where ${one} ${orderby}") UserInfo findUserInfo(@Param("orderby") String orderby, @Param("one") int i); // String orderby 这个形参接受到的值会原样取代掉 "${orderby}", orderby 如果接受到的值为null,那么${orderby}默认为"" // int i 接受到的值会取代掉 "${one}" // 假设: orderby的值为: "order by age desc", i的值为:1 // 则: 最终的SQL为: "select * from `userinfo` where 1 order by age desc"
采用${name}时请注意:
传递null值,模板变量默认取""
参数模板仅仅用来辅助开发者构建SQL语句
请堤防使用不当,引发SQL注入问题
请避免模板参数的值完全来源于用户层的输入
请确保参数值可控.
通过defaultVal属性指定:若参数接受到null值,应该采用的默认值(该属性不是必须的,默认为"").例如:
@Query("select * from `userinfo` ${orderby}") // orderby 若为null, 那么 ${orderby}的值,就取defaultVal的值 JSONArray findUserInfo(@Param(value="orderby",defaultVal="order by age desc") String orderby);
@QueryByNamed命名式查询
就是把SQL语句写在配置文件里,然后用@QueryByNamed绑定配置文件中的id值,以便引用到SQL.
配置文件的命名格式:类的长名称(包含包地址).queries.xml,每个类文件对应一个配置文件.
配置文件里的SQL代码段,会被Velocity的模板引擎所渲染,因此,很方便写出复杂的动态SQL语句.
例如:org.fastquery.dao.QueryByNamedDBExample.queries.xml
<?xml version="1.0" encoding="UTF-8"?> <queries> <query id="findUserInfoAll"> select id,name,age from UserInfo </query> <query id="findUserInfoOne"> <value> ## :id 最终会替换成 ? ## ${id} 不会替换还成"?",引用的是参数源值 select id,name,age from UserInfo where id = :id </value> </query> <query id="findUserInfoByNameAndAge"> <value> select id,name,age from UserInfo where 1 #{#condition} </value> <parts> <part name="condition"> #if(${name}) and name = :name #end #if(${age}) and age = :age #end </part> </parts> </query> </queries>
如果想把一些公用的SQL代码片段提取出来,以便重复使用,通过定义<parts>元素(零件集)可以达到效果. 在<value>,<countQuery>元素中,可以通过#{#name}表达式引用到名称相匹配的零件.如:#{#condition}表示引用name="condition"的零件.
public interface QueryByNamedDBExample extends QueryRepository { // 从该类的配置文件里寻找id="findUserInfoAll"节点,然后绑定其SQL代码段 @QueryByNamed("findUserInfoAll") JSONArray findUserInfoAll(); @QueryByNamed("findUserInfoOne") UserInfo findUserInfoOne(@Param("id")Integer id); @QueryByNamed("findUserInfoByNameAndAge") JSONArray findUserInfoByNameAndAge(@Param("name") String name, @Param("age")Integer age); }
分页
通过@QueryByNamed实现分页
<query id="findPage"> <!-- 查询主体语句 --> <value> select no, name, sex from Student where 1 #{#condition} #{#order} </value> <!-- 求和语句 --> <countQuery> select count(no) from Student where 1 #{#condition} </countQuery> <!-- 定义零件集,他们可以被value,countQuery节点引用,以达到复用的效果 --> <parts> <part name="condition"> #if($no) or no like :no #end #if($name) or name like :name #end #if($age) or age > :age #end </part> <part name="order"> order by age desc </part> </parts> </query>
注意: #{#limit}是分页模板的内置零件,表示分页区间,#{#limit}可以放在SQL语句中的任何地方,不过,前提是:必须符合SQL语法.#{#limit}可以不用指定,默认在尾部.
DB接口:
@QueryByNamed("findPage") // 引用id为"findPage"的分页模板 Page<Student> findPage(Pageable pageable, @Param("no") String no, @Param("name") String name,@Param("age") Integer age);
详细文档请参阅: