在编写dao之前,一定要编写一个BaseDao,封装一下原生的数据库处理方法。这个确实非常有用,比如做Hibernate的时候肯定会有一个BaseHibernateDao
,里面封装了增删改查的各个方法,一般一个普通的dao只要继承BaseHibernateDao
就不用写什么代码了。
下面也秀一秀封装的BaseDao
/**
* 基础DAO,用于封装dao操作
*
* @author 孔垂云
* @date 2017-06-13
*/
@Component
public class BaseDao<T, S> {
@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<T> list = jdbcTemplate.query(sql, objects, BeanPropertyRowMapper.newInstance(getClazz()));
if (list.size() > 0)
return list.get(0);
else
return null;
}
/**
* 取得当前泛型的实际class名
*
* @return
*/
private Class<T> getClazz() {
return ((Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0]);
}
/**
* 直接根据sql获取列表
*
* @param sql
* @return
*/
protected List<T> list(String sql) {
List<T> list = jdbcTemplate.query(sql, BeanPropertyRowMapper.newInstance(getClazz()));
return list;
}
/**
* 根据sql和多参数获取列表
*
* @param sql
* @param objects
* @return
*/
protected List<T> list(String sql, Object... objects) {
List<T> list = jdbcTemplate.query(sql, objects, BeanPropertyRowMapper.newInstance(getClazz()));
return list;
}
/**
* 根据查询条件获取列表
*
* @param sql
* @param s
* @return
*/
protected List<T> list(String sql, S s) {
List<T> 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里面加入如下配置
<!--注入namedParameterJdbcTemplate -->
<bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
BaseDao的原理
1、泛型类,BaseDao是一个泛型类,需要传入两个泛型对象<T S>
,第一个是实体类,第二个是查询VO类,如果没有第二个,第二个也为实体类。
2、该类里面添加或重写了insert、update、delete、get、list、count
等方法,基本满足常见的数据库操作方法。
SysUserDao.java
@Repository
public class SysUserDao extends BaseDao<SysUser, SysUserSearchVO> {
/**
* 新增用户
* @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<SysUser> 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<SysUser> 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<ComboboxVO> listAllUser() {
String sql = "select id value,username content from t_sys_user order by id";
return listCombobox(sql);
}
}
说明几点
1、public class SysUserDao extends BaseDao<SysUser, SysUserSearchVO>
继承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写法类似,都是判断该字段是否为空,不为空则拼查询语句。
网友评论