以前做过个C#的单机软件,用一个静态类封装了数据库操作(所有属性和方法都是静态的,比如static Connection conn= new Connection()),用起来很顺手.现在想在JSP项目里用.不知道可行不.因为static修饰的对象在内存中只有一个,那是否每个访问用户都会使用这个对象? 这样是否会有问题?
我这样做会存在其他问题吗?

解决方案 »

  1.   

    如果只有一个人在用的话,没有任何问题,因为也不存在什么并发访问。如果是 Web 服务端的代码,就有可能会是并发访问,连你原来写的静态类、静态成员都有可能会产生线程安全问题。
      

  2.   

    数据库连接就像媳妇一样,严格意义上说最好是不可以共用,你可以使用单例模式管理数据库连接,或者使用数据库连接池,针对可能存在的问题不好说,贴出测试程序,你可以参考分析:
    package dao;import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.HashMap;
    //这是一个对jdbc数据库连接池的封装类
    import org.apache.commons.dbcp.BasicDataSource;public class  DBHelper {
    private DBHelper(){
    basicDataSource = new BasicDataSource();

    String driver = null;
    String url = null;
    String user = null;
    String password = null;

    driver = "com.mysql.jdbc.Driver";
    url = "jdbc:mysql://localhost:3306/bookstore";
    user = "root";
    password ="tiger";

    basicDataSource.setUrl(url);
    basicDataSource.setUsername(user);
    basicDataSource.setPassword(password);
    basicDataSource.setDriverClassName(driver);
    basicDataSource.setInitialSize(5);
    basicDataSource.setMaxActive(50);
    basicDataSource.setMaxWait(1000 * 60 * 2);
    }

    private static DBHelper instance = null;

    static{
    instance = new DBHelper();
    }

    public static DBHelper getInstance(){
    return instance;
    }

    private BasicDataSource basicDataSource = null;

    public Connection getConnection() {
    Connection conn = null;
    try {
    conn = this.basicDataSource.getConnection();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    return conn;
    }

    public void releaseSource(ResultSet rs, Statement st, Connection conn){
    try {
    if(rs != null)
    rs.close();
    if(st != null)
    st.close();
    if(conn != null)
    conn.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    }-------------------------------------------------------------------------------------<%@ page language="java" import="java.util.*,dao.DBHelper,java.sql.Connection" pageEncoding="utf-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'index.jsp' starting page</title>
      </head>
      <%!
       static Connection conn=DBHelper.getInstance().getConnection();
       static int i=0;
      %>
      <%
       i+=1;
       out.println("==>"+conn+"  ;  "+i);
       DBHelper.getInstance().releaseSource(null,null,conn);
      %>
      <body>
      </body>
    </html>第一次打开浏览器:
    ==>jdbc:mysql://localhost:3306/bookstore, UserName=root@localhost, MySQL-AB JDBC Driver ;  1关闭第二次打开浏览器:
    ==>null ; 2关闭第三次打开浏览器:
    ==>null ; 3....另外引用java基础关于static用法的描述:
    JAVA中通常我们会使用static域变量来在内存中缓存数据或长驻内存数据,众所周知
    ,static是类的所有实例所共享,考虑一个问题,假如在多线程情况下,共享数据
    肯定会有危险的,例如使用SimpleDateFormat工具的一个变量时,为方便作为util
    写为了static,后来在几W条数据中会出现一个奇怪的日期,这就是在多线程下会出现问题
    导致的数据冲突,一般这种能私有不共享的数据最好为一个实例一份拷贝,不要做为static
    若非要做,就对象同步锁,使之单线程。
      

  3.   

    如果将jsp页面改成如下就不会有任何问题:
    <%@ page language="java" import="java.util.*,dao.DBHelper,java.sql.Connection" pageEncoding="utf-8"%>
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <title>My JSP 'index.jsp' starting page</title>
      </head>
      <body>
      <%!static int i=0; %>
      <% 
         Connection   conn=DBHelper.getInstance().getConnection();     %> 
        <% 
    i+=1;
        out.println( "==> "+conn+ "     ;     "+i); 
        DBHelper.getInstance().releaseSource(null,null,conn);
        %> 
      </body>
    </html>jsp页面本身也即是一个java类,所属的静态成员先于类而首先被实例化,并且只会被实例化一次,就常住在内存中,生命周期和gc一样长,static是公共厕所,谁都可以进去添屎加尿,别把手机,钱包,身份证这种私有的物件丢进去,掉地上被别人捡到就不是你的了.