动态SQL数据层框架(1):DBUtils框架基础
这是一个简单的数据层框架,可以实现动态SQL查询、自动化事务管理、IOC和依赖注入,使用了以下技术:
1) Maven管理依赖,Github托管代码 2) DBUtils框架作为JDBC底层框架 3) JDK动态代理实现的AOP 4) 注解 5) Freemarker来做动态SQL模板的解析 6) 工厂设计模式 7) 反射和XML解析
从使用方式开始介绍,逐步深入地去理解框架的各个知识点。
框架主要分为两部分:
1) dynamic-sql-dao是框架主体
2) dynamic-sql-dao-test是一个demo含有测试用例
本文将简单介绍一下DBUtils框架。
Github地址
https://github.com/xuguofeng/dynamic-sql-dao
https://github.com/xuguofeng/dynamic-sql-dao-test
文章目录
动态SQL数据层框架(0):一个基于FreeMarker和DBUtils的动态SQL框架
动态SQL数据层框架(1):DBUtils框架基础
动态SQL数据层框架(2):框架结构
动态SQL数据层框架(3):BaseDao接口和BaseDaoSupport抽象类
动态SQL数据层框架(4):DynamicSQLParser工具类和配置文件
动态SQL数据层框架(5):AOP事务管理
在使用JDBC开发DAO实现类时,我们要写很多管理PreparedStatement、ResultSet的代码,还需要手动关闭Connection、PreparedStatement、ResultSet资源。
如:给PreparedStatement参数赋值
如:关闭连接
有很多框架可以帮助我们简化DAO代码,比如封装JDBC代码的DBUtils框架,比如ORM框架MyBatis、Hibernate等。
DBUtils是Apache提供的一个对JDBC进行简单封装的开源工具类库,让开发者减少重复代码的编写,能够简化JDBC应用程序的开发。轻量、小巧,贴近JDBC底层,效率较高,不会影响程序的性能。
对于数据表的读操作,可以把结果转换成List、Array、Set等集合,便于程序操作。
对于数据表的写操作,也变得很简单(只需写sql语句)。
在ORM方面,DBUtils只能进行最简单的Column—Property关系映射,不能管理关联关系,没有MyBatis、Hibernate强大。
QueryRunner类
执行SQL查询、处理ResultSets结果集。这个类是线程安全的。
要介绍两个构造方法:一个无参,一个需要传入一个DataSource参数。推荐使用无参构造方法,因为尽量我们自己管理连接(获取、事务和关闭)而不是让DBUtils去管理连接。
在后面学习动态代理、AOP和注解技术的时候,我们将在代理类中控制连接的获取、事务和关闭,而不再需要写在DAO实现里面。
主要使用两个方法:
1 public int update(Connection conn, String sql, Object... params) throws SQLException { 2 return ...... 3 } 4 5 public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException { 6 return ...... 7 }
对于查询方法,需要传入一个ResultSetHandler接口的实现,作用是把查询结果集转为对象或对象集合,具体返回值还需要有传入的实现类决定。
1 public interface ResultSetHandler<T> { 2 3 T handle(ResultSet rs) throws SQLException; 4 5 }
类型 |
作用 |
ArrayHandler |
把结果集中的第一行数据转成对象数组 |
ArrayListHandler |
把结果集中的每一行数据都转成一个对象数组,再存放到List中 |
BeanHandler |
将结果集中的第一行数据封装到一个对应的JavaBean实例中 |
BeanListHandler |
将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里 |
MapHandler |
将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值 |
MapListHandler |
将结果集中的每一行数据都封装到一个Map里,然后再存放到List |
ColumnListHandler |
将结果集中某一列的数据存放到List中 |
KeyedHandler(name) |
将结果集中的每一行数据都封装到一个Map里(List<Map>),再把这些map再存到一个map里,其key为指定的列 |
ScalarHandler |
获取结果集中第一行数据指定列的值,常用来进行单值查询 |
1 public class EmployeeDaoImpl implements EmployeeDao { 2 3 @Override 4 public boolean addEmployee(Employee e) { 5 6 QueryRunner qr = new QueryRunner(); 7 8 String sql = "insert into oa_employee (name,gender,salary,phone,email,birthday,join_date,dept_id,description,create_time) values (?,?,?,?,?,?,?,?,?,?)"; 9 10 Connection conn = null; 11 12 try { 13 conn = DBUtil.getConnection(); 14 15 conn.setAutoCommit(false); 16 17 int row = qr.update(conn, sql, e.getName(), e.getGender(), e 18 .getSalary(), e.getPhone(), e.getEmail(), 19 new java.sql.Date(e.getBirthday().getTime()), 20 new java.sql.Date(e.getJoinDate().getTime()), e 21 .getDepartment().getId(), e.getDescription(), 22 new Timestamp(e.getCreateTime().getTime())); 23 24 conn.commit(); 25 return row == 1; 26 27 } catch (SQLException e1) { 28 try { 29 conn.rollback(); 30 } catch (SQLException e2) { 31 } 32 e1.printStackTrace(); 33 } finally { 34 try { 35 DbUtils.close(conn); 36 } catch (SQLException e1) { 37 } 38 } 39 return false; 40 } 41 42 @Override 43 public boolean updateEmployee(Employee e) { 44 45 QueryRunner qr = new QueryRunner(); 46 47 String sql = "update oa_employee set name=?,gender=?,salary=?,phone=?,email=?,birthday=?,join_date=?,dept_id=?,description=? where id=?"; 48 49 Connection conn = null; 50 51 try { 52 conn = DBUtil.getConnection(); 53 54 conn.setAutoCommit(false); 55 56 int row = qr.update(conn, sql, e.getName(), e.getGender(), e 57 .getSalary(), e.getPhone(), e.getEmail(), 58 new java.sql.Date(e.getBirthday().getTime()), 59 new java.sql.Date(e.getJoinDate().getTime()), e 60 .getDepartment().getId(), e.getDescription(), e 61 .getId()); 62 63 conn.commit(); 64 return row == 1; 65 66 } catch (SQLException e1) { 67 try { 68 conn.rollback(); 69 } catch (SQLException e2) { 70 } 71 e1.printStackTrace(); 72 } finally { 73 try { 74 DbUtils.close(conn); 75 } catch (SQLException e1) { 76 } 77 } 78 return false; 79 } 80 81 @Override 82 public boolean deleteEmployee(Integer id) { 83 84 QueryRunner qr = new QueryRunner(); 85 86 String sql = "delete from oa_employee where id=?"; 87 88 Connection conn = null; 89 90 try { 91 conn = DBUtil.getConnection(); 92 93 conn.setAutoCommit(false); 94 95 int row = qr.update(conn, sql, id); 96 97 conn.commit(); 98 return row == 1; 99 100 } catch (SQLException e1) { 101 try { 102 conn.rollback(); 103 } catch (SQLException e) { 104 } 105 e1.printStackTrace(); 106 } finally { 107 try { 108 DbUtils.close(conn); 109 } catch (SQLException e) { 110 } 111 } 112 return false; 113 } 114 115 @Override 116 public int deleteEmployees(Integer[] ids) { 117 118 if (ids == null || ids.length == 0) { 119 return 0; 120 } 121 122 Object[] params = new Object[ids.length]; 123 124 StringBuilder sql = new StringBuilder( 125 "delete from oa_employee where id in ("); 126 int max = ids.length - 1; 127 128 for (int i = 0;; i++) { 129 sql.append("?"); 130 params[i] = ids[i]; 131 if (i == max) { 132 sql.append(")"); 133 break; 134 } 135 sql.append(","); 136 } 137 138 QueryRunner qr = new QueryRunner(); 139 140 Connection conn = null; 141 142 try { 143 conn = DBUtil.getConnection(); 144 145 conn.setAutoCommit(false); 146 147 int row = qr.update(conn, sql.toString(), params); 148 149 conn.commit(); 150 return row; 151 152 } catch (SQLException e1) { 153 try { 154 conn.rollback(); 155 } catch (SQLException e) { 156 e.printStackTrace(); 157 } 158 } finally { 159 try { 160 DbUtils.close(conn); 161 } catch (SQLException e) { 162 } 163 } 164 return 0; 165 } 166 167 @Override 168 public Employee getEmployee(Integer id) { 169 170 String sql = "select a.id,a.name,a.gender,a.salary,a.phone,a.email,a.birthday,a.join_date,a.description,a.create_time,b.id,b.name,b.description,b.create_time from oa_employee a,oa_department b where a.dept_id=b.id and a.id=?"; 171 172 QueryRunner qr = new QueryRunner(); 173 174 Connection conn = null; 175 176 try { 177 conn = DBUtil.getConnection(); 178 return qr.query(conn, sql, new ResultSetHandler<Employee>() { 179 @Override 180 public Employee handle(ResultSet rs) throws SQLException { 181 if (rs.next()) { 182 return rowMapping(rs); 183 } 184 return null; 185 } 186 }, id); 187 } catch (SQLException e1) { 188 e1.printStackTrace(); 189 } finally { 190 try { 191 DbUtils.close(conn); 192 } catch (SQLException e) { 193 } 194 } 195 return null; 196 } 197 198 @Override 199 public List<Employee> getEmployees(Integer pageNum, Integer pageSize) { 200 201 String sql = "select a.id,a.name,a.gender,a.salary,a.phone,a.email,a.birthday,a.join_date,a.description,a.create_time,b.id,b.name,b.description,b.create_time from oa_employee a,oa_department b where a.dept_id=b.id limit ?,?"; 202 203 QueryRunner qr = new QueryRunner(); 204 205 Connection conn = null; 206 try { 207 conn = DBUtil.getConnection(); 208 return qr.query(conn, sql, new ResultSetHandler<List<Employee>>() { 209 @Override 210 public List<Employee> handle(ResultSet rs) throws SQLException { 211 List<Employee> emps = new ArrayList<Employee>(); 212 while (rs.next()) { 213 Employee emp = rowMapping(rs); 214 emps.add(emp); 215 } 216 return emps; 217 } 218 }, (pageNum - 1) * pageSize, pageSize); 219 } catch (SQLException e1) { 220 e1.printStackTrace(); 221 } finally { 222 try { 223 DbUtils.close(conn); 224 } catch (SQLException e) { 225 } 226 } 227 return null; 228 } 229 230 @Override 231 public int count() { 232 233 String sql = "select count(*) from oa_employee"; 234 235 Connection conn = null; 236 237 QueryRunner qr = new QueryRunner(); 238 239 try { 240 conn = DBUtil.getConnection(); 241 return qr.query(conn, sql, new ScalarHandler<Long>(1)).intValue(); 242 } catch (SQLException e1) { 243 e1.printStackTrace(); 244 } finally { 245 try { 246 DbUtils.close(conn); 247 } catch (SQLException e) { 248 } 249 } 250 return 0; 251 } 252 253 private Employee rowMapping(ResultSet rs) throws SQLException { 254 Employee emp = new Employee(); 255 256 emp.setId(rs.getInt(1)); 257 emp.setName(rs.getString(2)); 258 emp.setGender(rs.getInt(3)); 259 emp.setSalary(rs.getDouble(4)); 260 emp.setPhone(rs.getString(5)); 261 emp.setEmail(rs.getString(6)); 262 emp.setBirthday(rs.getDate(7)); 263 emp.setJoinDate(rs.getDate(8)); 264 emp.setDescription(rs.getString(9)); 265 emp.setCreateTime(rs.getTimestamp(10)); 266 267 Department dept = new Department(); 268 dept.setId(rs.getInt(11)); 269 dept.setName(rs.getString(12)); 270 dept.setDescription(rs.getString(13)); 271 dept.setCreateTime(rs.getTimestamp(14)); 272 273 emp.setDepartment(dept); 274 275 return emp; 276 } 277 }优质内容筛选与推荐>>