国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

DbUtils(二) 結果集實例

2019-11-14 22:56:18
字體:
來源:轉載
供稿:網友
DbUtils(二) 結果集實例

單行數據處理:ScalarHandler ArrayHandler MapHandler BeanHandler

多行數據處理:BeanListHandler AbstractListHandler(ArrayListHandler MapListHandler ColumnListHandler)

AbstractKeyedHandler(KeyedHandler BeanMapHandler)

可供擴展的類:BaseResultSetHandler

Dbutils使用結果集的方法有query、insert、insertBatch三個。這些方法都在QueryRunner類中,需要注意的是insert和update方法都能執行 “insert”開頭的sql語句,但是返回值有區別。insert 執行后返回的是表中的插入行生成的主鍵值,update 返回的是受語句影響的行數。所以,如果目標表中有主鍵且需要返回插入行的主鍵值就用 insert 方法,如果表沒有主鍵或者不需要返回主鍵值可使用 update 方法。

先建立測試用數據表[users]:

iduserNameloginNameuserPassWorduserLeveluserLock
1測試用戶1test1jiseflwes100
2知道什么hello2556sefsfs101
3編程就編程cjavasfsfsef254sefs20

字段類型,id 為主鍵:

[id] [int] IDENTITY(1,1) NOT NULL,[userName] [nchar](20) NOT NULL,[loginName] [nchar](20) NOT NULL,[userPassword] [nchar](100) NOT NULL,[userLevel] [int] NOT NULL,[userLock] [bit] NOT NULL,

1、ScalarHandler<T>

用于獲取結果集中第一行某列的數據并轉換成 T 表示的實際對象。

該類對結果集的處理直接在 handle 方法中進行,不涉及 dbutils 庫的其他類。

String sql = "select * from users";// ---- query 語句 ----// ScalarHandler 的參數為空或null時,返回第一行第一列的數據int rs = runner.query(sql, new ScalarHandler<Integer>());System.out.數據庫,QueryRunner的insert獲取插入數據的主鍵其實調用的是select SCOPE_IDENTITY()// 數據庫執行后返回的類型是numeric,映射到 java 類型就是 java.math.BigDecimalString inSql = "insert users (userName, loginName, userPassword, userLevel, userLock) values (?, ?, ?, ?, ?)";BigDecimal insertRs = runner.insert(inSql,new ScalarHandler(),  "java程序編寫", "javahello", "sefsfsfwew", "15", false);System.out.println("ScalarHandler: " + insertRs); // Print:[ScalarHandler: 4]

使用的時候一定要保證提供正確的列索引或列名,并且結果類型也要正確可轉換。

2、ArrayHandler

用于獲取結果集中的第一行數據,并將其封裝到一個數組中,一列值對應一個數組元素。

handle 源碼

