从零搭建项目开发框架-09编写BaseDao及其他Dao

在编写dao之前,一定要编写一个BaseDao,封装一下原生的数据库处理方法。这个确实非常有用,比如做Hibernate的时候肯定会有一个BaseHibernateDao,里面封装了增删改查的各个方法,一般一个普通的dao只要继承BaseHibernateDao就不用写什么代码了。

下面也秀一秀封装的BaseDao


/**
 * 基础DAO,用于封装dao操作
 *
 * @author 孔垂云
 * @date 2017-06-13
 */
@Component
public class BaseDao {
    @Autowired
    protected JdbcTemplate jdbcTemplate;
    @Autowired
    protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    /**
     * 新增
     *
     * @param sql
     * @param t
     * @return
     */
    protected int insert(String sql, T t) {
        return namedParameterJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(t));
    }

    /**
     * 新增并返回主键
     *
     * @param sql
     * @param t
     * @param pkField 主键字段
     * @return
     */
    protected int insertForId(String sql, T t, String pkField) {
        KeyHolder keyHolder = new GeneratedKeyHolder();
        int rc = namedParameterJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(t), keyHolder, new String[]{pkField});
        if (rc > 0) {
            return keyHolder.getKey().intValue();
        } else {
            return 0;
        }
    }

    /**
     * 修改,参数为model类
     *
     * @param sql
     * @param t
     * @return
     */
    protected int update(String sql, T t) {
        return namedParameterJdbcTemplate.update(sql, new BeanPropertySqlParameterSource(t));
    }

    /**
     * 按照参数修改
     *
     * @param sql
     * @param objects
     * @return
     */
    protected int update(String sql, Object... objects) {
        return jdbcTemplate.update(sql, objects);
    }

    /**
     * 删除
     *
     * @param sql
     * @param objects
     * @return
     */
    protected int delete(String sql, Object... objects) {
        return jdbcTemplate.update(sql, objects);
    }

    /**
     * 根据参数获取model
     *
     * @param sql
     * @param objects
     * @return
     */
    protected T get(String sql, Object... objects) {
        List list = jdbcTemplate.query(sql, objects, BeanPropertyRowMapper.newInstance(getClazz()));
        if (list.size() > 0)
            return list.get(0);
        else
            return null;
    }

    /**
     * 取得当前泛型的实际class名
     *
     * @return
     */
    private Class getClazz() {
        return ((Class) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0]);
    }

    /**
     * 直接根据sql获取列表
     *
     * @param sql
     * @return
     */
    protected List list(String sql) {
        List list = jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(getClazz()));
        return list;
    }

    /**
     * 根据sql和多参数获取列表
     *
     * @param sql
     * @param objects
     * @return
     */
    protected List list(String sql, Object... objects) {
        List list = jdbcTemplate.query(sql, objects, BeanPropertyRowMapper.newInstance(getClazz()));
        return list;
    }

    /**
     * 根据查询条件获取列表
     *
     * @param sql
     * @param s
     * @return
     */
    protected List list(String sql, S s) {
        List list = namedParameterJdbcTemplate.query(sql, new BeanPropertySqlParameterSource(s), BeanPropertyRowMapper.newInstance(getClazz()));
        return list;
    }

    /**
     * 查询总数,无参数
     *
     * @param sql
     * @return
     */
    protected int count(String sql) {
        return jdbcTemplate.queryForObject(sql, Integer.class);
    }

    /**
     * 查询总数,带参数
     *
     * @param sql
     * @return
     */
    protected int count(String sql, Object... objects) {
        return jdbcTemplate.queryForObject(sql, objects, Integer.class);
    }

    /**
     * 查询总数,带查询对象
     *
     * @param sql
     * @param s
     * @return
     */
    protected int count(String sql, S s) {
        return namedParameterJdbcTemplate.queryForObject(sql, new BeanPropertySqlParameterSource(s), Integer.class);
    }
}

这里面还需要引用一个namedParameterJdbcTemplate,所以需要在Spring的配置文件里面applicationContext.xml里面加入如下配置


    
        
    

BaseDao的原理

1、泛型类,BaseDao是一个泛型类,需要传入两个泛型对象,第一个是实体类,第二个是查询VO类,如果没有第二个,第二个也为实体类。
2、该类里面添加或重写了insert、update、delete、get、list、count等方法,基本满足常见的数据库操作方法。

SysUserDao.java

@Repository
public class SysUserDao extends BaseDao {
    /**
     * 新增用户
     * @param sysUser
     * @return
     */
    public int add(SysUser sysUser) {
        String sql = "insert into t_sys_user(username,password,randomcode,status,realname,mobile,created_at,created_by,role_id)";
        sql += " values(:username,:password,:randomcode,1,:realname,:mobile,sysdate,:createdBy,:roleId)";
        return insertForId(sql, sysUser, "id");
    }

    /**
     * 修改用户
     * @param sysUser
     * @return
     */
    public int update(SysUser sysUser) {
        String sql = "update t_sys_user set realname=:realname,role_id=:roleId,mobile=:mobile,last_modified_by=:lastModifiedBy,last_modified_at=sysdate where id=:id ";
        return update(sql, sysUser);
    }


