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();
    }
    }
    }

    }




  • 相关阅读:
    除草第一季 1 简单日常心得
    [搬家from qzone] 读书笔记 人间情味.半成品
    [搬家from qzone] 读书笔记 最好的告别
    [搬家from qzone] 读书笔记 爱是一种选择
    [搬家from qzone] 读书笔记 童年的王国
    [搬家from qzone] 我不是一个很好的学长,所以毕业前,给学习学妹们写写自己犯的错误吧
    博客重新开张 第一篇灌水
    我眼中的vim
    linux启动kdump失败
    centos7 minimal安装之后要做的事情
  • 原文地址:https://www.cnblogs.com/newbee/p/2324036.html
Copyright © 2011-2022 走看看