public Object[] handle(ResultSet rs) throws SQLException {    // convert = new BasicRowProcessor()    // 如果有數據,將調用 BasicRowProcessor 的 toArray(rs) 方法處理    return rs.next() ? this.convert.toArray(rs) : EMPTY_ARRAY;}
// ---- query 語句 ----String sql = "select * from users";Object[] rs = runner.query(sql, new ArrayHandler());// Print: ArrayHandler: [1, 測試用戶1, test1, jiseflwes, 10, false]System.out.println("ArrayHandler: " + Arrays.toString(rs));// ---- insert 語句 ----String inSql = "insert users_t (userName, loginName, userPassword, userLevel, userLock) values (?, ?, ?, ?, ?)";Object[] insertRs = runner.insert(inSql,new ArrayHandler(),  "java程序編寫", "javahello", "sefsfsfwew", "15", false);// Print: ArrayHandler: [5]System.out.println("ArrayHandler: " + Arrays.toString(insertRs));

3、MapHandler

用于獲取結果集中的第一行數據,并將其封裝到一個Map中,Map 中 key 是數據的列別名(as label),如果沒有就是列的實際名稱,Map 中 value 就是列的值,注意代表列的 key 不區分大小寫。

handle 源碼:

public Map<String, Object> handle(ResultSet rs) throws SQLException {    // convert = new BasicRowProcessor()    // 如果有數據,將調用 BasicRowProcessor 的 toMap(rs) 方法處理    return rs.next() ? this.convert.toMap(rs) : null;}

通過查看BasicRowProcessor 代碼,可以知道封裝結果集的 Map 其實是一個LinkedHashMap 對象。

// ---- query 語句 ----String sql = "select userName, loginName, userPassword as password, userLevel, userLock from users";Map<String, Object> rs = runner.query(sql, new MapHandler());// Print: MapHandler: {userName=測試用戶1, loginName=test1, password=jiseflwes, userLevel=10, userLock=false}System.out.println("MapHandler: " + rs);// 列名小寫 Print: username: 測試用戶1System.out.println("username: " + rs.get("username"));// 列名大寫 Print: USERNAME: 測試用戶1System.out.println("USERNAME: " + rs.get("USERNAME"));// 使用了as指定別名,那么取數據的時候一定要用別名,否則返回null。// Print: userPassword as password: jiseflwesSystem.out.println("userPassword as password: " + rs.get("password"));// Print: userPassword as password: nullSystem.out.println("userPassword as password: " + rs.get("userPassword"));// ---- insert 語句 ----String inSql = "insert users (userName, loginName, userPassword, userLevel, userLock) values (?, ?, ?, ?, ?)";Map<String, Object> insertRs = runner.insert(inSql,new MapHandler(),  "java程序編寫", "javahello", "sefsfsfwew", "15", false);// 注意這個鍵(key)是由數據庫驅動定義的。// Print: MapHandler:{GENERATED_KEYS=6}System.out.println("MapHandler: " + insertRs);// 我用的是微軟提供的驅動,所以是GENERATED_KEYS,如果是其他驅動就又不同了(比如jtds驅動key是ID)// jtds驅動使用 insertRs.get("ID")// Print: MapHandler: 6System.out.println("MapHandler: " + insertRs.get("GENERATED_KEYS"));

4、BeanHandler<T>

用于獲取結果集中的第一行數據,并將其封裝到JavaBean對象。

整個轉換過程最終會在BeanProcessor 類中完成。

/** * Users類 */public class Users {    private int id;    private String userName;    private String loginName;    private String userPassword;    private int userLevel;    private boolean userLock;    public int getId() {        return id;    }    public void setId(int id) {        this.id = id;    }    public String getUserName() {        return userName;    }    public void setUserName(String userName) {        this.userName = userName;    }    // ... 略過其他 getter 和 setter 方法    @Override    public String toString() {        return "Users{" +                "id=" + id +                ", userName='" + userName + '/'' +                ", loginName='" + loginName + '/'' +                ", userPassword='" + userPassword + '/'' +                ", userLevel=" + userLevel +                ", userLock=" + userLock +                '}';    }}

執行代碼:

//---- query 語句 ----String sql = "select * from users";Users rs = runner.query(sql, new BeanHandler<Users>(Users.class));// Print: BeanHandler: Users{id=1, userName='測試用戶1', loginName='test1', userPassword='jiseflwes', userLevel=10, userLock=true}System.out.println("BeanHandler: " + rs);// Print: BeanHandler: test1System.out.println("BeanHandler: " + rs.getLoginName());

需要注意的是,默認的情況下要保證表的字段和javabean的屬性一致(字符一致即可,對大小寫不敏感),比如字段是userLock,那么javabean中屬性必須是userLock這幾個字母(可以是userlock,userLock,userLOCK,不過還是建議按照規范來定義)。

但有個問題,數據表中的字段可能已經定下來了,而且名稱可能不太規范,比如用下劃線(login_name),或者加了一個類型前綴(chrLoginName),如果修改表字段,那么涉及到的修改地方太多了,其實查看源碼可以知道BeanHandler有兩個構造方法:

    // BeanHandler 構造方法    public BeanHandler(Class<T> type) {        this(type, ArrayHandler.ROW_PROCESSOR);    }    public BeanHandler(Class<T> type, RowProcessor convert) {        this.type = type;        this.convert = convert;    }

可以看出其實都是調用的第二個方法。

runner.query(sql, new BeanHandler<Users>(Users.class));// 等價于runner.query(sql, new BeanHandler<Users>(Users.class, new BasicRowProcessor()));// 等價于runner.query(sql, new BeanHandler<Users>(Users.class, new BasicRowProcessor(new BeanProcessor())));// 所以關鍵的地方在 new BeanProcessor() 這個具體處理結果的對象

情況一:只涉及到下劃線,表字段名用下劃線間隔(如表users_t字段:[id],[user_name],[login_name],[user_password],[user_level],[user_lock]),現在要封裝到Javabean中Users類(代碼見上),其中屬性使用駝峰命名。可以用dbutils1.6提供的BeanProcessor類的子類GenerousBeanProcessor。

String sql = "select id,user_name,login_name,user_password,user_level,user_lock from users_t"; // 創建一個BeanProcessor對象// GenerousBeanProcessor 僅僅重寫了父類BeanProcessor的mapColumnsToProperties方法BeanProcessor bean = new GenerousBeanProcessor();// 將GenerousBeanProcessor對象傳遞給BasicRowProcessorRowProcessor processor = new BasicRowProcessor(bean);// 最后使用GenerousBeanProcessor的mapColumnsToProperties處理表字段到javabean的屬性映射Users rs = runner.query(sql, new BeanHandler<Users>(Users.class, processor));// Print: BeanHandler: Users{id=1, userName='測試用戶1', loginName='test1', userPassword='jiseflwes', userLevel=10, userLock=true}System.out.println("BeanHandler: " + rs);

情況二:完全改變表字段到Javabean屬性的映射(如表users_m字段:[yhmid],[charUsername],[charLoginName],[charPassword],[intLevel],[boolLock])映射到Users類(代碼同上):

// BeanProcessor 有兩個構造方法,可以傳入一個HashMap集合// HashMap 規定了表字段映射到Javabean的哪個屬性,即key為字段名稱,value為對應的javabean屬性// map.put(表字段名稱, Javabean屬性名稱)Map<String, String> map = new HashMap<String, String>();map.put("yhmid", "id");map.put("charUsername", "userName");map.put("charLoginName", "loginName");map.put("charPassword", "userPassword");map.put("intLevel", "userLevel");map.put("boolLock", "userLock");// 用構建好的HashMap建立一個BeanProcessor對象BeanProcessor bean = new BeanProcessor(map);RowProcessor processor = new BasicRowProcessor(bean);Users rs = runner.query(sql, new BeanHandler<Users>(Users.class, processor));// Print: BeanHandler: Users{id=1, userName='測試用戶1', loginName='test1', userPassword='jiseflwes', userLevel=10, userLock=true}System.out.println("BeanHandler: " + rs);

5、BeanListHandler<T>

用于將結果集的每一行數據轉換為Javabean,再將這個Javabean添加到ArrayList中。可以簡單的看著是BeanHandler的高級版,只不過是多了一步,就是將生成的Javabean添加到ArrayList中,其他的處理都和BeanHandler一樣。

String sql = "select * from users";List<Users> rs = runner.query(sql, new BeanListHandler<Users>(Users.class));// Print: BeanListHandler: [// Users{id=1, userName='測試用戶1', loginName='test1', userPassword='jiseflwes', userLevel=10, userLock=true},// Users{id=1, userName='知道什么', loginName='hello', userPassword='2556sefsfs', userLevel=10, userLock=true},// Users{id=1, userName='編程就編程', loginName='cjava', userPassword='sfsfsef254sefs', userLevel=2, userLock=false}]System.out.println("BeanListHandler: " + rs);

6、AbstractListHandler<T>

    // AbstractListHandler 類實現了handle方法    @Override    public List<T> handle(ResultSet rs) throws SQLException {        List<T> rows = new ArrayList<T>();        while (rs.next()) {            rows.add(this.handleRow(rs)); // 每個子類實現自己的handleRow方法        }        return rows;    }

AbstractListHandler抽象類已經實現handle方法,該方法其實只是起到一個包裝作用,將處理好的每行數據添加到ArrayList中。每行的數據處理通過調用handleRow方法實現,所有它的3個子類都必須實現這個方法。

6.1ArrayListHandler(extends AbstractListHandler<Object[]>)

用于將結果集每行數據轉換為Object數組(處理過程等同與ArrayHandler),再將該數組添加到ArrayList中。簡單點,就是將每行數據經過ArrayHandler處理后添加到ArrayList中。

String sql = "select * from users";List rs = runner.query(sql, new ArrayListHandler());// Print:// [1, 測試用戶1, test1, jiseflwes, 10, true]// [2, 知道什么, hello, 2556sefsfs, 10, true]// [3, 編程就編程, cjava, sfsfsef254sefs, 2, false]for(Object user : rs) {    System.out.println(Arrays.toString((Object[])user));}

6.2MapListHandler(extends AbstractListHandler<Map<String, Object>>)

用于將結果集每行數據轉換為Map(處理過程等同與MapHandler),再將Map添加到ArrayList中。簡單點,就是將每行數據經過MapHandler處理后添加到ArrayList中。

String sql = "select * from users";List rs = runner.query(sql, new MapListHandler());// Print:// {1, 測試用戶1, test1, jiseflwes, 10, true}// {2, 知道什么, hello, 2556sefsfs, 10, true}// {3, 編程就編程, cjava, sfsfsef254sefs, 2, false}for(Object user : rs) {    System.out.println(Arrays.toString((Map<String, Object>)user));}

6.3ColumnListHandler<T>(extends AbstractListHandler<T>)

根據列索引或列名獲取結果集中某列的所有數據,并添加到ArrayList中。可以理解為ScalarHandler<T>的加強版。

String sql = "select * from users";List<String> rs = runner.query(sql, new ColumnListHandler<String>(2));// 等同 List<String> rs = runner.query(sql, new ColumnListHandler<String>("userName"));// Print:// 測試用戶1// 知道什么// 編程就編程for(String user : rs) {    System.out.println(user);}

7、AbstractKeyedHandler<K, V>

AbstractKeyedHandler是一個抽象類,已經實現了handle方法,其子類必須實現createKey(ResultSetrs)和createRow(ResultSetrs)方法,以便handle()的調用。

   /**     * 返回一個HashMap<K, V>     * createKey(rs) 將某列的值作為HashMap的key     * createRow(rs) 將結果集轉換后作為HashMap的value     */    @Override    public Map<K, V> handle(ResultSet rs) throws SQLException {        Map<K, V> result = createMap();        while (rs.next()) {            result.put(createKey(rs), createRow(rs)); // 需要子類自己實現        }        return result;    }

7.1KeyedHandler<K>(extends AbstractKeyedHandler<K, Map<String, Object>>)

用于獲取所有結果集,將每行結果集轉換為Map<String, Object>,并指定某列為key。可以簡單的認為是一個雙層Map,相當于先對每行數據執行MapHandler,再為其指定key添加到一個HaspMap中。KeyedHandler<K> 中的<K>是指定的列值的類型。

String sql = "select * from users";// 在這兒指定主鍵id為結果key,也可以傳入列名 new KeyedHandler<Integer>("id")Map<Integer, Map<String, Object>> rs = runner.query(sql, new KeyedHandler<Integer>(1));// Print: KeyedHandler: {//        1={id=1, userName=測試用戶1, loginName=test1, userPassword=jiseflwes, userLevel=10, userLock=true},//        2={id=2, userName=知道什么, loginName=hello, userPassword=2556sefsfs, userLevel=10, userLock=true},//        3={id=3, userName=編程就編程, loginName=cjava, userPassword=sfsfsef254sefs, userLevel=2, userLock=false}}System.out.println("KeyedHandler: " + rs);// 也可以指定其他列作為key,但是需要注意如果指定的列值存在重復值,那么后面的值將覆蓋前面的,最終HashMap中key都是唯一的。// 如指定列userLevel為key,最終只有兩個結果,因為前兩行userLevel值都是10。Map<Integer, Map<String, Object>> rs = runner.query(sql, new KeyedHandler<Integer>("userLevel"));// Print: KeyedHandler: {//        2={id=3, userName=編程就編程, loginName=cjava, userPassword=sfsfsef254sefs, userLevel=2, userLock=false},//        10={id=2, userName=知道什么, loginName=hello, userPassword=2556sefsfs, userLevel=10, userLock=true}}System.out.println("KeyedHandler: " + rs);

7.2 BeanMapHandler<K, V>(extends AbstractKeyedHandler<K, V>)

用于獲取所有結果集,將每行結果集轉換為Javabean作為value,并指定某列為key,封裝到HashMap中。相當于對每行數據的做BeanHandler一樣的處理后,再指定列值為Key封裝到HashMap中。

String sql = "select * from users";// new BeanMapHandler<Integer, Users>(Users.class,"id")Map<Integer, Users> rs = runner.query(sql, new BeanMapHandler<Integer, Users>(Users.class,1));// Print: BeanMapHandler: {// 1=Users{id=1, userName='測試用戶1', loginName='test1', userPassword='jiseflwes', userLevel=10, userLock=true},// 2=Users{id=2, userName='知道什么', loginName='hello', userPassword='2556sefsfs', userLevel=10, userLock=true},// 3=Users{id=3, userName='編程就編程', loginName='cjava', userPassword='sfsfsef254sefs', userLevel=2, userLock=false}}System.out.println("BeanMapHandler: " + rs);

需要注意這個結果轉換類也可以像BeanHandler的情況一和情況二介紹的那樣定義一個processor,但默認情況下這么做了就會以每行的第一列作為Key,不能指定其他列為Key。

// 這種情況下,以每行第一列為keyMap<Integer, Users> rs = runner.query(sql, new BeanMapHandler<Integer, Users>(Users.class,processor));

8、BaseResultSetHandler<T>

根據文檔介紹,如果上面的結果集處理類都不能滿足你的要求,可以通過繼承這個抽象類定義自己的結果處理類,子類必須實現無參方法handle()。

做個簡單的例子,比如要將指定列值加一個前綴"class-"后添加到ArrayList中:

//------------- 定義類 MeResultHandler.java -------------/** * 自定義的結果處理類,對結果集的操作直接調用父類已經封裝好的方法。 * 這兒只是對取到的結果包裝加工。 */public class MeResultHandler extends BaseResultSetHandler<List<String>> {    private final int columnIndex;    // 指定要獲取值的列索引    public MeResultHandler(int columnIndex) {        this.columnIndex = columnIndex;    }    // 重寫父類的方法,封裝每行數據    @Override    protected List<String> handle() throws SQLException {        List<String> rows = new ArrayList<String>();        // 因為父類已經封裝好了對ResultSet各種操作,直接調用父類方法 next()        while(this.next()) {            rows.add(handleRow());        }        return rows;    }    // 自定義的數據處理方法    @SuppressWarnings("unchecked")    private String handleRow() throws SQLException {        // 直接調用父類方法 getObject()        return "class-" + String.valueOf(this.getObject(this.columnIndex));    }}//------------- 使用類 -------------List<String> rs = runner.query(sql, new MeResultHandler(1));// Print: MeResultHandler: [class-1, class-2, class-3]System.out.println("MeResultHandler: " + rs);

======================================================================

總的來說,最終的數據處理是在BasicRowProcessor 的四個方法中進行,涉及到JavaBean的話會通過BasicRowProcessor 調用BeanProcessor 的兩個方法。其他的都是對每行數據轉換后的結果的封裝。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 团风县| 伊川县| 洛宁县| 南宁市| 红桥区| 昌都县| 榆树市| 扎赉特旗| 鲁山县| 资中县| 米脂县| 邢台县| 阿巴嘎旗| 正镶白旗| 繁峙县| 阿克陶县| 元氏县| 惠水县| 博兴县| 西青区| 大英县| 赣榆县| 昂仁县| 海林市| 驻马店市| 大兴区| 鲜城| 呼图壁县| 华亭县| 竹山县| 慈溪市| 永平县| 昭平县| 微山县| 永定县| 镇坪县| 太仆寺旗| 鸡西市| 沁源县| 上饶县| 磐安县|