看到一篇相当不错的文章,把DBUtils和BeanUtils的用法和区别介绍的相当清楚,特转载分享!
原文地址;http://blog.sina.com.cn/s/blog_14ecbc22a0102wf7i.html
1. BeanUtils 组件
什么是Javabean?
Javabean, 是一个对象(cn.itcat.entity 包下所有的类都是 !
Javabean作用:封装数据/业务
Javabean要满足下面特点:
1. 必须有无参数构造函数
2. get或者set 方法
如何操作javabean?
方式1:
User user = new User();
User.setId(…); 设置值
User.getId(); 获取值
方式2: 反射
操作麻烦!
方式3:
程序中操作javabean,比较频繁! 无处不在!
可以使用apache提供的开源组件: BeanUtils 操作javabean!
BeanUtils 使用 Apache提供简化javabean操作的组件!
组件使用步骤:
1. 下载组件,项目中引入组件(jar)
commons-beanutils-1.8.3.jar
commons-logging-1.1.3.jar
2. (配置)
3. Api (如何使用)
组件使用:
1. 对象属性的拷贝
BeanUtils.copyProperty(user, "id" , id);
2. 对象的拷贝
BeanUtils.copyProperties(newUser, user);
3. map 数据拷贝到对象中
BeanUtils.populate(user, map);
注意:如果项目缺少jar文件,会报错:
java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
// BeanUtils组件
public class App {
// 1. 对象属性的拷贝
@Test
public void test_copyProperties() throws Exception{
// 模拟:从表单中获取的数据
int id=100; // 模拟request.getParameter("id");
String name = "Jack";
double salary = 5000;
// 新操作方式:使用组件
User user = new User();
BeanUtils.copyProperty(user, "id" , id);
BeanUtils.setProperty(user, "name" , name);
BeanUtils.copyProperty(user, "salary" , salary);
System.out.println(user);
}
// 2. 对象的拷贝
@Test
public void test_copyBean() throws Exception{
int id=100; // 模拟request.getParameter("id");
String name = "Jack";
double salary = 5000;
// 对象
User user = new User();
user.setId(id);
user.setName(name);
user.setSalary(salary);
// 新对象
User newUser = new User();
BeanUtils.copyProperties(newUser, user);
System.out.println(newUser);
}
// 3. map 数据拷贝到对象中
@Test
public void test_copyMap2Bean() throws Exception{
// map对象 【Map map = request.getParameterMap();】
Map map = new HashMap();
map.put("id", 1000);
map.put("name", "Jack");
map.put("salary", 1000);
// map拷贝到对象中
User user = new User();
BeanUtils.populate(user, map);
// 测试
System.out.println(user);
}
}
日期类型转换器:
// BeanUtils组件
public class App2 {
//1. 使用提供的日期类型转换器完成日期转换
@Test
public void test_copyProperties() throws Exception{
int id=100;
String name = "Jack";
double salary = 5000;
String birth = "1990-09-09";
User user = new User();
BeanUtils.copyProperty(user, "id", "100");
// 拷贝生日字段: (String 能否自动转换为日期类型?) 不能
//BeanUtils.copyProperty(user, "birth", birth);
// 解决:注册日期类型转换器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
// 再实现String拷贝到Date中
BeanUtils.copyProperty(user, "birth", birth);
System.out.println(user);
}
//2 :自定义日期类型转换器
@Test
public void test_copyProperties2() throws Exception{
int id=100;
String name = "Jack";
double salary = 5000;
// String birth = "1990-09-09"; //OK
String birth = " "; //NOK
// String birth = null; //OK
User user = new User();
BeanUtils.copyProperty(user, "id", "100");
// 解决1:注册日期类型转换器
//ConvertUtils.register(new DateLocaleConverter(), Date.class);
// 解决2:自定义日期类型转换器
ConvertUtils.register(new Converter() {
public Object convert(Class type, Object value) {
// 什么类型的属性需要转换? 日期
if (type != Date.class) {
return null;
}
// 数值判断
if (value == null || "".equals(value.toString().trim())) {
return null;
}
try {
// 转换
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
return sdf.parse(value.toString());
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}, Date.class);
BeanUtils.copyProperty(user, "birth", birth);
System.out.println(user);
}
}
【案例】
需求:如何封装请求数据?
自动封装!
用户名:
薪水:
生日:
public class WebUtils {
public static void copyToBean_back(HttpServletRequest request, User user) {
try {
// 获取请求参数名称
Enumeration enums = request.getParameterNames();
ConvertUtils.register(new DateLocaleConverter(), Date.class);
// 遍历
while (enums.hasMoreElements()) {
// 获取每一个表单元素名称()
String name = enums.nextElement(); // 作为user的属性名称
// 获取对应的值
String value = request.getParameter(name);
// 设置到对象中
BeanUtils.copyProperty(user, name, value);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static T copyToBean(HttpServletRequest request, Class clazz){
try {
// 创建需要封装的对象
T t = clazz.newInstance();
// 日期类型转换器
ConvertUtils.register(new DateLocaleConverter(), Date.class);
// 把请求数据的map,直接拷贝到对象中
BeanUtils.populate(t, request.getParameterMap());
return t;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public class UserServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 方式1:
// 把请求数据,自动封装到javabean中
// User user = new User();
// WebUtils.copyToBean(request,user);
// 方式2:使用泛型优化,便于调用
User user = WebUtils.copyToBean(request,User.class);
// 测试
System.out.println(user);
}
}
2. JDBC中元数据类型
元数据:数据库、表、列的定义信息。
数据库元数据
DatabaseMetaData metaData = con.getMetaData();
参数元数据库
ParameterMetaData pmd = pstmt.getParameterMetaData();
结果集元数据
ResultSetMetaData rmd = rs.getMetaData();
注意:
通过结果集元数据,就可以获取当前执行的sql中的列个数、列名称!
3. 通用操作封装
// 工具类
public class JdbcUtils {
// 数据库连接参数
private static String driverClass = "com.mysql.jdbc.Driver";
private static String url = "jdbc:mysql://localhost:3306/day16";
private static String user = "root";
private static String password = "root";
// 初始化参数 (alt + shift +a )
private static Connection con = null;
private static PreparedStatement pstmt = null;
private static ResultSet rs = null;
public static Connection getConnection(){
try {
Class.forName(driverClass);
return DriverManager.getConnection(url, user, password);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 2. 释放资源
public static void closeAll(Connection con, Statement stmt, ResultSet rs ){
try {
if (rs != null) {
rs.close();
rs = null;
}
if (stmt != null) {
stmt.close();
stmt = null; // 优先会被回收
}
if (con != null) {
con.close();
con = null;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static List query(String sql,Class clazz,Object...paramValues){
// 返回的集合
List list = new ArrayList();
try {
//1. 获取连接
con = JdbcUtils.getConnection();
//2. 创建执行命令的对象
pstmt = con.prepareStatement(sql);
// 设置sql中占位符对应的值
if (paramValues != null && paramValues.length >0) {
// 占位符参数个数
int paramCount = pstmt.getParameterMetaData().getParameterCount();
// 设置每一个参数值
for (int i=0;i
pstmt.setObject(i+1,paramValues[i]);
}
}
//3. 执行查询,得到结果集
rs = pstmt.executeQuery();
// 获取结果集元数据
ResultSetMetaData rmd = rs.getMetaData();
// 列个数
int columnCount = rmd.getColumnCount();
//4. 遍历结果集
while (rs.next()) {
// 创建对象
T obj = clazz.newInstance();
// 遍历结果集中每一行的,每一列
for (int i=0; i
// 获取列名称
String columnName = rmd.getColumnName(i+1);
// 获取列值
Object columnValue = rs.getObject(columnName);
// 把列名称对应的值,设置到对象的属性中! (要求:列名称,要与属性名一样!)
BeanUtils.copyProperty(obj, columnName, columnValue);// 列名称作为属性名称!
}
// 当前对象封装结束, 添加到list中
list.add(obj);
}
return list;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
closeAll(con, pstmt, rs);
}
}
}
Jdbc操作,代码重复比较多!固定步骤!
Apache也提供对jdbc操作简化的组件,DbUtils组件!
4. DbUtils组件
DbUtils, 简化jdbc操作! (JdbcUtils.
Apache提供的开源产品!
使用步骤:
1. 下载组件引入jar文件
commons-dbutils-1.6.jar
2. Api
DbUtils 定义了加载驱动、关闭资源的一些方法
QueryRunner 封装jdbc对数据库的常用操作
|-- QueryRunner
创建方式:
QueryRunner()
Constructor for QueryRunner.
QueryRunner(DataSource ds)
注意:
创建的时候可以传入DataSource对象,如果传入这个对象,使用其下所有方法操作数据库的时候,就不用传入Connection对象; 否则,就需要传入Connection对象!
更新方法:
int update(Connection conn, String sql) 更新, 适合于sql语句没有参数的情况
int update(Connection conn, String sql, Object... params)
更新,可以传入多个参数
int update(Connection conn, String sql, Object param)
更新,传入一个参数
注意:
如果创建QueryRunner 是通过无参数构造器创建,必须传入Connection对象!
int[] batch(Connection conn, String sql, Object[][] params)
批处理操作
查询方法:
T query(Connection conn, String sql, ResultSetHandler rsh)
查询
T query(Connection conn, String sql, ResultSetHandler rsh, Object... params)
查询,带参数查询
|-- interface ResultSetHandler 结果集处理器
T handle(ResultSet rs) 处理方法
1. 自己写结果集处理器, 自己封装结果
关键点:
Class MyClass implements ResultSetHandler
_