1. 程式人生 > >基於JDBC 的資料庫返回資料Resultset 資料繫結到Javabean

基於JDBC 的資料庫返回資料Resultset 資料繫結到Javabean

由於jdbc連線所有hibernate等都不能用,也不想用暴力的get/set 方法逐項新增儲存為臨時Javabean,所以可以採用反射和註解,一下為反射機制

package com.util;


import java.lang.reflect.Field;  
import java.lang.reflect.Method;  
import java.sql.ResultSet;  
import java.sql.ResultSetMetaData;  
import java.util.ArrayList;  
import java.util.List;  

/**
 * 
 * @author Administrator
 *@說明:利用反射機制從ResultSet自動繫結到JavaBean;根據記錄集自動呼叫javaBean裡邊的對應方法。
 * @param <T>
 */
public class ResultToBeanUtil<T> {
 
	    /** 
	     * @param clazz 
	     *            所要封裝的javaBean 
	     * @param rs 
	     *            記錄集 
	     * @return ArrayList 數組裡邊裝有 多個javaBean 
	     * @throws Exception 
	     */  
	    public List<T> getList(Class<T> clazz, ResultSet rs) {  
	        Field field = null;  
	        List<T> lists = new ArrayList<T>();  
	        try {  
	            // 取得ResultSet列名  
	            ResultSetMetaData rsmd = rs.getMetaData();  
	            // 獲取記錄集中的列數  
	            int counts = rsmd.getColumnCount();  
	            // 定義counts個String 變數  
	            String[] columnNames = new String[counts];  
	            // 給每個變數賦值(欄位名稱全部轉換成大寫)  
	            for (int i = 0; i < counts; i++) {  
	                columnNames[i] = rsmd.getColumnLabel(i + 1).toUpperCase(); 
	            }  
	            // 變數ResultSet  
	            while (rs.next()) {  
	                T t = clazz.newInstance();  
	                // 反射, 從ResultSet繫結到JavaBean  
	                for (int i = 0; i < counts; i++) {  
	  
	                    // 設定引數型別,此型別應該跟javaBean 裡邊的型別一樣,而不是取資料庫裡邊的型別  
	                    field = clazz.getDeclaredField(columnNames[i]);  
	  
	                    // 這裡是獲取bean屬性的型別  
	                    Class<?> beanType = field.getType();  
	  
	                    // 根據 rs 列名 ,組裝javaBean裡邊的其中一個set方法,object 就是資料庫第一行第一列的資料了  
	                    Object value = rs.getObject(columnNames[i]);  
	  
	                    if (value != null) {  
	  
	                        // 這裡是獲取資料庫欄位的型別  
	                        Class<?> dbType = value.getClass();  
	  
	                        // 處理日期型別不匹配問題  
	                        if (dbType == java.sql.Timestamp.class  
	                                && beanType == java.util.Date.class) {  
	                            // value = new  
	                            // java.util.Date(rs.getTimestamp(columnNames[i]).getTime());  
	                            value = new java.util.Date(  
	                                    ((java.sql.Timestamp) value).getTime());  
	                        }  
	                        // 處理double型別不匹配問題  
	                        if (dbType == java.math.BigDecimal.class  
	                                && beanType == double.class) {  
	                            // value = rs.getDouble(columnNames[i]);  
	                            value = new Double(value.toString());  
	                        }  
	                        // 處理int型別不匹配問題  
	                        if (dbType == java.math.BigDecimal.class  
	                                && beanType == int.class) {  
	                            // value = rs.getInt(columnNames[i]);  
	                            value = new Integer(value.toString());  
	                        }  
	                    }  
	  
	                    String setMethodName = "set"  
	                            + columnNames[i];  
	                    // 第一個引數是傳進去的方法名稱,第二個引數是 傳進去的型別;  
	                    Method m = t.getClass().getMethod(setMethodName, beanType);  
	  
	                    // 第二個引數是傳給set方法資料;如果是get方法可以不寫  
	                    m.invoke(t, value);  
	                }  
	                lists.add(t);  
	            }  
	        } catch (Exception e) {  
	            e.printStackTrace();  
	            return null;  
	        }  
	        return lists;  
	    }  
	  
