那位大哥能帮我设计一个数据库框架(access)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了那位大哥能帮我设计一个数据库框架(access)相关的知识,希望对你有一定的参考价值。

用Access设计一数据库,来管理U/C矩阵 利用(VBA)
能实现U/C矩阵的生成,能支持U/C矩阵的各种分析方法。具体解释如下:

U/C矩阵正确性检验
正确性检验原则:数据守恒
正确性检验目的:
确保功能和数据类划分和选取正确、合理;
保证U/C矩阵建立无错误。
三方面正确性检验:
完备性检验 一致性检验 无冗余性检验

U/C矩阵的主要功能:
利用U/C矩阵正确性检验,及时发现前阶段系统分析和调查工作中的错误。
通过U/C矩阵正确性经验来分析U/C矩阵建立的的正确性。
通过U/C矩阵求解过程最终获得子系统划分方案。
确定子系统间的共享数据。

如上所述,不求做出,只要能提供个思路即可。
不胜感激之至。
如有代码更好,请发至kerran@sohu.com

学习JDBC以来一直想实现一个简单的封装来方便编程但是由于水平有限一直没有较好的办法,看了IBM开发网上的两篇文章以后感觉作者的设计思想很好一定能扩充成一个实用的JDBC封装。所以我在文章提供的源码基础上加了一些功能这些功能包括支持多种数据类型,处理了空值,利用反射方便的在Row对象和值对象之间进行转换,还有加了一个我自认为通用的DAO类来方便用户的操作。

我把源码提供出来有两个目的一鍪窍M�馨镏�任一钩跹У某跹д呤煜�DBC,另外就是请各位高手不吝赐教,改进程序中的错误如果能将你们的对JDBC的封装方法提供出来那就更好了(不要说你们只用EJB或者Hibernate,JDO什么的?)。

设计思想

把DBMS抽象成类Database,这个类负责管理数据库连接以及提供表对象。

把数据库中的一张或多张表抽象成类Table,这个类中提供对表的添加,修改,删除的JDBC封装。

将数据库表中的一条记录抽象成类Row,这个类用HashMap保存关系数据库中表格中一行数据的字段名和值并提供一些相关操作。另外这个类还提供了两个静态方法用于在Row对象和ValueObject之间进行方便的转换。

把对个Row的集合抽象成RowSet,这个类中用一个vector把多个Row对象保存起来并提供一些相关操作。

代码分析

由于已经给出源码所以我只对代码中关键的和需要注意的地方加以说明,大家可以执行源码一边演示一边体会。

Database类源码如下:

package com.gdr

j.util.database;
import java.sql.*;
import javax.sql.*;
import com.gdrj.util.servicelocator.*;
public class Database

/**
* 这个数据库连接成员只有在与数据库直接建立连接的情况下是有效的
*/

private Connection conn = null;

/**
* 当这个参数有效时,表明程序是直接与数据库建立的连接而不是从连接池里取得连接
*/

private String url, user, password;

/**
* 当这个参数有效时,表明程序是从连接池里取得连接。
*/

private String datasource;

/**
* 用数据库地址,用户名,密码初始化数据库对象,这个构造器用于程序是直接
* 与数据库建立连接的情况。
* @param url
* @param user
* @param password
*/

public Database(String url, String user, String password)

this.url = url;
this.user = user;
this.password = password;

/**
* 用JNDI数据源名初始化数据库对象,这个构造器用于从连接池取数据库连接的情况。
* @param datasource
*/

public Database(String datasource)

this.datasource = datasource;


/**
* 得到数据库连接,对于是否从连接池里取连接做了自动处理即根据用户调用了哪个构造器
* 来判断是否直接与数据库建立连接还是从连接池里取连接。
* 对于用户来说不用考虑程序是从那里取得连接,他只管正确的初始化数据库对象。
* @return * @throws SQLException
*/

public Connection getConnection() throws Exception

if (datasource == null)

//直接与数据库建立连接
if (conn == null)

conn = DriverManager.getConnection(url, user, password);


else

//从应用服务器的连接池里取得连接
ServiceLocator sl = ServiceLocator.getInstance();
DataSource ds = sl.getDataSource(datasource);
return ds.getConnection();
//每调用一次都返回一个连接池中的数据库连接

return conn;


/**
* 释放连接,如果是直接与数据库连接的情况则什么也不做
* 如果是从连接池中取得的�幽敲词头糯�吹牧�?
* @param conn
*/

public void disConnect(Connection connection)

if (datasource != null)

//只处理从连接池取连接的情况
try

if (connection != null)

connection.close();


catch (Exception ex)



/**
* 得到与参数名对应的表对象,注意这里不作任何数据库操作
* @param name
* @return
*/

public Table getTable(String name)

return new Table(this, name);