    /**
     * 修改密码
     *
     * @param id
     * @param newPass
     * @param randowmcode
     * @return
     */
    public int updatePass(int id, String newPass, String randowmcode) {
        String sql = "update t_sys_user set password=?,randomcode=?  where id=? ";
        return update(sql, newPass, randowmcode, id);
    }

    /**
     * 修改个人信息,用户自己操作
     *
     * @param sysUser
     * @return
     */
    public int updateInfo(SysUser sysUser) {
        String sql = "update t_sys_user set realname=:realname,telephone=:telephone where id=:id";
        return update(sql, sysUser);
    }

    /**
     * 修改状态
     *
     * @param id
     * @param status
     * @return
     */
    public int updateStatus(int id, int status) {
        String sql = "update t_sys_user set status=?  where id=?";
        return update(sql, status, id);
    }

    /**
     * 删除用户
     * @param id
     * @return
     */
    public int delete(int id) {
        String sql = "delete from t_sys_user where id=?";
        return delete(sql, id);
    }

    public SysUser get(int id) {
        String sql = "select t.id,t.id,t.username,t.password,t.randomcode,t.status,t.realname,t.mobile,t.created_at,t.created_by,t.role_id,t.last_modified_by,t.last_modified_at from t_sys_user t where id=?";
        return get(sql, id);
    }

    /**
     * 根据username获取sysUser
     *
     * @param username
     * @return
     */
    public SysUser getByUsername(String username) {
        String sql = "select t.id,t.username,t.password,t.randomcode,t.status,t.realname,t.mobile,t.created_at,t.created_by,t.role_id,t.last_modified_by,t.last_modified_at,(select name from t_sys_role where id=role_id) roleName from t_sys_user t where username=?";
        return get(sql, username);
    }

    /**
     * 查询用户信息
     *
     * @param sysUserSearchVO
     * @return
     */
    public List list(SysUserSearchVO sysUserSearchVO) {
        String sql = "select t.id,t.username,t.password,t.randomcode,t.status,t.realname,t.mobile,t.created_at,t.created_by,t.role_id,t.last_modified_by,t.last_modified_at,(select name from t_sys_role where id=t.role_id) roleName  from t_sys_user t where 1=1 ";
        sql += createSearchSql(sysUserSearchVO);
        sql += " order by id asc";
        sql = PageUtil.createMysqlPageSql(sql, sysUserSearchVO.getPageIndex());
        return list(sql, sysUserSearchVO);
    }

    public List listAll() {
        String sql = "select t.id,t.username,t.password,t.randomcode,t.status,t.realname,t.mobile,t.created_at,t.created_by,t.role_id,t.last_modified_by,t.last_modified_at,(select name from t_sys_role where id=role_id) roleName  from t_sys_user t ";
        sql += " order by id asc";
        return list(sql);
    }

    /**
     * 查询用户总数
     *
     * @param sysUserSearchVO
     * @return
     */
    public int count(SysUserSearchVO sysUserSearchVO) {
        String sql = "select count(*) from t_sys_user where 1=1 ";
        sql += createSearchSql(sysUserSearchVO);
        return count(sql, sysUserSearchVO);
    }

    private String createSearchSql(SysUserSearchVO sysUserSearchVO) {
        String sql = "";
        if (StringUtil.isNotNullOrEmpty(sysUserSearchVO.getUsername())) {
            sql += " and username=:username";
        }
        if (StringUtil.isNotNullOrEmpty(sysUserSearchVO.getRealname())) {
            sql += " and realname like :realnameStr";
        }
        if (sysUserSearchVO.getRoleId() != null) {
            sql += " and role_id=:roleId";
        }
        if (sysUserSearchVO.getStatus() != null) {
            sql += " and status=:status";
        }
        return sql;
    }

    /**
     * 所有人员列表,查询日志使用
     *
     * @return
     */
    public List listAllUser() {
        String sql = "select id value,username content from t_sys_user  order by id";
        return listCombobox(sql);
    }
}

说明几点

1、public class SysUserDao extends BaseDao继承BaseDao
2、在PageUtil.java这个类中有公共的Mysql分页方法,只需要写正常的查询语句即可,分页由公共方法来做
3、整个Dao中基本都是sql语句了,所以要规范sql的写法
4、在新增或修改时,数据库字段比如是created_at,实体字段是createdAt,这两个是怎么映射起来的呢?在org.springframework.jdbc.core.BeanPropertyRowMapper类中,spring提供了两种字段映射方法,如果是驼峰写法,可以根据大写的分隔,自动映射至下划线分隔的字段,比如实体字段是createdAt,既可以映射数据库字段createdAt,也可以created_at。
5、编写dao时还用到了几个工具类,比如StringUtil.java里面有判断是否为空的方法。
6、多条件查询sql的写法和mybatis的动态sql写法类似,都是判断该字段是否为空,不为空则拼查询语句。

源码下载

本阶段详细源码

你可能感兴趣的:(从零搭建项目开发框架-09编写BaseDao及其他Dao)