	    /** 
	     * @param clazz 
	     *            bean類 
	     * @param rs 
	     *            結果集 (只有封裝第一條結果) 
	     * @return 封裝了查詢結果的bean物件 
	     */  
	    public T getObj(Class<T> clazz, ResultSet rs) {  
	        Field field = null;  
	        T obj = null;  
	        try {  
	            // 取得ResultSet列名  
	            ResultSetMetaData rsmd = rs.getMetaData();  
	            // 獲取記錄集中的列數  
	            int counts = rsmd.getColumnCount();  
	            // 定義counts個String 變數  
	            String[] columnNames = new String[counts];  
	            // 給每個變數賦值(欄位名稱全部轉換成大寫)  
	            for (int i = 0; i < counts; i++) {  
	                columnNames[i] = rsmd.getColumnLabel(i + 1).toUpperCase();  
	            }  
	            // 變數ResultSet  
	            if (rs.next()) {  
	                T t = clazz.newInstance();  
	                // 反射, 從ResultSet繫結到JavaBean  
	                for (int i = 0; i < counts; i++) {  
	                    try{  
	                    // 設定引數型別,此型別應該跟javaBean 裡邊的型別一樣,而不是取資料庫裡邊的型別  
	                    field = clazz.getDeclaredField(columnNames[i]);  
	                    }catch(Exception ex){  
	                        ex.printStackTrace();  
	                        continue;  
	                    }  
	  
	                    // 這裡是獲取bean屬性的型別  
	                    Class<?> beanType = field.getType();  
	  
	                    // 根據 rs 列名 ,組裝javaBean裡邊的其中一個set方法,object 就是資料庫第一行第一列的資料了  
	                    Object value = rs.getObject(columnNames[i]);  
	  
	                    if (value != null) {  
	  
	                        // 這裡是獲取資料庫欄位的型別  
	                        Class<?> dbType = value.getClass();  
	                        // 處理日期型別不匹配問題  
	                        if (dbType == java.sql.Timestamp.class  
	                                && beanType == java.util.Date.class) {  
	                            // value = new  
	                            // java.util.Date(rs.getTimestamp(columnNames[i]).getTime());  
	                            value = new java.util.Date(  
	                                    ((java.sql.Timestamp) value).getTime());  
	                        }  
	                        // 處理double型別不匹配問題  
	                        if (dbType == java.math.BigDecimal.class  
	                                && beanType == double.class) {  
	                            // value = rs.getDouble(columnNames[i]);  
	                            value = new Double(value.toString());  
	                        }  
	                        // 處理int型別不匹配問題  
	                        if (dbType == java.math.BigDecimal.class  
	                                && (beanType == int.class || beanType == Integer.class)) {  
	                            // value = rs.getInt(columnNames[i]);  
	                            value = new Integer(value.toString());  
	                        }  
	                        
	                        if (dbType == java.math.BigDecimal.class  
	                                && beanType == String.class) {  
	                            // value = rs.getInt(columnNames[i]);  
	                            value = new Integer(value.toString())+"";  
	                        } 
	                    }  
	  
	                    String setMethodName = "set"  
	                            +columnNames[i];  
	                    // 第一個引數是傳進去的方法名稱,第二個引數是 傳進去的型別;  
	                    Method m = t.getClass().getMethod(setMethodName, beanType);  
	  
	                    // 第二個引數是傳給set方法資料;如果是get方法可以不寫  
	                    m.invoke(t, value);  
	                }  
	                obj = t;  
	            }  
	        } catch (Exception e) {  
	            e.printStackTrace();  
	            return null;  
	        }  
	        return obj;  
	    }  
	  
//	    // 首寫字母變大寫  這裡大家視情況而定,保證資料庫和你的Javabean欄位對應即可
//	    public static String firstUpperCase(String old) {  
//	        return old.substring(0, 1).toUpperCase() + old.substring(1);  
//	    }  
}
本文轉載自zfz1214

相關推薦

基於JDBC資料庫返回資料Resultset 資料Javabean

由於jdbc連線所有hibernate等都不能用,也不想用暴力的get/set 方法逐項新增儲存為臨時Javabean,所以可以採用反射和註解,一下為反射機制 package com.util; import java.lang.reflect.Field; imp

Spring Boot學習筆記(三)——使用JPA查詢資料庫返回需要的資料

1.概述 在上一篇中,我們已經學會了如何建立執行一個Spring Boot程式,但是他還遠遠滿足不了一個網站的基本需求,完成這篇的學習後我們就能實現一個簡單的雛形。 2.目標 在本篇中,實現的簡單的資料庫訪問,讀取資料的功能。 3.詳細步驟 (1)在第

Winfrom中資料的雙向(使用INotifyPropertyChanged)

在WPF中新建專案是自動實現了INotifyPropertyChanged介面,用於資料繫結時非常的方便 在winfrom中也可以實現INotifyPropertyChanged介面 將需要繫結的欄位寫到一個類中,用這個類實現INotifyPropertyChanged介面 pub