这个类是对DBMS的抽象,所以使用时应用程序中只要有一个Database对象就够了,如果你是以与数据库之间建立连接的方式使用那么你用Database(String url, Stri

ng user, String password)构造器进行初始化。如果是从应用服务器的连接池中取得连接的方式使用那么用Database(String datasource)构造器初始化,这样以后你使用这个对象进行getConnection和disConnection时就挥萌タ悸鞘贾毡3忠桓隽�?C/S方式),还是将连接返回连接池了因为在disConnection中已经做了处理。集体使用方法将Table类。在getConnection中的从连接池中取连接的代码你只要参考以下《J2EE核心模式》中的服务定位器模式就知道是怎么回事了,你在用Database(String url, String user, String password)初始化时其中的代码不起作用。

Table类源码如下:

package com.gdrj.util.database;
import java.sql.*;
import java.util.*;
import com.gdrj.util.*;
public class Table

/**
* 通过这个数据库对象得到数据库连接
*/

private Database database;

/**
* 数据库中一个或多个(只限查询)表的名
*/

private String name;

/**
* 初始化表对象,此时不作任何数据库相关操作
* 一般通过database的getTable调用
* @param database
* @param name
*/

public Table(Database database, String name)

this.database = database;
this.name = name;


/**
* 查询某一行
* @return
*/

public Row getRow(String fields, String criteria, Object[] args)
throws DBAccessException

RowSet rows = executeQuery(fields, criter

ia, args);
if (rows == null)

return null;

return rows.get(0);


/**
* 得到一个多行记录
* @param criteria 查询条件
* @param args 查询条件的参数列表
* @return
*/

public RowSet getRows(String fields, String criteria, Object[] args)
throws DBAccessException

return executeQuery(fields, criteria, args);


/**
* 执行SQL查询
* @param fields 要查询的字段,如果传入null则表示查询表中所有字段
* @param criteria用户输入的查询Where条件
* @param args 用到的参数数组
* @return 返回符合结果行集
*/

private RowSet executeQuery(String fields, String criteria, Object[] args)
throws DBAccessException

Connection conn = null;
RowSet rows = new RowSet();
String sql = null;
if (fields == null)

fields = "*";

try

conn = database.getConnection();
//取得数据库连接,在方法内部对不同的连接情况进行了处理
sql = "select " + fields + " from " + name + ( (criteria == null) ? "" : (" where " + criteria));
PreparedStatement pstmt = conn.prepareStatement(sql);
if (args != null)

//如果有查询参数则设置参数
for (int i = 0; i < args.length; i++)

pstmt.setO
bject(i + 1, args[i]);


ResultSet rs = pstmt.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
int cols = rsmd.getColumnCount();
/**@todo 判断是否为零*/
if (cols == 0) return null;
while (rs.next())

Row row = new Row();
for (int i = 1; i <= cols; i++)

String name = rsmd.getColumnName(i);
Object value = rs.getObject(i);
//作通用类型处理,这样row中的类型都是Object型的。
/**
* 这里要做空值处理,因为在进行RowToValueObject转换时如果是空值则不能得到值的类型
* 所以如果是空值那么把value设置成类型信息
*/

if (value == null)

value = Class.forName(rsmd.getColumnClassName(i));

// System.out.println(value.getClass());

//用于得到数据库中的类型对应Java中的什么类型

row.put(name, value);

rows.add(row);

rs.close();
pstmt.close();

catch (Exception ex)

throw new DBAccessException(InforGeter.getErrorInfor(this, "executeQuery", ex, "执行SQL(" + sql + ")查询时出错!"));

finally

database.disConnect(conn);

//调用数据库对象的释放连接方法(此方法内对取得连接方式的不同情况做了处理)

return rows;


/**
* 增加一行
* @param row
*/

public int putRow(Row row) throws DBAccessException

return putRow(row, null, null);


/**
* 修改一行(没有条件就是增加)
* @param row
* @param conditions
*/

public int putRow(Row row, String conditions, Object[] args)
throws DBAccessException

String ss = "";
int affectableRow = 0;
//执行SQL后影响的行数
if (conditions == null)

ss = "INSERT INTO " + name + "(";
for (int i = 0; i < row.length(); ++i)

String k = row.getKey(i);
ss += k;
if (i != row.length() - 1)

ss += ", ";


ss += ") VALUES (";
for (int j = 0; j < row.length(); ++j)

ss += (row.get(j) == null) ? "null" : "?";
//如果row中有空值则设置为null,否则设置为查询参数
if (j != row.length() - 1) ss += ", ";

ss += ")";

else

ss = "UPDATE " + name + " SET ";
for (int i = 0; i < row.length(); ++i)

String k = row.getKey(i);
ss += k + "=" + ( (row.get(i) == null) ? "null" : "?");

//设置查询参数
if (i != row.length() - 1) ss += ", ";

ss += " WHERE ";
ss += conditions;

Connection conn = null;
try

conn = database.getConnection();
PreparedStatement st = conn.prepareStatement(ss);
int j = 0;
//查询参数计数器
for (int i = 0; i < row.length(); i++)

if (row.get(i) != null)

