动态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事务管理

1、DBUtils框架

在使用JDBC开发DAO实现类时,我们要写很多管理PreparedStatementResultSet的代码,还需要手动关闭ConnectionPreparedStatementResultSet资源。

如:给PreparedStatement参数赋值

如:关闭连接

有很多框架可以帮助我们简化DAO代码,比如封装JDBC代码的DBUtils框架,比如ORM框架MyBatisHibernate等。

DBUtilsApache提供的一个对JDBC进行简单封装的开源工具类库,让开发者减少重复代码的编写,能够简化JDBC应用程序的开发。轻量、小巧,贴近JDBC底层,效率较高,不会影响程序的性能。

对于数据表的读操作,可以把结果转换成ListArraySet等集合,便于程序操作。

对于数据表的写操作,也变得很简单(只需写sql语句)。

ORM方面,DBUtils只能进行最简单的ColumnProperty关系映射,不能管理关联关系,没有MyBatisHibernate强大。

2、核心API

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接口的实现,作用是把查询结果集转为对象或对象集合,具体返回值还需要有传入的实现类决定。

3、ResultSetHandler接口

1 public interface ResultSetHandler<T> {
2 
3     T handle(ResultSet rs) throws SQLException;
4 
5 }

4、内置的ResultSetHandler实现

类型

作用

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

获取结果集中第一行数据指定列的值,常用来进行单值查询

5、EmployeeDaoImpl .java

  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 }

优质内容筛选与推荐>>
1、Django框架(二十七)—— ContentType组件
2、电商大数据学习笔记:实战
3、WeakhashMap源码1
4、《当程序员的那些狗日日子》四
5、第四章:JQuery选择器


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn