J2ee开发用到的数据库操作类大全

J2ee项目开发过程中用到的数据库操作类

此数据库操作封装类在一个省级项目中使用到,在一个集团公司的科技管理项目中也使用过.

 

package jing.dbnew;

import java.sql.*;
import java.util.*;
import javax.sql.rowset.CachedRowSet;
import oracle.jdbc.rowset.OracleCachedRowSet;
import com.sun.rowset.CachedRowSetImpl;
/**
 * Title:数据库操作类,有数据事物控制功能,请注意main函数中的调用事例
 * @author 欧朝敬
 * QQ:35712069
 * 手机:13873195792
 * @version 1.0
 */
public class DBManager {
 public DBManager(){
  
 }

 /**
  * 开始事务
  *
  */
 public void beginTransaction() {
  try {
   Connection con = ConnectionFactory.getInstance().getConnection();
   con.setAutoCommit(false);
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 /**
  * 回滚事务
  *
  */
 public void rollbackTransactoin() {
  try {
   Connection con = ConnectionFactory.getInstance().getConnection();
   con.rollback();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**
  * 提交事务
  *
  */
 public void commitTransaction() {
  try {
   Connection con = ConnectionFactory.getInstance().getConnection();
   con.commit();
   con.setAutoCommit(true);
   ConnectionFactory.getInstance().closeConnection();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 /**
  * 结束事务
  *
  */
// public void endTransaction() {
//  try {
//   Connection con = ConnectionFactory.getInstance().getConnection();
//   con.commit();
//   con.setAutoCommit(true);
//   ConnectionFactory.getInstance().closeConnection();
//  } catch (Exception e) {
//   e.printStackTrace();
//  }
// } 
 
 
 public boolean execute(String sql) throws Exception {
  System.out.println("execute:" + sql);
  boolean re = false;
  Connection con = null;
  PreparedStatement pstmt = null;
  try {
   con = ConnectionFactory.getInstance().getConnection();
   pstmt =con.prepareStatement(sql);
   re = pstmt.execute();
  }catch(Exception ex){
   ex.printStackTrace();
   con.rollback();
  } finally {
   if (pstmt != null) {
    pstmt.close();
   }
  }
  return re;
 }

 /**
  * 批量执行SQL语句,在一个事物里
  * @param sql
  * @return
  * @throws Exception
  */
 public int[] executeBatch(String[] sql) throws Exception {
  int[] re=null;;
  Connection con = null;
  Statement stmt = null;
  try {
   con = ConnectionFactory.getInstance().getConnection();
   con.setAutoCommit(false);
   stmt =con.createStatement();
   stmt.clearBatch();
   for(int i=0;i<sql.length;i++){
    stmt.addBatch(sql[i]);
    System.out.println("executeBatch:" + sql[i]);
   }
   re = stmt.executeBatch();
   con.commit();
  }catch(Exception ex){
   ex.printStackTrace();
   con.rollback();
  }
  finally {
   if (stmt != null) {
    stmt.close();
   }
  }
  return re;
 }
 
 /**
  *
  * @param sql
  * @param value
  * @param type
  * @return
  * @throws Exception
  */
 public boolean execute(String sql, String[] value, int[] type)
 throws Exception {
  System.out.println("execute:" + sql);
  boolean re = false;
  Connection con = null;
  PreparedStatement pstmt = null;
  try {
   con = ConnectionFactory.getInstance().getConnection();
   pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
     ResultSet.CONCUR_UPDATABLE);
   this.setParameters(pstmt,value,type);  //调用私有方法设置参数
   re = pstmt.execute();
  } catch(Exception ex){
   ex.printStackTrace();
   con.rollback();
  }finally {
   if (pstmt != null) {
    pstmt.close();
   }
  }
  return re;
 } 

 /**
  * 执行查询,返回结果集 隐式事物处理
  * @param sql String 要执行的SELECT语句
  * @return CachedRowSet 未查到记录则返回null
  * @throws Exception
  */
 public CachedRowSet executeQueryCachedRowSet(String sql) throws Exception {
  System.out.println("executeQueryCachedRowSet:" + sql);
  CachedRowSet crs = null;
  //OracleCachedRowSet crs=null;
  Connection con = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  try {
   con =  ConnectionFactory.getInstance().getConnection();
   /*stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
    * java.sql.SQLException: 不允许的操作: Unsupported syntax for refreshRow()
    * Oracle: Unsupported syntax for refreshRow()报此错使用以下方式解决
    * 1、con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
    * 2、con.createStatement();
   */
   pstmt=con.prepareStatement(sql);
   rs = pstmt.executeQuery();
   if (!(rs.isBeforeFirst() == rs.isAfterLast())) {
    crs = new CachedRowSetImpl();
    //crs = new OracleCachedRowSet();
    crs.populate(rs);
   }
  } catch(Exception ex){
   ex.printStackTrace();
   con.rollback();
  }finally {
   if (rs != null) {
    rs.close();
   }
   if (pstmt != null) {
    pstmt.close();
   }
  }
  return crs;
 }

 
 /**使用OracleCachedRowSet实现,专门处理Oracle特有的SQL语句
  * 执行查询,返回结果集 隐式事物处理
  * @param sql String 要执行的SELECT语句
  * @return OracleCachedRowSet 未查到记录则返回null
  * @throws Exception
  */
 public OracleCachedRowSet executeQueryOracleCachedRowSet(String sql) throws Exception {
  System.out.println("executeQueryOracleCachedRowSet:" + sql);
  OracleCachedRowSet crs=null;
  Connection con = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  try {
   con = ConnectionFactory.getInstance().getConnection();
   /*stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
    * java.sql.SQLException: 不允许的操作: Unsupported syntax for refreshRow()
    * Oracle: Unsupported syntax for refreshRow()报此错使用以下方式解决
    * 1、con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
    * 2、con.createStatement();
   */
   pstmt=con.prepareStatement(sql);
   rs = pstmt.executeQuery();
   if (!(rs.isBeforeFirst() == rs.isAfterLast())) {
    crs = new OracleCachedRowSet();
    crs.populate(rs);
   }
  }catch(Exception ex){
   ex.printStackTrace();
   con.rollback();
  } finally {
   if (rs != null) {
    rs.close();
   }
   if (pstmt != null) {
    pstmt.close();
   }
  }
  return crs;
 }
 
 /**
  * 执行高效率的SELECT语句,使用ORACLE的SQL特点
  * @param sql String 带?号的SELECT语句
  * @param value String[] ?对应的值
  * @param type int[] ?对应的值的数据库表中的类型
  * @return CachedRowSet 未查到记录则返回null
  * @throws Exception
  */
 public CachedRowSet executeQueryCachedRowSet(String sql, String[] value,
   int[] type) throws Exception {
  System.out.println("executeQueryRowSet:" + sql);
  CachedRowSet crs = null;
  Connection con = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  try {
   con = ConnectionFactory.getInstance().getConnection();
   pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
     ResultSet.CONCUR_UPDATABLE);
   this.setParameters(pstmt,value,type);  //调用私有方法设置参数
   rs = pstmt.executeQuery();
   if (!(rs.isBeforeFirst() == rs.isAfterLast())) {
    crs = new CachedRowSetImpl();
    crs.populate(rs);
   }
  }catch(Exception ex){
   ex.printStackTrace();
   con.rollback();
  } finally {
   if (rs != null) {
    rs.close();
   }
   if (pstmt != null) {
    pstmt.close();
   }
  }
  return crs;
 }


 /**
  * 执行查询,返回Map单条记录,如查执行结果有多条记录的情况下也只返回第一条记录 隐式事物处理
  * @param sql String 要执行的SELECT语句
  * @return Map 未查到记录则返回null,使用列名的大家做为Map的Key,列值对象为Map的value
  * @throws Exception
  */
 public Map executeQueryMap(String sql) throws Exception {
  System.out.println("executeQueryMap:" + sql);
  Map map = null;
  Connection con = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  try {
   con = ConnectionFactory.getInstance().getConnection();
   pstmt =con.prepareStatement(sql);
   rs = pstmt.executeQuery();
   if (rs.next()) { // 有记录的情况
    map = new HashMap();
    ResultSetMetaData rsm = rs.getMetaData();
    int colnum = rsm.getColumnCount(); // 得到记录的列数
    for (int i = 1; i <= colnum; i++) {
     // rsm.getColumnName(i).toUpperCase()统一列名大写
     // rs.getObject(i)更的值为对象类型
     map
       .put(rsm.getColumnName(i).toUpperCase(), rs
         .getObject(i));
    }
   }
  } catch(Exception ex){
   ex.printStackTrace();
   con.rollback();
  }finally {
   if (rs != null) {
    rs.close();
   }
   if (pstmt != null) {
    pstmt.close();
   }
  }
  return map;
 }


 /**
  * 执行高效率的SELECT语句,使用ORACLE的SQL特点
  * @param sql  String 带?号的SELECT语句
  * @param value String[] ?对应的值
  * @param type int[] ?对应的值的数据库表中的类型
  * @return Map 未查到记录则返回null,使用列名的大家做为Map的Key,列值对象为Map的value
  * @throws Exception
  */
 public Map executeQueryMap(String sql, String[] value, int[] type)
   throws Exception {
  System.out.println("executeQueryMap:" + sql);
  Map map = null;
  Connection con = null;
  PreparedStatement pstmt = null;
  ResultSet rs = null;
  try {
   con = ConnectionFactory.getInstance().getConnection();
   pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
     ResultSet.CONCUR_UPDATABLE);
   this.setParameters(pstmt,value,type);  //调用私有方法设置参数
   rs = pstmt.executeQuery();
   if (rs.next()) { // 有记录的情况
    map = new HashMap();
    ResultSetMetaData rsm = rs.getMetaData();
    int colnum = rsm.getColumnCount(); // 得到记录的列数
    for (int i = 1; i <= colnum; i++) {
     // rsm.getColumnName(i).toUpperCase()统一列名大写
     // rs.getObject(i)更的值为对象类型
     map
       .put(rsm.getColumnName(i).toUpperCase(), rs
         .getObject(i));
    }
   }
  } catch(Exception ex){
   ex.printStackTrace();
   con.rollback();
  }finally {
   if (rs != null) {
    rs.close();
   }
   if (pstmt != null) {
    pstmt.close();
   }
  }
  return map;
 }


 /**
  * 执行更新语句INSERT,UPDATE or DELETE
  * @param sql String 要执行的SQL语句
  * @return int 如果执行INSERT,UPDATE or DELETE则返回影响的记录行数,如果执行没有返回值的语句则返回为0
  * @throws Exception
  */
 public int executeUpdate(String sql) throws Exception {
  System.out.println("executeUpdate:" + sql);
  int re = 0;
  Connection con = null;
  PreparedStatement pstmt = null;
  try {
   con = ConnectionFactory.getInstance().getConnection();
   pstmt = con.prepareStatement(sql);
   re = pstmt.executeUpdate();
  }catch(Exception ex){
   ex.printStackTrace();
   con.rollback();
  } finally {
   if (pstmt != null) {
    pstmt.close();
   }
  }
  return re;
 }


 /**
  * 执行更新语句INSERT,UPDATE or DELETE
  * @param sql String 要执行的带有?号的INSERT,UPDATE or DELETE语句
  * @param value String[] ?对应的值
  * @param type int[] ?对应的值的数据库表中的类型
  * @return int 如果执行INSERT,UPDATE or DELETE则返回影响的记录行数,如果执行没有返回值的语句则返回为0
  * @throws Exception
  */
 public int executeUpdate(String sql, String[] value, int[] type)
   throws Exception {
  System.out.println("executeUpdate:" + sql);
  int re = 0;
  Connection con = null;
  PreparedStatement pstmt = null;
  try {
   con = ConnectionFactory.getInstance().getConnection();
   pstmt = con.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE,
     ResultSet.CONCUR_UPDATABLE);
   this.setParameters(pstmt,value,type);  //调用私有方法设置参数
   re = pstmt.executeUpdate(); // 影响的记录行数
  }catch(Exception ex){
   ex.printStackTrace();
   con.rollback();
  } finally {
   if (pstmt != null) {
    pstmt.close();
   }
  }
  return re;
 }

 /**
  私有方法用来设置
  * @param pstmt PreparedStatement对象的参数
  * @param value  参数值
  * @param type   参数类型
  * @throws Exception
  */
 private void setParameters(PreparedStatement pstmt,String[] value,int[] type)throws Exception{
  int j = 1;
  for (int i = 0; i < value.length; i++) {
   switch (type[i]) {
   case Types.INTEGER:
    pstmt.setInt(j, Integer.parseInt(value[i]));
    System.out.println("Parameter("+i+")    INTEGER      "+value[i]);
    break;
   case Types.FLOAT:
   case Types.DOUBLE:
   case Types.DECIMAL:
   case Types.NUMERIC:
    pstmt.setDouble(j, Double.parseDouble(value[i]));
    System.out.println("Parameter("+i+")    FLOAT、DOUBLE、DECIMAL、NUMERIC      "+value[i]);
    break;
   case Types.CHAR:
   case Types.VARCHAR:
   case Types.LONGVARCHAR:
    pstmt.setString(j, value[i]);
    System.out.println("Parameter("+i+")    CHAR、VARCHAR、LONGVARCHAR      "+value[i]);
    break;
   case Types.DATE:
   case Types.TIMESTAMP:
    pstmt.setString(j, value[i]);
    System.out.println("Parameter("+i+")    DATE、TIMESTAMP      "+value[i]);
    break;
   case Types.BOOLEAN:
    // Boolean.parseBoolean(value[i]) JDK5API
    pstmt.setBoolean(j, Boolean.getBoolean(value[i]));
    System.out.println("Parameter("+i+")    BOOLEAN      "+value[i]);
    break;
   }
   j = j + 1;
  }
 }
 

 /**
  * 执行记录的查询(调用存储过程)
  * @param procName:调用存储过程的名称;
  * @param returnType:游标返回类型
  * 0为CachedRowSet以及各种类型
  * @param outParameter:传入输出参数的类型,例如:new int[]{Types.REF,Types.REF,Types.VARCHAR},
  * 表示所调用的存储过程前两个输出结果的类型为游标类型,第三个输出结果的类型为VARCHAR2类型。
  * @param args       所调用存储过程的输入参数
  * @return List<Object> 存储过程的输出结果
  *
  */
 public List<Object> executeProc(String procName,int returnType,int[] outParameter,Object... args) throws Exception {
  List<Object> list = null;
  Connection con = null;
  CallableStatement cstmt = null;
  try {
   con = ConnectionFactory.getInstance().getConnection();
   int iInStart = 1;// 存储过程输入参数的起始位
   // 统计问号的个数
   int parameterCount = args.length+outParameter.length; //调用的存储过程的总参数个数
   // 组装带问号的SQL
   String sql = "{call " + procName + "(";
   for (int i = 1; i <= parameterCount; i++) {
    if (i == parameterCount){
     sql += "?";
    }else{
     sql += "?,";
    }
   }
   sql += ")}";
   System.out.println("executeProc:"+sql);
   cstmt = con.prepareCall(sql);
   for (int i = 0; i < args.length; i++) {// 循环设定存储过程的输入参数
    cstmt.setObject(iInStart + i, args[i]);
    System.out.println("设置输入参数:"+iInStart+"  "+args[i]);
   }
   int iOutStart = args.length + iInStart;// 存储过程输出参数的起始位
   for (int i = 0; i < outParameter.length; i++) {// 循环设定存储过程的输出参数
    if (outParameter[i]==Types.REF){ //代表游标
     cstmt.registerOutParameter(i + iOutStart, oracle.jdbc.driver.OracleTypes.CURSOR);
     System.out.println("设置输出参数:"+(i + iOutStart)+" 游标");
    }else if((outParameter[i]==Types.INTEGER)){
     cstmt.registerOutParameter(i + iOutStart, Types.INTEGER);
     System.out.println("设置输出参数:"+(i + iOutStart)+" 数值型");
    }else{
     cstmt.registerOutParameter(i + iOutStart, Types.VARCHAR);
     System.out.println("设置输出参数:"+(i + iOutStart)+" 字符型");
    }
   }
   cstmt.execute();  //执行
   list = new ArrayList<Object>();
   switch (returnType) {
   case 0:// 把存储过程中返回的游标转换为CachedRowSet类型输出
    for (int i = 0; i < outParameter.length; i++) {// 循环获取存储过程的输出结果,包括游标、字符串
     if (outParameter[i]==Types.REF) { //处理游标
      CachedRowSet crs=new CachedRowSetImpl();
      //OracleCachedRowSet crs=new OracleCachedRowSet();  //使用Oracle10g的数据则必须要用10g的驱动,Oracle 10g驱动解决了“ORA-01002: 读取违反顺序”这个问题
      if (cstmt.getObject(i + iOutStart) != null){
       crs.populate((ResultSet)cstmt.getObject(i + iOutStart));
      }
      list.add(crs);
     } else{ //非游标
      list.add(cstmt.getObject(i + iOutStart));
     }
    }
    break;
   }
  } catch (Exception ex) {
   ex.printStackTrace();
   con.rollback();
  } finally {
   cstmt.close();
  }
  return list;
 } 

 public static void main(String[] args) throws Exception {
  //DBManager dbm = new DBManager();
  //dbm.execute("update dept set dname=? where deptno=? ",new String[]{"sdfsdfsad","51"},new int[]{Types.VARCHAR,Types.NUMERIC});
  // Connection con = SingletonDataSource.getInstance().getConnection();
  // CachedRowSet crs = dbm.executeQueryRowSet(
  // "SELECT EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO FROM EMP WHERE
  // EMPNO >7654",
  // con);
  // while (crs.next()) {
  // System.out.println(crs.getString("EMPNO") + " " +
  // crs.getString("ENAME"));
  // }
  // System.out.println("########################");
  // Map map = dbm.executeQueryMap(
  // "SELECT EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO FROM EMP WHERE
  // EMPNO=7654",
  // con);
  // System.out.println(map.get("EMPNO") + " " + map.get("ENAME") + " " +
  // map.get("COMM"));
  // con.close();
  /*
   * String sql = "select * from emp where comm=?"; String[] value = new
   * String[] {"500"}; int[] type = {Types.DOUBLE}; Map map =
   * dbm.executeQueryMap(sql, value, type, null); //Map map =
   * dbm.executeQueryMap("select * from emp where empno=? and ename=?",new
   * String[] {"7654","MARTIN"},new int[]{Types.INTEGER,Types.VARCHAR},
   * null); if (map != null) { System.out.println(map.get("EMPNO") + " " +
   * map.get("ENAME")); }
   */
  /*
   * String sql = "select * from emp where empno>?"; String[] value = new
   * String[] {"7693"}; int[] type = {Types.INTEGER}; CachedRowSet crs =
   * dbm.executeQueryRowSet(sql, value, type, null); boolean isprint =
   * true; while (crs.next()) { ResultSetMetaData rsmd =
   * crs.getMetaData(); int colcount = rsmd.getColumnCount(); if (isprint) {
   * isprint=false; for (int i = 0; i < colcount; i++) {
   * System.out.print(rsmd.getColumnName(i + 1) + "/t/t"); }
   * System.out.println(); } for (int i = 0; i < colcount; i++) {
   * System.out.print(crs.getString(i + 1)+"/t/t"); }
   * System.out.println(); }
   */
  /*
   * String sql = "update emp set comm=? where comm=?"; String[] value =
   * new String[] {"56.22", "0"}; int[] type = {Types.DOUBLE,
   * Types.INTEGER}; System.out.println(dbm.executeUpdate(sql, value,
   * type, null));
   */
  // System.out.println(dbm.selectList("test", "empno", "ename", true,
  // "","select * from emp", null, null));
  
  
  //DBManager dbmt = new DBManager();
/*  //有事物操作示例
   dbmt.beginTransaction();
  try{
   dbmt.execute("insert into emp values (1234, 'TEST', 'TEST', 0, to_date('2008-03-12', 'yyyy-mm-dd'), 0, 0, 10)");
   dbmt.execute("insert into emp values (1235, 'TEST', 'TEST', 0, to_date('2008-03-12', 'yyyy-mm-dd'), 0, 0, 10)");
   //dbmt.commitTransaction();
  }catch(Exception ex){
   dbmt.rollbackTransactoin();
  }*/
  //自动事物处理
  //dbmt.execute("insert into emp values (1236, 'TEST', 'TEST', 0, to_date('2008-03-12', 'yyyy-mm-dd'), 0, 0, 10)");
 }

}

 

 

package jing.dbnew;

import java.sql.*;
import javax.sql.*;
import javax.naming.*;

/**
 * <p>
 * Title: 使用单实例进行数据库连接池中的数据库连接获取
 * @author 欧朝敬
 * QQ:35712069
 * 手机:13873195792
 * @version 1.0
 */
public class ConnectionFactory {
 private static DataSource ds = null;
 private static ConnectionFactory cf = new ConnectionFactory();
 private static final ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>(); //线程本地变量

 private ConnectionFactory() {
  try {
   InitialContext ctx = new InitialContext();
   // 使用时改成正确的数据配置
   //ds = (DataSource) ctx.lookup("jdbc/OracleSource");
   //TomCat中的连接池获取方式使用java:/comp/env/
   ds = (DataSource) ctx.lookup("java:/comp/env/jdbc/OracleSource");
  } catch (NamingException ne) {
   System.out.println(ne.getMessage() + "/n没有使用连接池!");
  }
 }

 public static ConnectionFactory getInstance() {
  return cf;
 }

 
 public Connection getConnection() throws Exception {
  Connection con = threadLocal.get();
  if (con == null) {
   if (ds == null) {
    // 使用时改成正确的数据配置
    Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
    String url = "jdbc:oracle:thin:@localhost:1521:sample";
    con = DriverManager.getConnection(url, "scott", "tiger");
   } else {
    con = ds.getConnection();
   }
   //System.out.println("未使用线程中的连接!");
   threadLocal.set(con);
  }else{
   //System.out.println("使用线程中的连接!");
  }
  return con;
  /**
   * 如果不做Main方法的调试则使用如下方法体 return ds.getConnection();
   */
 }

 /**
  * 关闭连接<br>
  * 同时删除当前线程关联的连接对象,Client不能对用getConnection()方法获得的连接直接调用con.close()方法,必须使用此方法closeConnection()进行连接的关闭
  */
 public void closeConnection() {
  Connection con = threadLocal.get();
  if (con != null) {
   try {
    con.close();
    threadLocal.set(null);
    con=null;
   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 }

 public static void main(String[] args) throws Exception {
  /**
   * 调用方式如下
   */
  Connection con =ConnectionFactory.getInstance().getConnection();
  ConnectionFactory.getInstance().closeConnection();
  con.createStatement();
 }
}

 

-------------------------------------------------------------------------------------------------

毕业后头五年决定你的一生                                    海量Android教程、开发资料和源码

10类最急需IT人才:Java开发者居首                   给将成为“Android高手”的10个建议 

成为Java高手的25个学习目标--非常经典           Android 4.1果冻豆新特性详解 

芯片巨头海思和展讯:给中国芯片业带来信心    海量经典Java教程、学习资料和源码

Java侵权诉讼Google获胜,Android厚积薄发       面试必备:Android笔试总结 

Android高手必须掌握的28大内容和10个建议     Android平台研发人才缺口30万 

Android开发环境安装和配置步骤详细图解        2012国内移动App开发者大调查结果 

Windows 7下搭建android开发环境步骤图解      Android 4.0的30个突出的新特性 

Android高手要经过的6个阶段和6个境界           linux下搭建Android开发环境步骤 

从IT菜鸟变为“IT骨干开发者”的11个建议        程序员编程技术迅速提高的终极攻略 

2012世界各国人均GDP排名,中国超泰国           2012年全国各省平均工资排行 

2012年中国大学高校排行榜(580强排名)      中国各省市面积和人口数量排名 

中国百万开发者大调查:程序员的薪水不错     Java高手需要越过的10座高山

周立功谈嵌入式:我的25年嵌入式生涯           Android和Java语言的异同和关系 

华为中国区手机销量达千万,80%为智能机        谷歌Android碎片化严重

2012年中国各省GDP和人均GDP排名              90后就业“钱景”:IT仍是最佳选择

2012全球城市竞争力500强,69个中国城市上榜   不要做浮躁的软件工程师 

2012年世界500强,79家大陆香港台湾公司上榜名单 给IT新兵的15个建议 

美国知名科技公司入门级软件工程师的薪水排名  回顾Java经过的风风雨雨 

71道经典Android面试题和答案--重要知识点都涉及到了 

高校应届毕业生“IT业”收入最高,Android技术最热门 

 


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第一章 绪论 1.1. 选题背景 这几年,许多新名词涌入我们的视野:博客、圈子、播客、WAP等。这些都预示着我们进入了一个新的互联网阶段web 2.0,它是相对web 1.0的新的一互联网应用的总称,是一次从核心内容到外部应用的革命[10]。这个阶段发展迅速,互联网应用趋于多样化,其中变化最大的是由web 1.0网站创造内容的时代变为由用户创造内容的web 2.0时代。 在web 2.0应用中,博客(Blog)是web 2.0核心应用中最典型、最流行的代表之一,也是web 2.0技术应用的最直观的表现,是web 2.0精神和理念的具体体现。 1.2. 问题的提出 Blog记载了日常发生的事情和自己的兴趣爱好,把自己的思想和知识和他人分享、交流,同时又通过“六度空间”结识了更多志趣相投的朋友;而越来越多专业知识的 Blog 的出现,让我们看到了 Blog 更多所蕴涵的巨大的信息价值:不同的 Blog 选择不同的内容,收集和整理成为很多人关注的专业 Blog ——目前越来越多的人获取信息的来源是一些固定的 Blog 。随着博客人数的增加, Blog 作为一种新的生活方式、新的工作方式、新的学习方式已经被越来越多的人所接受,并且在改变传统的网络和社会结构:网络信息不再是虚假不可验证的,交流和沟通更有明确的选择和方向性,单一的思想和群体的智慧结合变的更加有效,个人出版变成人人都可以实现的梦想—— Blog 正在影响和改变着我们的生活。 1.3. 系统的开发目标 管理员通过前台页面进入后台管理模块后,可对注册的博客用户进行维护,包括对注册用户的添加、查找、修改和删除。 管理员进入登录后,可对帐户进行管理,包括添加管理员帐户、修改管理员帐户、删除管理员帐户和对帐户进行权限设置。 博客用户通过前台登录后,可对自己的博客空间进行管理,包括发布自己的网络日志、收藏个人图片、和相关人员进行交流和沟通以及删除访问者发表的评论等。 因此,在具体设计实现该博客网站时,主要考虑了主流博客网站的几个主要功能:(1)博客的注册、登录验证功能(2) 网络用户通过关键字搜索博文功能(3) 最热门博客页面推荐浏览(4) 文章详细内容及相关评论显示(5) 博客页面访问量统计(6) 博客个人文章管理维护功能(7) 博客个人文章分管理维护功能(8) 博客个人友情链接维护功能(9) 博客个人基本信息管理维护功能(10) 博客图片上传及个人相册管理(11) 网络用户写留言,博主查看留言。 第二章 系统设计 2.1. 系统分析 在整个blog进行开发之前,要确定出整个项目的整体架构,包括系统的选型、运行环境的确定及系统结构设计。下面对这进行详细介绍。 在进行软件系统开发的最初环节,一般都需要进行系统的选型,即根据系统功能的实际需求,选择合适的开发工具及软件架构。 blog对系统的可靠性、稳定性有比较高的要求。本系统设计时,比较主流的B/S设计有基于JSP、ASP、PHP、CGI及J2EE等模式。相比较而言PHP的功能相对简单,不适合做大程序;而CGI效率相对较低,所以也不考虑。由于J2EE的开源的框架中提供了MVC模式实现框架Struts、对象关系模型中的Hibernate 的框架及拥有事务管理和依赖注入的Spring。利用现存框架可以更快开发系统。所以选择Java技术作为blog 的开发工具。 为了增加系统的吞吐量,提高并发处理客户请求数量,系统采用了IBM服务器作为主机。在数据库处理方面,不需要在数据层借助存储过程及数据库服务器端函数封装过多的业务逻辑,因此数据库系统采用相对精巧的MySQL[6]。 该在线博客系统服务器端如果需要布置到其他主机上,则该主机必备条件如下: 1. 服务器端操作系统:独立于操作系统的跨平台系统,客户端MicroSoft Windows 2000及以上; 2. 数据库:MySQL 5.0.27版本; 3. Web服务器:Tomcat 5.5及以上版本,配合MVC设计模式及 Hibernate开发架构; 4. 客户端运行环境:能运行IE 5以上或Netscape 5以上浏览器的操作系统,配合使用Ajax技术; 5. 客户端运行工具:目前的系统采用浏览器作为客户端,为了支持Ajax开发框架,应该选择使用IE 5以上版本浏览器。 本网站以xp为Web平台,JSP+Ajax+Servlet+JavaBean+Hibernate为网站实现技术,建立基于MySQL数据库系统的核心动态网页,实现博客网站前台及博客个人维护管理等功能模块。 1、 系统处理的准确性和及时性:系统处理的准确性和及时性是系统的必要性能。在系统设计和开发过程中,要充分考虑系统当前和将来可能承受的工作量,使系统的处理能力和响应时间能够满足信息处理的需求。 2、 系统的开放性和系统的可扩充性:系统在开发过程中,应该充分考虑以后的可扩充性。例如数据表中用户选择字段方式的改变,用户查询的需求也会不断的更新和完善。所有这些,都要求系统提供足够的手段进行功能的调整和扩充。而要实现这一点,应通过系统的开放性来完成,既系统应是一个开放系统,只要符合一定的规范,可以简单的加入和减少系统的模块,配置系统的硬件。通过软件的修补、替换完成系统的升级和更新换代。 3、 系统的易用性和易维护性:要实现这一点,就要求系统应该尽量使用用户熟悉的术语和中文信息的界面;针对用户可能出现的使用问题,要提供足够的在线帮助,缩短用户对系统熟悉的过程。 4、 系统的数据要求:1、数据录入和处理的准确性和实时性。2、数据的一致性与完整性。3、数据的共享与独立性。 2.2. 系统的可行性分析 2.2.1. 技术可行性 技术上的可行性分析要考虑将来要采用的硬件和软件技术能否满足用户(这里是服务器,网速)提出的要求(如计算机的容量、速度等)。此外,还要考虑开发人员的水平,学习了两年的jsp开发,对于这个系统的编写,我想完整的之需要两个月就可以写出程序,再花上几天的调试,计划两个月左右就可以完成投入使用了。 我们掌握了数据库及其应用技术、数据库原理、计算机网络技术等课程,对数据库的设计、应用、维护及局域网的组成有了深刻的认识与一定的动手实践能力,考取了信息处理、程序设计、数据库技术等国家IT认证。从一定程度上具备了开发一个小型系统的能力。再有就! 2.2.2. 经济可行性 主要从对项目的经济上进行分析评价,一方面是支出的费用,包括设备购置费、管理和维护费用、人员工资和培训费等,另一个是取得的收益。这是个小型的系统,从投入的人力,财力与物力来讲是非常小的,发布出去之需要注册域名就可以了,从节省人力方面,可以让管理人员从繁与复杂的工作中解脱出来,做更多的工作。 2.2.3. 管理可行性 有IP地址、用户名与密码等,可以下载一个FTP上传工具(cure)上传更新后的内容.可以在http://www.skycn.com/soft/683.html下载到. 下载以后,通过"站点管理"-->"新建站点".输入IP,用户名,密码.然后连接即可. 当然也可用FTP工具.直接在IE浏览器地址栏输入ftp://www.域名/然后输入用户名和密码.同样可以上传.随时更新文件! 第三章 开发环境的说明与安装 3.1. 开发语言的选择 3.1.1. JAVA简介 Java是Sun公司推出的新的一代面向对象程序设计语言,特别适合于Internet应用程序开发。Java的产生与流行是当今Internet发展的客观要求,Java是一门各方面性能都很好的编程语言,它的基本特点是简单、面向对象、分布式、解释的、健壮的、安全的、结构中立的、可移植的、性能很优异的、多线程的、动态的,特别适合在Internet环境上开发的应用系统。 3.1.2. Web应用程序开发环境—JSP技术 JSP的全称是Java Server Pages,它是SUN推出的一种动态网页技术标准。它在传统的静态页面文件(*.html,*.htm)中加入JAVA程序片段和JSP标记,就构成了JSP页面。JSP具有以下的优点: 1、将业务层与表示层分离:使用JSP技术,网络开发人员可充分使用HTML来设计页面显示部分(如字体颜色等),并使用JSP指令或者JAVA程序片段来生成网页上的动态内容; 2、能够跨平台:JSP支持绝大部分平台,包括现在非常流行的LINUX系统,应用非常广泛的Apache服务器也提供了支持JSP的服务; 3、组件的开发和使用很方便:如ASP的组件是由C++,VB等语言开发的,并需要注册才能使用;而JSP的组件是用Java开发的,可以直接使用; 4、一次编写,处处运行:作为JAVA开发平台的一部分,JSP具有JAVA的所有优点,包括Write once , Run everywhere. 3.2. 数据库的选择 3.2.1. Web应用程序开发环境—SQLserver数据库 SQL Server是由Microsoft开发和推广的关系数据库管理系统(DBMS),它最初是由Microsoft、Sybase和Ashton-Tate三家公司共同开发的。SQL Server 2000是Microsoft公司于2000年推出的最新版本。 SQL Server 特点:   1.真正的客户机/服务器体系结构。   2.图形化用户界面,使系统管理和数据库管理更加直观、简单。   3.丰富的编程接口工具,为用户进行程序设计提供了更大的选择余地。   4.SQL Server与Windows NT完全集成,利用了NT的许多功能,如发送和接受消息,管理登录安全性等。SQL Server也可以很好地与Microsoft BackOffice产品集成。   5.具有很好的伸缩性,可跨越从运行Windows 95/98的膝上型电脑到运行Windows 2000的大型多处理器等多种平台使用。   6.对Web技术的支持,使用户能够很容易地将数据库中的数据发布到Web页面上。   7.SQL Server提供数据仓库功能,这个功能只在Oracle和其他更昂贵的DBMS中才有。   SQL Server 2000与以前版本相比较,又具有以下新特性 :   1.支持XML(Extensive Markup Language,扩展标记语言)   2.强大的基于Web的分析   3.支持OLE DB和多种查询   4.支持分布式的分区视图   安装、运行SQL Server 2000的硬件需求   (1)计算机   Inter及其兼容计算机,Pentium 166Mz或者更高处理器或DEC Alpha和其兼容系统。   (2)内存(RAM)   企业版最少64MB内存,其他版本最少需要32MB内存,建议使用更多的内存。   (3)硬盘空间   完全安装(Full)需要180MB的空间,典型安装(Typical)需要170MB的空间,最小安装(Minimum)需要65MB的空间。 3.3. 开发工具的选择 MyEclipse,Deamweare,选择SQLserver作为后台的数据库,选择JAVA、JSP、JavaScript、Html作为应用程序开发工具,运用Tomcat服务器技术,整个系统完全基于B/S (Browser/Server)模式进行设计。 1、Tomcat应用服务器 目前支持JSP的应用服务器是较多的,Tomcat是其中较为流行的一个Web服务器,被JavaWorld杂志的编辑选为2001年度最具创新的Java产品,可见其在业界的地位。 Tomcat是一个免费的开源的Serlvet容器,在Tomcat中,应用程序的部署很简单,你只需将你的WAR放到Tomcat的webapp目录下,Tomcat会自动检测到这个文件,并将其解压。你在浏览器中访问这个应用的Jsp时,通常第一次会很慢,因为Tomcat要将Jsp转化为Servlet文件,然后编译。编译以后,访问将会很快。 Tomcat也具有传统的Web服务器的功能:处理Html页面。但是与Apache相比,它的处理静态Html的能力就不如Apache。我们可以将Tomcat和Apache集成到一块,让Apache处理静态Html,而Tomcat处理Jsp和Servlet。Tomcat是一个很好的工具,不仅仅因为其免费,功能强大,更因为其开放性,越来越受到人们的重视。 2、 B/S 开发模式 伴随着Internet的迅速发展,计算机技术正在由基于C/S(client/ Server)模式的应用系统转变为基于B/S模式的应用系统。 过去,网络软件的开发都采用C/S(client)模式,在这种模式下,主要的业务逻辑都集中于客户端程序,因此,必然导致以下问题: 系统安装、调试、维护和升级困难。由于客户端的硬件配置可能存在差异,软件环能各不相同,因此,在安装时,必须对每一个客户端分别进行配置,同样,在软件升级时也要对客户端分别处理。 B/S模式带来了巨大的好处: 开发成本及维护成本降低。由于B/S架构管理软件只安装在服务器端(Server)上,即应用程序在部署、升级、维护时,只需要在服务器端进行配置就可以了,网络管理人员只需要管理服务器就行了,用户界面主要事务逻辑在服务器(Server)端完全通过WWW浏览器实现,极少部分事务逻辑在前端(Browser)实现,所有的客户端只有浏览器,网络管理人员只需要做硬件维护。 良好的安全性能,防火墙技术可以保证后台数据库的安全性。所有的配置工作都集中在服务器端且所有客户端请求都是通过DBMS来访问数据库,从而大大减少了数据直接暴露的风险。 第四章 系统设计 4.1开发框架技术介绍 对于框架技术,我们采用Struts+ajax的整合! Struts是应用比较广泛的一种表现层框架 1、 Struts是一个为开发基于模型(Model)-视图(View)-控制器(Controller)(MVC)模式的应用架构的开源框架,是利用Servlet,JSP和custom tag library构建Web应用的一项非常有用的技术。由于Struts能充分满足应用开发的需求,简单易用,敏捷迅速。它使用服务层框架可以将JavaBeans从Jsp/Servlet中分离出来,而使用表现层框架则可以将Jsp中剩余的JavaBeans完全分离,这部分JavaBeans主要负责显示相关信息,一般是通过标签库(Taglib)实现,不同框架有不同自己的标签库,Struts是应用比较广泛的一种表现层框架。 2、 Ajax我们主要应用就是xmlhttprequest,回调函数实现局部刷新达道数据更新! 4.2需求分析 Blog网站主要是实现注册用户登录、管理相关信息、博文及相关评论、查看留言、友情链接、及图片的上传和图像的播放而为上网用户提供按博文主题搜索,查看注册用户的博文及提出相关评论,并为注册用户写留言,游览注册用户的相册、注册等功能的系统。下面就以两种不同的用户来分析博客网站的需求。 4.2.1注册博友 首先必须在博客首页中登录填写用户名和密码,这样才能执行一些相关操作,不然就是普通用户只能查看一些信息,而不能发表博文。可以在管理页面上添加博文的分,可以上传图片和游览自己的相册,在上传过程中可以将一张图片定义为自己的签名,在个人管理页面中注册用户还可以修改自己的个人信息。博文管理,友情链接管理及博文分管理,用例图2。 图2 博客管理页面的用例图 在博客主界面中发表博文时可以选择博文型,这样可以更好管理自己的博文。并查看和删除网友对自己的博文的一些评论、查看和删除网友留下的一些留言,提供与其他网友交流的空间。更好交流,在信息时代人们通过个人空间沟通也用来但不能在自己的博客主页面中提交评论和留言。。这样在本系统中就可以为博友提供更多的个人色彩。在管理页面中添加和删除友情连接。这样博友可以在自己空间中快速定位自己的关心的网站。这样还可以让网友看到自己的一些信息。友情链接及网页访问量统计显示:在博客的个人页面中还提供了推荐给普通网络用户的相关友情链接,此外,对个人页面的访问量也在随时进行统计,并在个人页面中进行直观的显示。 博客主页面的用例图如图3所示: 图3 博客主页面的用例图 4.2.2 普通用户 在博客注册页面注册成为博客的注册用户,才可以拥有自己独立的空间,进入某一博客页面查看相关文章信息时,可以随时对自己所感兴趣的文章发表评论,同时也可以查看到其他人针对该博文的评论。普通用户在阅读博文时可以在最后留下自己的一些评论。他也可以留下更多的信息。这样他可以写留言。这样他留下的信息就更快地被博友所看到。普通用户进入博友的用例图如图4所示: 图4上网博友在博客主页面的用例图 普通网友可以搜索自己关心的一些数据。并且在搜索结果中提供在结果范围内再次搜索。这样就可以将范围缩小。首页向注册用户提供登陆模块,注册用户在博客网站首页跟上网网友一样可以查看博客和博文推荐。上网网友可以注册成为博客用户,拥有自己独立的空间。这一模块的用例图如图5所示: 图5 博客首页的用例图 4.3 功能模块介绍 4.3.1 博客注册登录管理模块 博客注册登录管理模块用于建立博客网站固定的客户群体,通过记录对应的博客档案,实现对博客信息的后台维护及管理,同时也便于通过博客档案库将网站最新动态及相关企业的信息方便地传达给每一位潜在的客户。 该功能模块实现了以下几个子功能。 (1)新博客在线注册。 (2)博客登录管理。 (3)跳转到博客主页。 只有进行登录并通过身份验证的用户,才可以在个人博客页面发表日志,并借助个人设置实现对个人博客相关信息的管理维护。对于没有经过身份验证的网络用户不允许在博客页面中发表日志,更不允许对博客页面信息进行管理维护。 该模块实现新博客的注册及登录验证功能。其中,注册新博客时会对用户输入的注册信息进行有效性验证,包括基本数据格式的有效性以及逻辑有效性,例如,用户名被占用时将及时给出提示。注册成功的博客登录时,会随时根据博客输入的登录信息进行提示,如用户名错误或者密码错误。 4.3.2 博客及文章检索查询模块 博客及文章检索查询模块为网络用户提供便捷的搜索,以及日志阅读浏览等功能,同时对日志的评论信息、博客推荐也能够及时反馈给网络用户。 该功能模块实现了以下几个子功能。 (1)热门博客页面推荐。 (2)最新博客日志推荐。 (3)日志信息关键字搜索。 该模块能够在网页中随时提供在线的最新日志信息。该信息需要定期更新,网络用户可以随时获得最新日志以及最热门的博客推荐。在客户选择了某个博客或者某个感兴趣的日志后,可以方便地跳转到对应博客页面进行日志的阅读,并和博客进行交流互动。 为了使网络用户尽快定位到所需的博客资料及日志信息,本模块提供了搜索功能,用户可以对所关注的日志信息按照标题进行关键字搜索,以避免用户浏览多个页面来寻找所需的日志信息。 4.3.3博客页面显示模块 当网络用户进入某个人博客主页后,在该页面中将提供博客日志列表的显示,同时为了方便用户浏览,在该模块中提供根据分名进行日志列表的显示,也提供日志评论的浏览,此外还允许用户在博客页面中发表评论及留言。 该功能模块实现了如下几个子功能。 (1)用户可以分页查看对应的日志内容及评论信息。 (2)用户可以针对日志内容发表评论。 (3)用户可以针对博客进行留言。 (4)用户可以分查看日志内容。 在该模块中还提供了博客页面统计信息,日志、评论及留言信息分页显示等方便用户的显示效果。 4.3.4 博客个人维护管理模块 博客个人维护管理模块用于实现用户对博客个人主页及相关信息的动态管理。 该功能模块实现了如下几个子功能: (1)日志及日志分管理。 (2)评论及留言管理。 (3)个人基本信息维护管理。 借助该模块,用户可以随时对个人博客主页中的内容进行增加或修改,包括日志分信息的更新、评论及留言管理等功能,也允许用户对博客的个人信息进行维护及其管理。 4.4 系统分析 本系统采用严格的J2 EE 应用结构,主要有如下几个分层。 1. 表现层:由JSP 页面组成。 2. MVC 层:使用Struts框架。 3. 业务逻辑层:主要由Spring loC 容器管理的业务逻辑组件组成。 4. DAO 层:由7 个DAO 组件组成,实现必须继承Spring提供的HibernateDaoSupport。 5. Hibernate 持久层:由7 个PO 组成,并在Hibernate Session 管理下,完成数据库访问。 6. 数据库服务层:使用MySQL 数据库存储持久化数据。 系统的具体分层如图5 所示。 图6 系统结构图 在图6 黑色大方框内的MVC 控制层、Service 层及DAO 组件层的组件,都由Spring IOC 容器负责生成,并管理组件的实例(实例必须是单身模式的,本系统中的bean基本上是单身的)。 4.3.1系统架构说明 本系统不仅严格按MVC 模式设计,还按J2 EE 分层设计,将中间层严格分成业务逻辑层、DAO 层及数据持久层等。MVC 层的控制器绝对禁止持久层访问,甚至不参与业务逻辑的实现。表现层采用传统JSP 技术。 本系统采用的是典型的J2EE 三层结构,分为表现层、中间层(业务逻辑层)和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。Jsp广泛的应用和稳定的表现,为其作为表现层技术打下了坚实的基础。中间层采用的是流行的Spring+Hibernate ,为了将控制层与业务逻辑层分离,又细分为以下几种。 Web 层,就是MVC 模式里面的C,负责逻辑层和表现层的交互。调用业务逻辑层,并将业务数据返回给表现层作组织表现,该系统的MVC采用Struts框架。 Service 层(就是业务逻辑层),负责实现业务逻辑。业务逻辑层以DAO 层为基础,通过对DAO 组件的正面模式包装,完成系统所要求的业务逻辑。 DAO 层,负责与持久化对象交互。该层封装了数据的增、删、查、改的操作。 PO ,持久化对象。通过实体关系映射工具将关系型数据库的数据映射成对象,很方便地实现以面向对象方式操作数据库,该系统采用Hibernate 作为ORM 框架。Spring 的作用贯穿了整个中间层,将Web 层、Service 层、DAO 层及PO 无缝整合,其数据服务层用来存放数据。 通过使用Hibernate 持久层,可以避免使用传统的JDBC 操作数据库,对JDBC近一步包装,从而更好地使用面向对象的方式来操作数据库。保证了整个软件开发过程以面向对象的方式进行,即面向对象分析、设计及编程,透过Hibernte 对PO对象持久化操作,不管插入还是查询都是通过PO。 4.3.2实现DAO 层 DAO 还有助于提升系统的可移植性。独立的DAO 层使得系统能在不同的数据库之间轻易切换,底层的数据库实现对于业务逻辑组件是透明的。数据库移植时仅仅影响DAO 层,不同数据库的切换不会影响业务逻辑组件,因此提高了系统的可复用性。 对于不同的持久层技术, Spring 的DAO 提供一个DAO 模板,将通用的操作放在模板里完成,而对于特定的操作,则通过回调接口完成。Spring 为Hibernate 提供的DAO 支持是: HibernateDaoSupport。 4.3.3 DAO组件的定义 DAO 组件提供了各持久化对象的基本的CRUD 操作。而在DAO 接口里则对DAO组件包含的各种CRUD 方法提供了声明,但有一些IDE 工具也可以生成基本的CRUD方法。使用DAO 接口的原因是:避免业务逻辑组件与特定的DAO组件藕合。由于DAO 组件中的方法不是开始就设计出来的,其中的很多方法可能会随着业务逻辑的需求而增加,但以下几个方法是通用 的。 • get: 根据主键加载持久化实例。 • saveor update: 保存或更新持久化实例。 • remove: 删除持久化实例。 上面涉及了7个PO,这样我们必须设计7个对应的PODao 7个Dao必须继承BaseDao 这个BaseDao 有对接口的一些基本的CURD操作。7个Dao 如下。LinksDao ,BlogDao、FeedBackDao、ArticleDao、MessageDao、SortDao、PictureDao。这7个Dao 分别封装对自己的持久化对象的一些操作。 4.3.4 部署DAO 层 HibernateDaoSupport只需要一个SessionFactory 属性,即可完成数据库访问。SessionFactroy创建Session,而数据库的CRUD操作都是有Session 完成,并将查询结果保存在一级缓存中,每次用户提交一次会话,可能需要Session完成一些数据库操作而实际的数据库访问由模板HibernateTemplate完成,该模板提供了大量便捷的方法,简化了数据库的访问。 第五章 数据库设计 5.1定义(数据词典) 1、数据库表名的定义使用:重点字_table;重点字可以是多个英文单词的组合,从组合的第二单词起首字母大写,字段命名是能表达字段内容的英文单词的组合,组合方式同表名重点字相同。 2、NN 表示not null 不填表可为空。 3、数据型不使用固定数据库型,标识大众型,如字符串、字符、数字等。这样在更改数据库时需求的数据是可移植的 4、输写数据表在数据库中的物理名称,可用自己熟悉的语言再定义表名称,方便沟通。 5、长度定义又数据型决定:如字符串可选8000以下,数字可在50位之间,字符只允许一位。 6、输入方式表示数据的来源:生成表由程序或数据库的索引自动生成,而不需人工录入;输入表示通过文本框等输入的数据;选择表单选框、复选框、下拉列表等通过选择输入的数据;自定获取是为外码的输入设定的,它由程序自动获取。 5.2主要表结构如下 1. 表[blogs]日志数据表 字段名 型 说明 blogid Int(10) 日志的ID title text 日志标题 pubtime Int(11) 日志发表时间 authorid Int(8) 日志作者的UID replies Int(8) 日志的评论数 tbs Int(8) 日志的trackback数 views Int(8) 日志的查看次数 category Int(3) 日志所属的分的ID content mediumtext 日志正文内容 property Int(1) 日志的属性 0 公开日志 1 锁定日志 2 隐藏日志 3 一般草稿 2.表[user]博友登陆信息表 字段名 型 说明 userid Int(10) 博友ID nicheng Text 博友在博客里的称呼 username text 登陆时的用户名 password text 登陆密码 3.表[register]用户数据表 字段名 型 说明 userid Int(8) 登陆时需要用到的用户名 username text 用户昵称 userpwd Int(8) 登陆密码 regtime Int(11) 注册时间 usergroup Int(2) 所属的用户组ID email text 用户email qq text Qq号 msn text 用户msn gender text 用户性别 第六章 主要功能的实现 6.1 登录控制: if(this.session().getAttribute("rand")!=null){//检验随机数是否为空 if(this.checkCode.equals(this.session().getAttribute("rand").toString())){//比较随机数 uservo=userbo.queryUserByINfo(uservo);//检验用户信息并将信息返回 if(uservo!=null){//看用户是否存在 this.setUserpurview(uservo.getPurviewId());//设置用户权限 this.session().setAttribute("user", uservo);//将用户信息放在session中 return SUCCESS;//返回用户主界面页面 }else{ return ERROR;返回到失败页面} }else{return ERROR; }}else{ return ERROR; } 6.2 Ajax 读取txt格式数据 function ajax_function(var1,var2){ var xmlHttp = null; //创建xmlhttprequest try { // Firefox, Opera 8.0+, Safari 对不同浏览器常见不同对象 xmlHttp=new XMLHttpRequest(); } catch (e) { try { // Internet Explorer xmlHttp=new ActiveXObject('Msxml2.XMLHTTP'); } catch (e) { try { xmlHttp=new ActiveXObject('Microsoft.XMLHTTP'); } catch (e) { alert('Your browser does not support AJAX!'); return false; } } } xmlHttp.onreadystatechange=function() { if(xmlHttp.readyState == 4 && xmlHttp.status == 200) { var someDiv = document.getElementById('someDiv'); someDiv.innerHTML=xmlHttp.responseText; } } xmlHttp.open('GET','www/index.jsp?param1='+var1+'¶m2='+var2,true); xmlHttp.send(null); } 6.3 系统架构与数据库的连接 由于我们开发时是利用MVC的设计模式,所以在此我们的数据库连接是封存在M中的,即只要我们和M层连接上,就已经连接上数据库了。 Hibernate使用数据库和配置信息来为应用程序提供持久化服务(以及持久的对象)。我们只需在hibernate.cfg.xml中配置以下语句即可: sa jdbc:microsoft:sqlserver://localhost:1035;DatabaseName=webexamine org.hibernate.dialect.SQLServerDialect sqlserver2000 aaaaaaaa com.microsoft.jdbc.sqlserver.SQLServerDriver org.hibernate.dialect.HSQLDialect true 其实我们在这里配置了一个数据连接,以保证系统的正常运行,我们需要使用proxool连接池,我们经测试,分别用proxool、tomcat JNDI、Hibernate自带的连接池进行配置之后分别执行以上的10000条数据插入和读取,结果显示proxool的性能要优于tomcat JNDI,而Hibernate自带的就更不用提了,差很远。依次为:39265毫秒/10000条、26013毫秒/10000条、50029毫秒/10000条。 6.4数据的备份与还原 我们根据Mysql数据库提供的backup(备份)命令及restore(恢复)命令,进行数据库的备份与还原,在连接数据库后,我们在需要备份和还原的地方加入以下语句: backup database to disk='备份文件名' restore database from disk='备份文件名' 然后发送给数据库的管理对象进行数据还原与备份。 在知道了数据库备份与还原的接口后,用JAVA进行具体的连接,这里采用JAVA直连的方 法,部分代码如下: try{ String user="sa";//连接sqlserver2000数据库登陆名 String password="aaaaaaaa";//连接sqlserver2000数据库密码 String sDBDriver="com.microsoft.jdbc.sqlserver.SQLServerDriver";//连接数据库的驱动字符串 String connStr="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=webexamine";//注册连接字符串 Connection con=null; Class.forName( sDBDriver);//注册数据库驱动 con = Driver Manager.getConnection(connStr ,user,password);//获取数据库连接 String sql="backup database xncsims to disk='d:\\xncback.dat'";//备份数据库,还原数据库和着似,只是将这句变为还原的语句 st=con.createStatement();//创建发送对象 rs=st.executeQuery(sql);//这里就是把你的SQL语句发到数据库执行 }catch(SQLException e){ System.out.println(e.toString());} catch(Exception e){ System.out.println(e.toString());} 6.4部分效果预览图 主页 留言界面
在核心J2EE模式中是这样介绍DAO模式的:为了建立一个健壮的J2EE应用,应该将所有对数据源的访问操作抽象封装在一个公共API中。用程序设计的语言来说,就是建立一个接口,接口中定义了此应用程序中将会用到的所有事务方法。在这个应用程序中,当需要和数据源进行交互的时候则使用这个接口,并且编写一个单独的来实现这个接口在逻辑上对应这个特定的数据存储。 比如考虑在iBatis: SQL Maps中的应用例子。这是一个Struts应用允许对一个关系表执行SELECT, INSERT, UPDATE和DELETE的SQL请求。在这个应用中,使用SQL Maps做持续性框架。现在我们要修改这个应用,将这个关系表储存在一个XML文件中而不是存在关系数据库中,或者使用Hibernate来实现SELECT请求,而用SQL Map来执行其他请求,因为Hibernate提供了对高速缓存更好的支持。这样的修改很难实现,或者即使我们能修改而实现了这个功能,也会是很混乱的解决方案。 对于这问题更好的解决方法是建立一个ContactDAO接口,在这个接口中定义处理SELECT, INSERT, UPDATE, 和DELETE 请求的事务方法。然后根据不同的事务逻辑建立不同的实现各个方法。所以可能会有一个处理使用SQL Maps同关系表进行交互的情况,而另外一个处理用XML文件存放关系表而不是关系数据库的情况,等等。在项目中,根据实际的需要从不同的ContactDAO中选择相应的实现。 ……………………………………
课程设计 题目:在线考试系统设计与开发 "简介:目前国内基于B/S、C/S结构的在线考试系统产品已经有许多,本文首" "先介绍了这些考试系统的形成和发展过程,大致结构。然后通过仔细分析," "提出了目前的这些系统还存有系统更新和维护等种种弊端,仍不够成熟。基 " "于对现有产品的思考,结合J2EE的成熟技术,我们想到了是否可以将该技术 " "运用在在线考试系统中,提出了一个基于J2EE架构的在线考试系统。通过将 " "该架构与已有结构的在线考试系统进行比较,分析了该架构的优势,重点介 " "绍了该框架的整体构造以及相关的概念和技术。并通过设计了一个基于J2EE" "架构的在线考试系统对该架构做了一个比较深入的剖析。最后,对J2EE技术" "做了一个总结性的展望,认为该技术有着良好的发展空间和广阔的前景。 " 1 引言 现阶段,学校与社会上的各种考试大都采用传统的考试方式,在此方式下,组织一次 考试至少要经过五个步骤,即出卷、考生考试、阅卷、成绩评估和试卷分析。显然,随 着考试型的不断增加及考试要求的不断提高,教师的工作量将会越来越大,并且其工 作将是一件十分繁琐和非常容易出错的事情,可以说传统的考试方式已经不能适应现代 考试的需要。随着计算机应用的迅猛发展,网络应用不断扩大,如远程教育和虚拟大学 的出现等等,且这些应用正逐步深入到千家万户。人们迫切要求利用这些技术来进行在 线考试,以减轻教师的工作负担及提高工作效率,从而提高了考试的质量,使考试更趋 于公证、客观、激发学生的学习兴趣。例如目前许多国际著名的计算机公司所举办的各 种认证考试绝大部分采用这种方式。 为了适应新形势的发展,目前国内有很多公司团体研究开发了基于Web的考试系统。 而我们知道网络应用软件运行的模式主要有二:Client/Server模式、Browser/Serve r模式。前者主要的缺点是维护、升级较麻烦,后者是近几年伴随Internet迅速发展而应 运而生的一种技术,在这种模式下,客户端需要一个浏览器,服务器端是Web Server ,而Web Server是与数据库和应用服务器的紧密结合,可见,这种模式是瘦客户端,即对客户端 的要求不高.如今,很多部门的业务系统、企业的MIS系统纷纷采用这种模式,它的主要 优点是便于扩充应用、升级维护简便。然而,随着技术的发展,更先进的模式纷纷被提 出并时兴起来,其中J2EE就是比较成熟的一种。 2 在线考试系统构架 2.1 在线考试系统一般需求分析 在线考试系统应具有以下要求: 1)由于考试对应的是特定的对象,所以系统需要经过有效的身份验证才可以登陆。 并且系统需要有可以管理会话的功能。以便在考试过程中全程跟踪考试状态。 2)系统的权限一般分为两种:管理员和学生。不同的身份使用不同的权限和功能。 3)管理员需要对试题和考生进行有效的管理,负责试题的录入及更新和修改,对试 题的分,每次考试前,需要对试场环境和考生状态进行考前初始化工作。要注意 的是, 鉴于考试环境一般为机房,考试者之间的距离很近,为了在线考试做到规范,对于 每个应试者来说,试卷的试题和题量都应是相同的,但试题并不相同。 4. 系统要有良好的试卷上传和回收功能,确保信息传送的正确性。 5. 系统要有一个友善的界面,确保考生考试的顺利进行。 6. 因为试卷中的主观题需要老师批改,可能需要一段时间才能查询到成绩。但如果试 卷是由客观题型组成的,考生就可以在考试结束后查询到自己的成绩了。 7. 系统提供对考生成绩的统计和查询等管理功能。 8. 系统应具有良好的安全性管理。 2.2 当前在线考试系统现状分析 当前考试系统中,仍有许多是基于c/s模式的,每一次伴随着系统的升级,都要在每 个客户端更新软件,耗时耗力。可喜的是,随着技术的发展,基于b/s模式的在线考试系 统越来越多,逐渐占据了主导地位。它克服了c/s模式下的许多缺点,从传统的基于C/S 模式的考试系统转变到基于B/S模式的考试系统,可以使用户在任何一台电脑上,只要可 以上网,就可以使用该服务,大大简化了操作,为用户提供了方便。另一方面,也为教 师的管理和批阅工作提供了方便,提高了效率。但是据我多方的观察和研究,发现大多 数的在线考试系统都是采用基于页面的模式开发,每个页面中都包含了要用到的所有功 能逻辑,导致代码重复率高,结构不够清晰,维护升级起来也很费时间和人力。鉴于这 种情况,所以我们将J2EE的概念加入到在线考试系统中来,使得该系统更易于升级和维 护。 2.3 基于J2EE的在线考试系统架构介绍及拥有的优势 2.3.1 结构总体介绍 J2EE使用多层的分布式应用模型,应用逻辑按功能划分为组件,各个应用组件根据他 们所在的层分布在不同的机器上。事实上,sun设计J2EE的初衷正是为了解决两层
基于J2EE的在线考试系统构建探讨 一、高校在线考试系统需求分析 在线考试系统的一般功能是将传统考试过程中的试卷组织、审定印制、传送收集、登记发放、评判归档各个环节缩小到一至两个环节,并尽量屏蔽所有人工直接干预考试的可能性。一般应在系统权限、智能组卷功能以及成绩管理等方面进行具体要求。 1.系统权限 由于考试对应的是特定的对象,所以系统需要经过有效的身份验证才可以登陆。系统的权限一般分为两种:管理员和学生。不同的身份使用不同的权限和功能。管理员需要对试题和考生进行有效的管理,负责试题的录入及更新和修改,对试题的分,每次考试前,需要对试场环境和考生状态进行考前初始化工作。学生权限主要是登记考试、浏览考试信息、进行考试过程以及对成绩进行查询等。 2.智能组卷功能 智能组卷功能一般应包含系统维护、试题录入、试题检索、试卷生成、复习题生成等基本模块。对于每个应试者来说,试卷的题型和题量都应是相同的,但试题并不相同。自动组卷的效率与质量完全取决于抽题算法的设计。如何设计一个算法从题库中既快又好地抽出一组最佳解或是抽出一组非常接近最佳解的实体,涉及到一个全局寻优和收敛速度快慢的问题,具有很高的研究价值。 3.成绩管理 一般考试成绩由两个部分组成:客观题成绩和主观题成绩。对于客观题成绩,在学生提交试卷后应该及时给出;主观题可采用老师批改或者采用一定的算法进行计算机阅卷,可能需要一段时间才能查询到成绩。 4.系统其它功能 对于在线考试,一般系统还需要具有以下功能: (1)系统需要有可以管理会话的功能。以便在考试过程中全程跟踪考试状态。(2)系统要有一个友善的界面,确保考生考试的顺利进行。(3)系统要有良好的试卷上传和回收功能,确保信息传送的正确性。(4)系统应具有良好的安全性管理,以保证考试的客观公正。 二、基于J2EE的在线考试系统构架 1.系统结构设计 系统结构针对了J2EE的四层架构进行设计,如图: 图1 J2EE架构的在线考试系统构架 客户层负责提供用户界面接口,包括试题的显示和考生答案的输入;Web层负责将得到的考生登陆和题目上传的信息送交给业务层,同时,将从业务层处得到考试的相关信息输出到html页面为考生提供相关服务;业务层负责系统的具体逻辑实现,主要是得到数据池中的数据源,向数据库中提交和获得数据等;信息系统层主要采用了Microsoft SQL 2000数据库对数据进行存贮管理。 2.系统流程 具体流程见下图: 图2 J2EE架构的在线考试系统流程 考生首先进入登陆页面,输入用户名和密码,系统将该用户名和密码与数据库中考生表的用户名密码一一核对,如果存在该考生且未登陆,则弹出一个考试的主页面正常进入考试,并将该考生置为考试状态。否则会跳到出错页面要求考生重新登陆。 进入考试页面后,有许多分的试题要求考生分别完成,考生点击相应页面的超链接,进入做题,在每个分页面的顶部,都将会有对该部分试题的操作提示和注意事项,考生阅读完相关事项后进行做题,每做完该部分试题都必须保存,系统将收集到的考生做题信息上传到数据库中,考生则继续做其他部分试题。 完成所有考试后,考生点击交卷标记,系统保存考生所有的答题信息后正常他退出,并将考生置于离线状态。 三、系统关键模块设计 在线考试系统的整体结构主要包括四个部分:数据库模块、系统辅助模块、系统管理模块和在线考试模块。其基本模块构成关系描述如下: 图3 J2EE架构的在线考试系统模块设计 1.数据库模块 目前市场上存在有许多的数据库产品,较流行的有oracle,Mssql,Access,等。对于本系统来说,采用Msssql则是一个较为合适的选择,Mssql是微软网络数据库的主打产品,支持网络功能,日志记录等多种方便的服务,并且有着较为稳定的性能和可靠的管理。 数据库表的设计如下: Students table: id, char,10,notnull; password, char,10,null; number, char,10,notnull; sex, char,1,null;(1=男,0=女) chooseans, char,60,null; wordans, image,16,null; status, char,1,notnull;(1=在线,0=离线) choose table: QNUM,INT,4,notnull; QCON,TEXT,16,notnull; QANSA,TEXT,50,notnull; QANSB,TEXT,50,notnull; QANSC,TEXT,50,notnull; QANSD,TEXT,50,notnull; QANSE,TEXT,50,notnull; QANS, TEXT, 1,notnull; Word table: Topic_Number , nvarchar, 2,notnull; Question_Title, text, 16,notnull; Question_Content,image, 16,notnull; 利用tomcat数据库连接池负责分配、管理和释放数据库连接。 2.在线考试模块功能设置 (1)考生登陆模块 在客户层,考生通过主登陆页面输入用户名与密码。 在web层,将从用户输入处得到的用户名和密码与从业务层返回的相应用户名和密码作比较,如果用户存在密码正确且还未登陆就登陆考试主页面,否则跳到出错页面要求重新登陆。 在业务层,获得与mssql数据库的连接,并取出所有的用户名和密码信息。将该信息传入web层。 在EIS层,对应的是mssql数据库中的students表格。 (2)做题模块 ① 选择题: 在客户层,浏览器中显示每个考生所对应的考试题目,要求考生输入考试答案。并有一个提交按钮供考生做完题目后上传题目。 在Web层,jsp负责从业务层中获得题目,并将题目组织在一起向客户端显示。 在业务层,获得与数据库的连接,并且取出选择题题目。 在EIS层,对应的是数据库中choose表格。 ② word题: 在客户层,在浏览器中applet的textarea区域显示word题的要求,并利用applett数字签名技术,突破访问本地文件系统的限制,打开word做题。 在Web层,利用servlet的文件上传下载技术,将读出的word文件下载到本地磁盘。 在业务层,获得数据库连接,并取出word题目,word题是以二进制流的方式将word文件存贮在数据库。 在EIS层,对应的是数据库中word表格。 由于涉及到需要调用word程序进行word试题的考试,因此需要用到调用java外部程序的功能,java.lang.Runtime提供了exce()方法来完成对外部可执行程序的调用。具体代码见下: String path="C:/word.doc"; try {Runtime.getRuntime().exec("cmd /c start winword \"" + path + "\"");} catch (IOException e) {e.printStackTrace();} (3)答案上传模块 在客户层,在浏览器中单击提交按钮将做完的答案提交制相应页面 在Web层,将用户提交的答案提交给相应的javabean组件,并在客户端显示提示信息。 在业务层,将提交上来的答案存入相应的数据库中。 在EIS层,数据库中students表格,有两个相应字段用来存放该用户所对应的提交答案。
VB.Net 数据库操作是用于在VB.Net程序中进行数据库操作。它可以通过连接数据库、执行SQL语句、查询数据库、插入、更新、删除数据等操作来实现对数据库的管理和操作数据库操作通常包括数据库连接、数据操作和数据读取等组件。 数据库连接用于建立与数据库的连接,包括连接字符串的配置、打开和关闭数据库连接等功能。数据操作用于执行数据库操作的方法,如执行SQL语句、执行存储过程、参数化查询等。数据读取用于从数据库中读取数据,包括执行查询、获取数据集、数据表等功能。 使用VB.Net数据库操作可以方便地实现对数据库的管理和操作,提高程序的数据库访问效率和安全性。它可以与各种数据库系统进行交互,如SQL Server、MySQL、Oracle等,实现对不同数据库的统一管理和操作。同时,数据库操作还可以简化程序代码,提高开发效率,避免重复编写数据库连接和操作的代码,提高代码的可维护性和可读性。 总之,VB.Net数据库操作是在VB.Net程序中进行数据库操作的重要组件,它可以方便地连接数据库并执行各种数据库操作,是实现数据库管理和操作的重要工具。通过合理地使用数据库操作,可以提高程序的数据库操作效率和安全性,减少开发工作量,提高程序的可维护性和可扩展性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值