//如果不是空则解析查询参数
st.setObject(++j, row.get(i));
//解析查询参数


if (args != null)

for (int i = 0; i < args.length; i++)

st.setObject(++j, args[i]);
//预定的规则,null不能放到查询参数中要以name=null的静态形式存放


affectableRow = st.executeUpdate();
st.close();

catch (Exception ex)

ex.printStackTrace();
throw new DBAccessException(InforGeter.getErrorInfor(this, "putRow", ex, "更新表" + name + "中的数据时出错!"));

finally

database.disConnect(conn);

return affectableRow;


/**
* 删除一行
* @param row
*/

public int delRow(Row row) throws DBAccessException

String ss = "";
int affectableRow = 0;
ss = "de

lete from " + name + " where ";
for (int i = 0; i < row.length(); ++i)

String k = row.getKey(i);
ss += k + ((row.get(i) == null)?" is null":"=?");
//设置查询参�锌罩荡�?
if (i != row.length() - 1)

ss += " and ";


Connection conn = null;
try

conn = database.getConnection();
PreparedStatement st = conn.prepareStatement(ss);
int j = 0;
//查询参数计数器
for (int i = 0; i < row.length(); i++)

if (row.get(i) != null)

st.setObject(++j, row.get(i));
//解析查询参数


affectableRow = st.executeUpdate();
st.close();

catch (Exception ex)

throw new DBAccessException(InforGeter.getErrorInfor(this, "delRow", ex, "删除表" + name + "中的数据时出错!"));

finally

database.disConnect(conn);


return affectableRow;


/**
* 有条件的删除即删除多行
* @param condition
* @param args
*/

public int delRow(String condition, Object[] args)
throws DBAccessException

String ss = "";
int affectableRow = 0;
ss = "delete from " + name + " where ";
ss += condition;
Connection co

nn = null;
try

conn = database.getConnection();
PreparedStatement st = conn.prepareStatement(ss);
if (args != null)

�or (int i = 0; i < args.length; i++)

st.setObject(i + 1, args[i]);


affectableRow = st.executeUpdate();
st.close();

catch (Exception ex)

throw new DBAccessException(InforGeter.getErrorInfor(this, "delRow", ex, "删除表" + name + "中的数据时出错!"));

finally

database.disConnect(conn);

�eturn affectableRow;



使用时可以用Database对象的getTable方法传入数据库表的名称来得到一个Table对象。得到这个对象后就可以对这个数据库表进行操作了,这个类提供了六个方法根据传过来的参数对数据库表进行添加修改删除操作。代码中没有特别难懂的地方,需要注意的是我在原有代码的基础上对空值进行的处理,在查询时如果表中的数据是空值的话那么我把字段对应的Java类型放到Row对象里,因为在进行Row对象到值对象的转换时用到了java反射API必须知道Row中的字段值的类型才能去调用值对象的setXXXX方法(见Row对象的toValueObject方法)。

行对象的源码如下:

package com.gdrj.util.database;
import java.util.*;
import java.math.BigDecimal;
import java.lang.reflect.*;
public class Row
参考技术A 关系数据库实现U/ C 矩阵的可行性
关系数据库最早见于60 年代。从70 年代开
始,著名的计算机专家E. F. Codd 先后发表了几篇论
文,提出关系数据库概念,引入数据库子语言,为关
系数据库的全面发展奠定了坚实的理论基础。此
后,关系数据库无论在理论上或是在实践上均得到
了全面的发展。关系描述对象结构清晰,易于理解,
用二维表即可描述实体对象。在数据库操作上采用
了非过程化的SQL 描述性语言,使用方便,不涉及任
何数据存储细节,具有较高的数据独立性。因此关
系数据库已被广泛地应用到各个领域。
U/ C矩阵是一个二维表,其特点是用列表示数据
类,用行表示功能项。求解U/ C 矩阵通常采用人工
调整方法。此方法十分繁杂,易于出错。因此必须研
究系统化的方法,利用计算机本身完成U/ C 矩阵的
求解。在关系中列称为属性,用于描述对象的特性,行称为元组,用于描述某个特定对象。若把U/ C 矩
阵的功能项视作元组,数据类视作属性,就可方便地
用关系存储U/ C 矩阵,利用RDBMS 现有的操作,实
现U/ C矩阵求解。本回答被提问者采纳
参考技术B What's U/C matrix?

以上是关于那位大哥能帮我设计一个数据库框架(access)的主要内容,如果未能解决你的问题,请参考以下文章

那个大哥能帮小弟做一下下面的题我做了不对,请用java和python帮我做一下我看看是那里不懂。

那位大哥大姐帮忙我下面一段摘要翻译成英文

谁能帮我将 Access Query 转换为 MS SQL Query

我有“不存在'Access-Control-Allow-Origin'标头。”谁能帮我将其转换为 POST 类型的 JSONP? [复制]

Access 2016 更新查询

那位大哥帮帮忙、、、MMC