BeanUtils 和 DBUtils

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
_
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章