Jackson資料處理及

獲取 Maven的 該軟體包的功能包含在Java包中com.fasterxml.jackson.databind,可以使用以下Maven依賴項來使用: < properties > ... <! -儘可能使用最新版本。- > < jackson .versio

vue中用computed簡單實現資料的雙向(getter 和 setter)

vue是號稱實現了資料雙向繫結的框架,但事實上在日常開發中我們用的最多的就是 v-model 將data(vue例項中)裡面的是資料和view 相關聯,實現 data 更新,view自動重新整理的效果。但是,在移動成都上來說,這種資料雙向繫結的效果並不是特別的明顯。 今天,我用輸入框和 co

vue 資料又向原理

<!DOCTYPE html> <html lang="zh-CN"> <head>     <meta charset="UTF-8">     <title>myVue</title>

你必須知道的React的知識點:單向資料流,高效能虛擬DOM,元件間的資料互動,事件與資料的雙向,生命週期鉤子,fetch:資料請求等

1、React除錯工具:React Developer Tools 2、React開發工具:Atom 3、React UI庫:Material-UI / Ant Deaign 4、React適用場景:資料不斷變化的大型應用程式 5、前端UI構建方式:資料模型、UI介面

vue資料的雙向

先看要實現的效果: 再貼程式碼: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="

使用髒檢查機制實現資料的雙向

1.實現效果: input標籤的值一變化,底下的p標籤的內容就跟著變化。 2.實現思路: 首先,angular得把我的舊資料記下來的吧。 angular的雙向繫結依賴髒檢查機制。為要雙向繫結的資料進行註冊,註冊到$scope上。($scope是a

初探Vue原理之view-model的資料動態雙向

Vue應用的是mvvm框架,view和model分離,然後通過vm雙向資料繫結,` <!-- 模板 --> <div id="app"> {{msg}} </div> <!-模型-> // 原生物件即

vue如何實現資料的雙向

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <titl

echart折線圖 柱形圖 資料格式化 動態資料 frame處理

var myChart; var eCharts; require.config({ paths : { 'echarts' : '${pageContext.reques

Angularjs 資料的雙向和controller通訊

資料的雙向繫結 Angular實現了雙向繫結機制。所謂的雙向繫結,無非是從介面的操作能實時反映到資料,資料的變更能實時展現到介面。 angular並不存在定時髒檢測,而是觸發指定函式進入angular的digest流程: - DOM事件,如輸入文字,點選按

WPF中,ListBox與資料間的

<Windowx:Class="ListBinding.Window1"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xa

vue資料的雙向原始碼分析

VUE中的資料雙向繫結是通過資料劫持的方式實現的,核心的便是object.defineProperty(),它內部分為三個部分:observer 可以遞迴地監聽物件上的所有屬性,當屬性改變時觸發相應的watcher。watcher 觀察者,當監聽的資料值修改時,執行相應的回撥

ionic3 list進入detail,detail頁面資料無法雙向

1.匯入ChangeDetectorRef [javascript] view plain copy import { ChangeDetectorRef } from '@ang

關於Vue.js中資料模型的以及方法事件的與呼叫

在vue.js中,我們可以將事件方法寫在methods屬性中,資料模型在data中定義Vue的基本結構如下(只寫最常用的):將資料與vue例項繫結通過v-bind標籤這裡繫結的是sourceId這個值,基於vue的雙向繫結,如果要取vue的資料模型中的資料,使用{{param

SpringMVC中利用@InitBinder來對頁面資料進行解析

在使用SpingMVC框架的專案中,經常會遇到頁面某些資料型別是Date、Integer、Double等的資料要繫結到控制器的實體,或者控制器需要接受這些資料,如果這類資料型別不做處理的話將無法繫結。       解決方法:使用註解@InitBinder來解決這些問題,這樣

c# 模仿 vue 實現 winform 的資料模型雙向

前前前段時間面試遭拒,當時面試關問自己的一些東西確實不懂,其中就包括vue(其實有看過相關文章和文件,秉著 如果只是用輪子的話,需要時間和文件就夠了,事實上只是使用的話,按規範來就行了)。 但是自己怎麼能輕易停留在用呢,於是在花了點時間,直接搜尋vue繫結原理,詳細看了兩篇

C#利用Lambda和Expression實現資料的動態

在程式開發過程中,有時為了讓資料能夠實時更新,我們會採用資料繫結來實現。 一般我們資料繫結時我們是這樣寫的 public class Helper : INotifyPropertyChanged { #region statusI