在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:dexcoder-assistant开源软件地址:https://gitee.com/selfly/dexcoder-assistant开源软件介绍:新版全新重构,更加方便易用,请移步:https://gitee.com/selfly/sonsure-dumper Dexcoder快速开发辅助工具包该通用dal是在开发过程中,对于简单封装的通用dao或数据访问层使用深感痛苦与不便,由此进行了整合和改进发展而来。 如果你不喜欢用 最近更新: 版本 2.3.5 更新时间:2016-06-08
配置动态数据源请看这里:在dexcoder-dal中使用动态数据源并设置读写分离 数据水平分表请看这里:在dexcoder-dal中实现分表数据水平拆分 ##核心组件dexcoder-dal使用说明 dexcoder-dal的一些特性:
命名上遵循了约定优于配置的原则,典型约定如下:
当然,这些你可以在扩展中改变它,但不建议这么做,这本身就是一个良好的规范。 要在项目中使用通用dao十分简单,目前已上maven中央库,直接在pom.xml中添加依赖: <dependency> <groupId>com.dexcoder</groupId> <artifactId>dexcoder-dal-spring</artifactId> <version>${version}</version></dependency> 然后在spring的配置文件中声明如下bean: <bean id="jdbcDao" class="com.dexcoder.dal.spring.JdbcDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"/></bean><!--需要分页时声明--><bean id="pageControl" class="com.dexcoder.dal.spring.page.PageControl"></bean> 接下来就可以注入到您的 ##下面是一些常用的方法示例,这里的 先来看一下 public class User extends Pageable { private Long userId; private String loginName; private String password; private Integer userAge; private String userType; private String email; private Date gmtCreate; //......} Pageable对象,用来保存页码、每页条数信息以支持分页 public class Pageable implements Serializable { /** 每页显示条数 */ protected int itemsPerPage = 20; /** 当前页码 */ protected int curPage = 1; //......} 都是普通的JavaBean对象,下面来看看如何进行具体的增删改查,每种操作都演示了 insert操作Entity方式 User user = new User();user.setLoginName("selfly_a");//......Long userId = jdbcDao.insert(user); Criteria 方式 Criteria criteria = Criteria.insert(User.class).into("loginName", "selfly_b").into("password", "12345678") .into("email", "[email protected]").into("userAge", 22).into("userType", "2").into("gmtCreate", new Date());Long userId = jdbcDao.insert(criteria); save操作,和insert的区别在于不处理主键,由调用者指定Entity方式 User user = new User();user.setUserId(-1L);//......jdbcDao.save(user); Criteria 方式 Criteria criteria = Criteria.insert(User.class).into("userId", -2L).into("loginName", "selfly-2") .into("password", "12345678").into("email", "[email protected]").into("userAge", 22).into("userType", "2") .into("gmtCreate", new Date());jdbcDao.save(criteria); update操作Entity方式 User user = new User();user.setUserId(57L);user.setPassword("abcdef");//方式一 为null的属性值将被忽略jdbcDao.update(user);//方式二 为null的属性值将更新到数据库jdbcDao.update(user,false); Criteria方式 //criteria方式这里的email设为null也将被更新Criteria criteria = Criteria.update(User.class).set("password", "update222").set("email",null) .where("userId", new Object[] { 56L, -1L, -2L });jdbcDao.update(criteria); ###get操作 根据主键 User user = jdbcDao.get(User.class, 63L); Criteria方式//criteria,主要用来指定字段白名单、黑名单等Criteria criteria = Criteria.select(User.class).include("loginName");User user = jdbcDao.get(criteria, 73L); ###delete操作 根据主键 jdbcDao.delete(User.class, 57L); Entity方式 //会把不为空的属性做为where条件User u = new User();u.setLoginName("selfly-1");u.setUserType("1");jdbcDao.delete(u); Criteria方式 //where条件使用了orCriteria criteria = Criteria.delete(User.class).where("loginName", new Object[] { "liyd2" }) .or("userAge", new Object[]{64});jdbcDao.delete(criteria); 列表查询操作所有结果 List<User> users = jdbcDao.queryList(User.class); 以Entity中不为空的属性作为查询条件 User user = new User();user.setUserType("1");//......List<User> users = jdbcDao.queryList(user); Criteria方式,可以指定黑白名单、排序字段等 Criteria criteria = Criteria.select(User.class).exclude("userId") .where("loginName", new Object[]{"liyd"}).asc("userAge").desc("userId");List<User> users = jdbcDao.queryList(criteria); 指定逻辑操作符 //使用了like,可以换成!=、in、not in等Criteria criteria = Criteria.select(User.class).where("loginName", "like", new Object[] { "%liyd%" });user.setUserAge(16);//这里entity跟criteria方式混合使用了,建议少用List<User> users = jdbcDao.queryList(user, criteria.include("userId")); count记录数查询,除了返回值不一样外,其它和列表查询一致//Entity方式user.setUserName("liyd");int count = jdbcDao.queryCount(user);//Criteria方式Criteria criteria = Criteria.select(User.class).where("loginName", new Object[] { "liyd" }) .or("userAge", new Object[]{27});int count = jdbcDao.queryCount(criteria); 查询单个结果,参数使用方式同上//EntityUser user = jdbcDao.querySingleResult(user);//CriteriaCriteria criteria = Criteria.select(User.class).where("loginName", new Object[] { "liyd" }) .and("userId", new Object[]{23L});User u = jdbcDao.querySingleResult(criteria); 指定属性白名单,在任何查询方法中都可以使用//将只返回loginNameCriteria criteria = Criteria.select(User.class).include("loginName");User u = jdbcDao.get(criteria, 23L); 指定属性黑名单,在任何查询方法中都可以使用//将不返回loginNameCriteria criteria = Criteria.select(User.class).exclude("loginName");User u = jdbcDao.get(criteria, 23L); 指定排序//指定多个排序字段,asc、descCriteria criteria = Criteria.select(User.class).exclude("userId") .where("loginName", new Object[]{"liyd"}).asc("userId").desc("userAge");List<User> users = jdbcDao.queryList(criteria); 分页直接传入Entity,继承于 //进行分页,只需要增加这行,列表查询方式跟上面没有任何区别PageControl.performPage(user);//分页后该方法即返回null,由PageControl中获取jdbcDao.queryList(user);Pager pager = PageControl.getPager();//列表List<User> users = pager.getList(User.class);//总记录数int itemsTotal = pager.getItemsTotal(); 直接传入页码和每页大小 //直接传入页码和每页条数PageControl.performPage(1, 10);//使用Criteria方式,并指定排序字段方式为ascCriteria criteria = Criteria.select(User.class).include("loginName", "userId") .where("loginName", new Object[]{"liyd"}).asc("userId");jdbcDao.queryList(criteria);Pager pager = PageControl.getPager(); 使用智能分页解析默认使用的简单分页在数据量较大,在自动做 这时可以选用sql解析的智能分页. 只需要在声明 <bean id="pageControl" class="com.dexcoder.dal.spring.page.PageControl"> <property name="pageSqlHandler" ref="smartPageSqlHandler"/></bean><bean id="smartPageSqlHandler" class="com.dexcoder.dal.spring.page.SmartPageSqlHandler"/> 同时别忘了,使用智能分页需要添加 <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>${jsqlparser.version}</version></dependency> 不同的属性在括号内or的情况:Criteria criteria = Criteria.select(User.class) .where("userType", new Object[] { "1" }).begin() .and("loginName", new Object[] { "selfly" }) .or("email", new Object[] { "[email protected]" }).end() .and("password", new Object[] { "123456" });User user = jdbcDao.querySingleResult(criteria); 执行函数//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);//distinctCriteria criteria = Criteria.select(User.class).addSelectFunc("distinct [loginName]");List<Map<String, Object>> mapList = jdbcDao.queryForList(criteria); 默认情况下, 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); 这是在select中执行函数,那怎么在update和where条件中执行函数呢?前面提到的 看下面代码: Criteria criteria = Criteria.update(User.class).set("[userAge]", "[userAge]+1") .where("userId", new Object[] { 56L });jdbcDao.update(criteria); 以上代码将执行sql: 也可以使用 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); 表别名支持有些时候,就算单表操作也必须用到表别名,例如oracle中的xmltype类型。可以在Criteria中设置表别名: Criteria criteria = Criteria.select(Table.class).tableAlias("t").addSelectFunc("[xmlFile].getclobval() xmlFile") .where("tableId", new Object[]{10000002L});Object obj = jdbcDao.queryForObject(criteria);//对应的sqlselect t.XML_FILE.getclobval() xmlFile from TABLE t where t.TABLE_ID = ? 使用注解可以用注解来指定表名、主键、列名或者忽略某个属性。具体的用法下面代码一看就能明白,唯一需要注意的是注解是在 @Table(name = "USER_A", pkField = "userId", pkColumn = "USER_ID")public class AnnotationUser extends Pageable { /** 用户id */ private Long userId; /** 数据库关键字 */ private String desc; /** 修改时间 数据库无 */ private Date gmtModify; //略... @Column(name = "`DESC`") public String getDesc() { return desc; } @Transient public Date getGmtModify() { return gmtModify; }} 执行自定义sql在实际的应用中,一些复杂的查询如联表查询、子查询等是省不了的。鉴于这类sql的复杂性和所需要的各类优化,通用dao并没有直接封装而是提供了执行自定义sql的接口。 执行自定义sql支持两种方式:直接传sql执行和mybatis方式执行。 ###直接传sql执行 该方式可能会让除了dao层之外的业务层出现sql代码,因此是不推荐的,它适合一些不在项目中的情况。 何为不在项目中的情况?例如做一个开发自用的小工具,临时处理一批业务数据等这类后期不需要维护的代码。 要执行自定义sql首先需要在 <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.queryRowMapListForSql("select * from USER where login_name = ?", new Object[] { "selfly_a99" }); 这个实现比较简单,参数Object数组中不支持复杂的自定义对象。 mybatis方式执行采用了插件式实现,使用该方式首先添加依赖: <dependency> <groupId>com.dexcoder</groupId> <artifactId>dexcoder-dal-batis</artifactId> <version>${version}</version></dependency> 之后同样注入 <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>
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE mapper PUBLIC "-//dexcoder.com//DTD Mapper 2.0//EN" "http://www.dexcoder.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 and params[0].userType != 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.queryRowMapListForSql("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"));} 我们调用
可以看到这里支持复杂参数,第一个是 除了传入的参数为Object数组并使用 另外返回结果中map的key做了 ###项目结构说明 dexcoder-commons 一些通用的工具类,里面的maven依赖可以按需添加。 dexcoder-dal 通用dal的接口,这里对于数据库访问没有具体的实现。具体的数据库操作取决于选择的实现方式(目前只有Spring JdbcTemplate)。 dexcoder-dal-spring Spring JdbcTemplate的dal实现。 dexcoder-dal-batis mybatis方式执行sql实现。 dexcoder-test 测试工程 ###一些说明
JdbcDao在声明时可以根据需要注入其它几个参数: <bean id="jdbcDao" class="com.dexcoder.dal.spring.JdbcDaoImpl"> <property name="jdbcTemplate" ref="jdbcTemplate"/> <property name="sqlFactory" ref="..."/> <property name="mappingHandler" ref="..."/> <property name="rowMapperClass" value="..."/> <property name="dialect" value="..."/></bean>
感谢&相关链接分页部分参考使用了Mybatis通用分页插件: https://github.com/pagehelper/Mybatis-PageHelper 博客:http://www.dexcoder.com/selfly 作者邮箱: [email protected] 交流QQ群: 32261424 |
请发表评论