本文隶属于专题系列: 通用数据库访问层dexcoder-dal

注意:本组件已重构并全新发布,更加方便易于使用。代码全部开源,详情访问 Github仓库码云

版本:v2.0.0-beta1

本次对代码进行了彻底的重构,并调整了项目结构,项目命名为dexcoder-dal。

主要更新:

  • 彻底的代码重写
  • Criteria方式针对sql的api调整
  • Criteria中支持sql函数的执行
  • Criteria原生方式sql执行,{}完全原生,[]进行fieldName到columnName转换的原生
  • 支持执行自定义sql
  • 支持使用类似mybatis的方式执行自定义sql

使用上来说变化主要有以下方面:

Criteria方式针对sql的api调整

针对不同的sql封装了不同的方法,对应sql的insertselectupdatedelete,具体见下面代码:

Criteria.insert(User.class).into(...)
Criteria.select(User.class)...
Criteria.update(User.class).set(...)
Criteria.delete(User.class)...

Criteria中支持sql函数的执行

不再以简单的sql拼装的方式来完成想要的操作,提供了更好的扩展,执行函数便是其中之一,记录数count(*)就使用了该方式:

//max()
Criteria criteria = Criteria.select(User.class).addSelectFunc("max([userId])");
Long userId = jdbcDao.queryForObject(criteria);
//count()
Criteria criteria = Criteria.select(User.class).addSelectFunc("count(*)");
Long count = jdbcDao.queryForObject(criteria);
//distinct
Criteria criteria = Criteria.select(User.class).addSelectFunc("distinct [loginName]");
List<Map<String, Object>> mapList = jdbcDao.queryForList(criteria);

默认情况下,addSelectFunc方法返回结果和表字段互斥,并且没有排序,如果需要和表其它字段一起返回并使用排序,可以使用如下代码:

Criteria criteria = Criteria.select(User.class).addSelectFunc("DATE_FORMAT(gmt_create,'%Y-%m-%d %h:%i:%s') date",false,true);
List<Map<String, Object>> mapList = jdbcDao.queryForList(criteria);

Criteria原生方式sql执行

在update和where条件中执行函数可以用{}[]来实现:

Criteria criteria = Criteria.update(User.class).set("[userAge]", "[userAge]+1")
    .where("userId", new Object[] { 56L });
jdbcDao.update(criteria);

以上代码将执行sql:UPDATE USER SET USER*AGE = USER*AGE+1 WHERE USER_ID = ?,[]中的fieldName被转换成了columnName,

也可以使用{}直接写columnName,因为在{}中的内容都是不做任何操作原生执行的,下面代码效果是一样的:

Criteria criteria = Criteria.update(User.class).set("{USER_AGE}", "{USER_AGE + 1}")
    .where("userId", new Object[] { 56L });
jdbcDao.update(criteria);

同理,在where中也可以使用该方式来执行函数:

Criteria criteria = Criteria.select(User.class).where("[gmtCreate]", ">",
    new Object[] { "str_to_date('2015-10-1','%Y-%m-%d')" });
List<User> userList = jdbcDao.queryList(criteria);

支持执行自定义sql

该方式可能会让除了dao层之外的业务层出现sql代码,因此是不推荐的,它适合一些不在项目中的情况。

何为不在项目中的情况?例如做一个开发自用的小工具,临时处理一批业务数据等这类后期不需要维护的代码。

要执行自定义sql首先需要在jdbcDao中注入sqlFactory,这里使用SimpleSqlFactory:

<bean id="jdbcDao" class="com.dexcoder.dal.spring.JdbcDaoImpl">
    <property name="jdbcTemplate" ref="jdbcTemplate"/>
    <property name="sqlFactory" ref="sqlFactory"/>
</bean>
<bean id="sqlFactory" class="com.dexcoder.dal.SimpleSqlFactory">
</bean>

然后就可以直接传入sql执行了:

List<Map<String, Object>> list = jdbcDao.queryForSql("select * from USER where login_name = ?",
    new Object[] { "selfly_a99" });

这个实现比较简单,参数Object数组中不支持复杂的自定义对象。

使用类似mybatis的方式执行自定义sql

同样注入sqlFactory,这里把上面的SimpleSqlFactory替换成BatisSqlFactoryBean

<bean id="jdbcDao" class="com.dexcoder.dal.spring.JdbcDaoImpl">
    <property name="jdbcTemplate" ref="jdbcTemplate"/>
    <property name="sqlFactory" ref="sqlFactory"/>
</bean>
<bean id="sqlFactory" class="com.dexcoder.dal.batis.BatisSqlFactoryBean">
    <property name="sqlLocation" value="user-sql.xml"/>
</bean>

BatisSqlFactoryBean有一个sqlLocation属性,指定自定义的sql文件,因为使用了spring的解析方式,所以可以和指定spring配置文件时一样使用各类通配符。

user-sql.xml是一个和mybatis的mapper类似的xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//dexcoder.com//DTD Mapper 2.0//EN"
        "http://www.ktanx.com/dtd/batis-mapper.dtd">
<mapper namespace="User">
    <sql id="columns">
        user_id,login_name,password,user_age,user_type
    </sql>
    <select id="getUser">
        select
        <include refid="columns"/>
        from user
        <where>
            <if test="params[0] != null">
                user_type = #{params[0].userType}
            </if>
            <if test="params[1] != null">
                and login_name in
                <foreach collection="params[1]" index="index" item="item" separator="," open="(" close=")">
                    #{item}
                </foreach>
            </if>
        </where>
    </select>
</mapper>

然后使用代码调用:

User user = new User();
user.setUserType("1");
Object[] names = new Object[] { "selfly_a93", "selfly_a94", "selfly_a95" };
List<Map<String, Object>> mapList = jdbcDao.queryForSql("User.getUser", "params", new Object[] { user, names });
for (Map<String, Object> map : mapList) {
    System.out.println(map.get("userId"));
    System.out.println(map.get("loginName"));
}

我们调用queryForSql方法时传入了三个参数:

User.getUser 具体的sql全id,namespace+id。 params 自定义sql中访问参数的key,如果不传入默认为item。 Object[] sql中用到的参数。访问具体参数时可以使用item[0],item[1]对应里面相应的元素,支持复杂对象。可以看到这里支持复杂参数,第一个是Userbean对象,第二个是Object数组,至于获取方式可以看上面的xml代码。

除了传入的参数为Object数组并使用item[0]这种方式访问相应的元素外,其它的和mybatis可以说是一样的,mybatis支持的动态sql方式这里也可以支持,因为他本身就是来源于mybatis。

另外返回结果中map的key做了LOGIN_NAME到骆驼命名法loginName的转换。

你可能感兴趣的内容
dexcoder-dal增加表别名支持 收藏,4927 浏览
0条评论

selfly

交流QQ群:32261424
Owner