zoukankan      html  css  js  c++  java
  • 持久层通用组件设计与范例,写给某孩子(基于JDBC)


    首先明确持久层作用,持久层就是要完成数据持久化。将数据库的存储功能从业务层分离出来的设计,也就是持久层组件了。目前,持久层框架分为两种(以Hibernate和iBatis为例),两者的提供的ORM机制对于业务逻辑开发人员都是面向对象,没有什么大的差别;但是在实现具体的数据持久化操作时,前者对SQL语句完全透明,而后者则要开发者具体去写SQL语句了。两者的优缺点在此处暂不做比较评论。Hibernate翻译为“冬眠”,老外很有意思,让数据冬眠也就是让数据持久化了。Hibernate对JDBC进行轻量级封装,所以这里,从JDBC学起。

    通用组件设计,重点应该落在通用两字上,如果要成为通用组件,应该满足一下要求:1.适用于任何数据库。2.适用于任何系统。3.屏蔽内部实现细节(这个实际很废话,面向抽象类或借口了)。4.由以上拓展,组件设计时应充分考虑到组件功能强大而不冗余。5.设计应保证组件可维护性,符合软件设计原则(这就要求我们应用一些其他组件或技术了,这里只写出最近本的范例)。

    面对以上问题,一一分析解决。在DBOP构造函数中连接数据库,只要把不同的链接字符串改一下就好了(如果这里用Spring中的依赖注入会好),满足各种数据库的基本操作无非CRUD。对于CRUD,基本的CRUD,当然还要考虑到预编译操作,毕竟系统中会经常传参(在这里设计时,必要去设计一些算法)。当然,为了设计更合理,更加符合单一原则,开闭原则等软件设计原则,应考虑一些优化设计(比如将SQL从JAVA代码中分离,这就涉及到属性文件的操作,这个以后介绍)。如果可以做到以上这些,可以说是比较通用了,一下附代码,DB用的是MS SQLserver。

    首先是类型定义

    package com.sys.dao;

    public final class TypeStruct {
    /**
    * String的代码值1
    */
    public static final String STRING = "1";

    /**
    * double的代码值2
    */
    public static final String DOUBLE = "2";

    /**
    * int的代码值3
    */
    public static final String INT = "3";

    /**
    * long的代码值4
    */
    public static final String LONG = "4";
    }

    DBOP抽象类

    package com.sys.dao;

    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.util.Vector;

    import javax.sql.DataSource;

    public interface DBOP {

    public abstract DataSource getDataSource();

    public abstract void setDataSource(DataSource dataSource);

    public abstract Connection getConn();

    public abstract void setConn(Connection conn);

    public abstract ResultSet getRs();

    public abstract void setRs(ResultSet rs);

    /**
    * 无参数查询
    *
    @param sql语句
    */
    public abstract ResultSet query(String sql);

    /**
    * 无参数修改
    *
    @param sql语句
    *
    @return 1成功 0失败
    */
    public abstract int update(String sql);

    /**
    * 通用操作
    *
    @param sql语句
    */
    public abstract boolean execute(String sql);

    /**
    * 预编译通用操作
    * @param1 sql语句 inser into table(param1,param2)values(?,?);
    * @param1 具体数据 vector偶数位--类型 奇数--数据
    *
    @return 1成功 0失败
    */
    public abstract int preUpdate(String sql, Vector vec);

    /**
    * 预编译通用查询
    */
    public abstract ResultSet preQuery(String sql, Vector vec);

    /**
    * 关闭连接
    */
    public abstract void close();

    /**
    * 关闭指定连接
    *
    *
    @param con
    */
    public abstract void close(Connection con);

    }

    DBOP实现细节,涉及到一个简单的字符串处理的算法,非常易于理解。

    package com.sys.dao;

    import java.sql.*;
    import java.util.*;

    import javax.sql.DataSource;

    public class DBOPImp implements DBOP {
    DataSource dataSource = null;
    Connection conn = null;
    ResultSet rs = null;

    public DataSource getDataSource() {
    return dataSource;
    }
    public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
    }
    public Connection getConn() {
    return conn;
    }
    public void setConn(Connection conn) {
    this.conn = conn;
    }
    public ResultSet getRs() {
    return rs;
    }
    public void setRs(ResultSet rs) {
    this.rs = rs;
    }


    //重载构造函数,首先执行
    public DBOPImp(){
    try {
    //加载数据库驱动
    Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver").newInstance();
    String url="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=formAction";
    String user="sa";
    String password="sa";
    conn= DriverManager.getConnection(url,user,password);
    } catch (Exception e) {
    System.out.println("["+e+"]");
    e.printStackTrace();
    }
    }
    /**
    * 无参数查询
    *
    @param sql语句
    */
    public ResultSet query(String sql){
    try {
    Statement stmt = conn.createStatement(
    ResultSet.TYPE_SCROLL_INSENSITIVE,
    ResultSet. CONCUR_READ_ONLY);
    rs = stmt.executeQuery(sql);
    System.out.println(rs);
    } catch (Exception e) {
    System.out.println("[无参数查询]"+e);
    e.printStackTrace();
    }
    return rs;
    }

    /**
    * 无参数修改
    *
    @param sql语句
    *
    @return 1成功 0失败
    */
    public int update(String sql){
    int flag = 0;
    try {
    Statement stmt = conn.createStatement();
    flag = stmt.executeUpdate(sql);
    System.out.println(flag);
    } catch (Exception e) {
    System.out.println("[无参数修改]"+e);
    e.printStackTrace();
    }
    return flag;
    }

    /**
    * 通用操作
    *
    @param sql语句
    */
    public boolean execute(String sql){
    boolean flag = false;
    try {
    Statement stmt = conn.createStatement();
    flag = stmt.execute(sql);
    System.out.println(flag);
    } catch (Exception e) {
    System.out.println("[通用操作]"+e);
    e.printStackTrace();
    }
    return flag;
    }


    /**
    * 预编译通用操作
    * @param1 sql语句 inser into table(param1,param2)values(?,?);
    * @param1 具体数据 vector偶数位--类型 奇数--数据
    *
    @return 1成功 0失败
    */
    public int preUpdate(String sql, Vector vec) {
    int result = 0;
    int index = 0;
    try {
    PreparedStatement updateSales = conn.prepareStatement(sql);
    // 动态参数
    int insertNum = 1;
    while (index < vec.size()) {
    switch (Integer.parseInt((String) vec.get(index))) {
    case 1: //String
    updateSales.setString(insertNum,
    (String) vec.get(++index));
    break;
    case 2: //double
    updateSales.setDouble(insertNum,
    ((Double) vec.get(++index)).doubleValue());
    break;
    case 3: //int
    updateSales.setInt(insertNum,
    ((Integer) vec.get(++index)).intValue());
    break;
    case 4: //long
    updateSales.setLong(insertNum,
    ((Long) vec.get(++index)).longValue());
    break;
    }
    insertNum++;
    index++;
    }
    // 写入数据库
    if (updateSales.executeUpdate() != 0)
    result = 1;
    }
    catch (Exception e) {
    System.out.println("[preUpdate]" + e);
    e.printStackTrace();
    }
    System.out.println(result);
    return result;
    }

    /**
    * 预编译通用查询
    */
    public ResultSet preQuery(String sql, Vector vec) {
    int index = 0;
    try {
    PreparedStatement updateSales = conn.prepareStatement(sql);
    // 动态参数
    int insertNum = 1;
    while (index < vec.size()) {
    switch (Integer.parseInt((String) vec.get(index))) {
    case 1: // String
    updateSales.setString(insertNum, (String) vec.get(++index));
    break;
    case 2: // double
    updateSales.setDouble(insertNum,
    ((Double) vec.get(++index)).doubleValue());
    break;
    case 3: // int
    updateSales.setInt(insertNum, ((Integer) vec.get(++index))
    .intValue());
    break;
    case 4: // long
    updateSales.setLong(insertNum, ((Long) vec.get(++index))
    .longValue());
    break;
    }
    insertNum++;
    index++;
    System.out.println(insertNum);
    }
    // 写入数据库
    rs = updateSales.executeQuery();
    }
    catch (Exception e) {
    System.out.println("[preQuery]" + e);
    e.printStackTrace();
    }
    System.out.println(rs);
    return rs;
    }

    /**
    * 关闭连接
    */
    public void close() {
    if (conn != null) {
    try {
    if (!conn.isClosed()) {
    conn.close();
    conn = null;
    System.out.println("关闭连接");
    }
    } catch (Exception e) {
    System.out.println("[关闭连接]" + e);
    e.printStackTrace();
    }
    }
    }

    /**
    * 关闭指定连接
    *
    *
    @param con
    */
    public void close(Connection con) {
    if (con != null) {
    try {
    if (!con.isClosed()) {
    con.close();
    con = null;
    System.out.println("关闭指定连接");
    }
    } catch (Exception e) {
    System.out.println("[关闭关闭指定连接连接]" + e);
    e.printStackTrace();
    }
    }
    }

    }




  • 相关阅读:
    hdu 4521 小明系列问题——小明序列(线段树 or DP)
    hdu 1115 Lifting the Stone
    hdu 5476 Explore Track of Point(2015上海网络赛)
    Codeforces 527C Glass Carving
    hdu 4414 Finding crosses
    LA 5135 Mining Your Own Business
    uva 11324 The Largest Clique
    hdu 4288 Coder
    PowerShell随笔3 ---别名
    PowerShell随笔2---初始命令
  • 原文地址:https://www.cnblogs.com/newbee/p/2324036.html
Copyright © 2011-2022 走看看