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()。
答案 0 :(得分:-1)
Db连接:
jdbc:mysql://hostname:port_number/database_name
Db互动:
您可以使用Statement
或PreparedStatement
与数据库进行交互(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!
}