如何在Java类中正确实现JDBC

时间:2017-03-01 18:40:32

标签: java mysql jdbc

import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

public class Database {
    public static java.sql.Connection createConnection() throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.jdbc.Driver");
        final String DB_URL = "none";
        final String USER = "none";
        final String PASS = "none";

        return DriverManager.getConnection(DB_URL, USER, PASS);
    }

    public static void close(Connection connection) {
        try {
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(Statement st) {
        try {
            if (st != null) {
                st.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void rollback(Connection connection) {
        try {
            if (connection != null) {
                connection.rollback();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void getMemberID(String memberFirstName) {
        java.sql.Connection conn = null;
        try {
            conn = createConnection();
            System.out.println("Creating statement...");
            java.sql.PreparedStatement pStmt = conn.prepareStatement("select * from Members where FNAME = ?");
            pStmt.setString(1, memberFirstName);
            ResultSet rs = pStmt.executeQuery();
            while (rs.next()) {
                String ID = rs.getString("MEMBER_ID");
                System.out.println("Member ID: " + ID);
            }
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

我是JDBC的新手,我试图了解如何在我的程序中实现它。我有一个有员工和会员的程序。我希望能够为每个查询创建许多不同的查询。

员工和会员都是独立的班级。我为数据库信息创建了一个单独的类,因为我在这里看到它作为答案(Stack Overflow)。所以现在我想知道我是否正确实现它。在底部,我创建了一个名为getMemberID的方法。我的计划是在Members类中从Database调用此方法。

这是实现Database类的正确方法吗?在我看来,我将在这个数据库类中进行所有查询,然后从我使用的任何类中调用该方法(如果我想获得某个员工薪水,我会在类数据库中调用另一个方法的getSalary()。

3 个答案:

答案 0 :(得分:-1)

Db连接:

  • URL_DB的格式为jdbc:mysql://hostname:port_number/database_name
  • 您需要将USER和PASS替换为您的真实用户名和密码

Db互动:

您可以使用StatementPreparedStatement与数据库进行交互(CRUD操作)。

PreparedStatement pstmt = null;
try {
   String SQL = "Update Employees SET age = ? WHERE id = ?";
   pstmt = conn.prepareStatement(SQL);
   . . .
}
catch (SQLException e) {
   . . .
}
finally {
   . . .
}

这只是一个简短的谈论你需要做什么。在线阅读更多JDBC教程并亲自尝试。

我建议在实施之前编写一个界面。

interface DbAccess{
    Connection connect(...);
    void close(...);
    createEmployee(...);
    update(...)
    delete(...);
}

答案 1 :(得分:-1)

很好的尝试,但是,不,你的代码不是包装JDBC的正确方法。在getMemberID()方法中,您每次都会打开一个连接,并在几次通话后很快就会断开连接。

包装JDBC时要做的第一件事是确保不泄漏任何资源。

实现这一目标最直接的方法是使用像

这样的代码块
Connection con = null;
PreparedStatement stm = null;
ResultSet rst = null;
try {
    con = createConnection();
    stm  = con.prepareStatement("SELECT ... FROM ... WHERE ...");
    stm.setString (1, "value1");
    rst = stm.executeQuery();
    while (rst.next()) {
       // int i = rst.getInt(1);
    }
} catch (Exception e) {
    // do whatever
} finally {
    try { if (rst!=null) rst.close(); } catch (SQLException sqle) { }
    try { if (stm!=null) stm.close(); } catch (SQLException sqle) { }
    try { if (con!=null) con.close(); } catch (SQLException sqle) { }
}

接下来,打开连接是一个相当慢的操作,因此您不希望为要执行的每个SQL语句打开连接。因此,您需要一个像Apache DBCP这样的连接池(可以选择无数的JDBC连接池实现)。

然后,您需要将ResultSet值映射到Java变量。我个人不喜欢Hibernate和JPA,但这只是一种意见。如果只是为了读取RDBMS的写入值,我个人的偏好是将ResultSet读入Map,然后为每个值创建getter和setter方法。

还有一些提示:始终按照打开它们的相反顺序关闭资源,并始终关闭已经引发SQLException的连接,因为它很可能保留并且未完成的事务将导致执行下一个SQL语句在它失败。

答案 2 :(得分:-1)

这适用于SQLite。我认为人们应该走向资源尝试。

       String sql = "Update Employees SET age = ? WHERE id = ?"; 
        try (Connection conn = DriverManager.getConnection("jdbc:mysql://hostname:port_number/database_name");
             PreparedStatement ps = conn.prepareStatement(sql);)
        {
            ps.setString(1, age);
            ps.setString(2, id);
            ps.execute();                
        } 
        catch (SQLException e) {
            //Catch here!
        }