WebMoney: WMZ Z294115950220 WMR R409981405661 WME E134003968233 |
Visa 4274 3200 2453 6495 |
Эта секция обеспечивает некоторые общие концепции JDBC.
Когда вы используете JDBC за пределами сервера приложений, класс
Определите для Следующий раздел показывает код Java, как вы могли бы зарегистрировать
MySQL Connector/J из метода После того, как драйвер был зарегистрирован в
Пример 7.1. Connector/J: Получение связи от
Если вы еще не сделали этого, пожалуйста, просмотрите
раздел 7.1 выше прежде, чем работать с примером ниже. Этот пример показывает, как можно получить экзепляр
После установки Объекты Чтобы создать экземпляр Имея экземпляр Чтобы обновить данные в базе данных, используйте метод
Если вы не знаете заранее, будет ли SQL-оператор
be a Пример 7.2. Connector/J: применение java.sql.Statement для выполнения
Connector/J полностью понимает интерфейс
Для получения дополнительной информации о хранимых процедурах
MySQL, пожалуйста, обратитесь к
Using Stored Routines. Connector/J выставляет функциональность хранимой процедуры через интерфейс
JDBC Следующий пример показывает хранимую процедуру, которая возвращает
значение Пример 7.3. Connector/J: Запрос хранимых процедур Чтобы использовать процедуру Подготовьте запрос при помощи
Заметьте, что необходимо использовать синтаксис JDBC escape
и что круглые скобки, окружающие заполнители параметра, не опциональны: Пример 7.4. Connector/J: Применение
Зарегистрируйте параметры вывода (если есть). Чтобы получить значения параметров вывода (параметры, определенные как
Пример 7.5. Connector/J: Регистрация параметров вывода Установите входные параметры (если есть). Параметры ввода и in/out заданы как для объектов
Пример 7.6. Connector/J: Установка входных параметров
Выполните Хотя Пример 7.7. Connector/J: Получение результатов и
значений выходных параметров Пример 7.8. Connector/J: Получение значений столбца
Пример 7.9. Connector/J: Получение значений столбца
Пример 7.10. Connector/J: Получение значений столбца
Управление предыдущим примером кода должно произвести следующий вывод: Время от времени это может быть хитро, чтобы использовать запрос
Глава 7. Концепции JDBC
7.1. Соединение с MySQL, используя интерфейс JDBC
DriverManager
DriverManager
управляет связями.DriverManager
, с какими
драйверами JDBC попытаться установить связи. Самый легкий способ сделать это:
использовать Class.forName()
в классе, который
осуществляет интерфейс java.sql.Driver
.
С MySQL Connector/J название этого класса
com.mysql.cj.jdbc.Driver
.
С этим методом вы могли использовать внешний конфигурационный файл, чтобы
поставлять имя класса драйвера и параметры, чтобы использовать,
соединяясь с базой данных.main()
вашего
приложения. Проверяя этот код, сначала прочитайте инсталляционную секцию в
главе 4, чтобы удостовериться, что установили
соединитель правильно и настроили CLASSPATH
.
Кроме того, гарантируйте, что MySQL формируется, чтобы принять внешние
связи TCP/IP.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
// Notice, do not import com.mysql.cj.jdbc.*
// or you will have problems!
public class LoadDriver {
public static void main(String[] args)
{
try {
// The newInstance() call is a work around for some
// broken Java implementations
Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
} catch (Exception ex) {
// handle the error
}
}
}
DriverManager
, можно получить экземпляр
Connection
, который связан с конкретной базой
данных, вызывая DriverManager.getConnection()
:
DriverManager
Connection
из
DriverManager
.
Есть несколько различных сигнатур для метода
getConnection()
.
Консультируйтесь с документацией API, которая идет с вашим JDK для более
определенной информации о том, как использовать их.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
Connection conn = null;
...
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost/test?" +
"user=minty&password=greatsqldb");
// Do something with the Connection
...
} catch (SQLException ex) {
// handle any errors
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
Connection
это может
использоваться, чтобы создать объекты
Statement
и
PreparedStatement
, а также получить
метаданные о базе данных. Это объяснено в следующих разделах.
7.2. Использование объектов JDBC
Statement
,
чтобы выполнить SQLStatement
позволяют вам выполнять
основные SQL-запросы и получать результаты через класс
ResultSet
, который описан позже.Statement
,
вызовите метод createStatement()
на объекте
Connection
, который вы получили с использованием
одного из методов DriverManager.getConnection()
или DataSource.getConnection()
, описанных ранее.
Statement
, можно
выполнить запрос SELECT
вызовом метода
executeQuery(String)
с SQL, который вы хотите использовать.executeUpdate(String SQL)
.
Этот метод возвращает количество строк, соответствовавших запросу
обновления, а не количество строк, которые были изменены.SELECT
или
UPDATE
/
INSERT
, тогда можно использовать метод.
Он вернет true, если SQL-запрос был
SELECT
, или false, если SQL-запрос был
UPDATE
,
INSERT
или
DELETE
. Если это был
SELECT
, можно получить результаты, вызвав
метод getResultSet()
. Если это был
UPDATE
,
INSERT
или
DELETE
, можно узнать затронутое количество
строк вызовом getUpdateCount()
в экземпляре
Statement
.SELECT
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
// assume that conn is an already created JDBC connection (see previous examples)
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT foo FROM bar");
// or alternatively, if you don't know ahead of time that
// the query will be a SELECT...
if (stmt.execute("SELECT foo FROM bar")) {
rs = stmt.getResultSet();
}
// Now do something with the ResultSet ....
}
catch (SQLException ex) {
// handle any errors
System.out.println("SQLException: " + ex.getMessage());
System.out.println("SQLState: " + ex.getSQLState());
System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
// it is a good idea to release resources in a finally{} block
// in reverse-order of their creation
// if they are no-longer needed
if (rs != null) {
try {
rs.close();
} catch (SQLException sqlEx) { } // ignore
rs = null;
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException sqlEx) { } // ignore
stmt = null;
}
}
7.3. Применение JDBC
CallableStatements
для выполнения сохраненных процедурjava.sql.CallableStatement
.CallableStatement
.inOutParam
+1 и последовательность,
переданную с использованием inputParam
, как
ResultSet
:
CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), INOUT inOutParam INT)
BEGIN
DECLARE z INT;
SET z = inOutParam + 1;
SET inOutParam = z;
SELECT inputParam;
SELECT CONCAT('zyxw', inputParam);
END
demoSp
с
Connector/J, выполните эти шаги:Connection.prepareCall()
.Connection.prepareCall()
import java.sql.CallableStatement;
...
// Prepare a call to the stored procedure 'demoSp'
// with two parameters
//
// Notice the use of JDBC-escape syntax ({call ...})
CallableStatement cStmt = conn.prepareCall("{call demoSp(?, ?)}");
cStmt.setString(1, "abcdefg");
Connection.prepareCall()
дорогой метод из-за
поиска метаданных, который драйвер выполняет, чтобы поддержать параметры
вывода. По исполнительным причинам минимизируйте ненужные запросы
Connection.prepareCall()
снова используя
экземпляр CallableStatement
.OUT
или INOUT
,
когда вы создали хранимую процедуру), JDBC требует, чтобы они были определены
перед выполнением запроса, используя различные методы
registerOutputParameter()
в интерфейсе
the CallableStatement
:
import java.sql.Types;
...
// Connector/J supports both named and indexed
// output parameters. You can register output
// parameters using either method, as well
// as retrieve output parameters using either
// method, regardless of what method was used to register them.
//
// The following examples show how to use
// the various methods of registering
// output parameters (you should of course
// use only one registration per parameter).
// Registers the second parameter as output, and
// uses the type 'INTEGER' for values returned
// from getObject()
//
cStmt.registerOutParameter(2, Types.INTEGER);
// Registers the named parameter 'inOutParam', and
// uses the type 'INTEGER' for values returned
// from getObject()
cStmt.registerOutParameter("inOutParam", Types.INTEGER);
...
PreparedStatement
, но
CallableStatement
также понимают
параметры по имени:CallableStatement
...
// Set a parameter by index
cStmt.setString(1, "abcdefg");
// Alternatively, set a parameter using the parameter name
cStmt.setString("inputParam", "abcdefg");
// Set the 'in/out' parameter using an index
cStmt.setInt(2, 1);
// Alternatively, set the 'in/out' parameter by name
cStmt.setInt("inOutParam", 1);
...
CallableStatement
и получите любые наборы результатов или выходные параметры.CallableStatement
допускает вызов
любого из методов выполнения Statement
(executeUpdate()
,
executeQuery()
или
execute()
), самый гибкий метод, это вызвать
execute()
, поскольку вы не должны знать
заранее, что хранимая процедура возвращает наборы результатов:
...
boolean hadResults = cStmt.execute();
//
// Process all returned result sets
//
while (hadResults) {
ResultSet rs = cStmt.getResultSet();
// process result set
...
hadResults = cStmt.getMoreResults();
}
// Retrieve output parameters
//
// Connector/J supports both index-based and
// name-based retrieval
int outputValue = cStmt.getInt(2); // index-based
outputValue = cStmt.getInt("inOutParam"); // name-based
...
7.4. Получение силами JDBC значений столбцов
AUTO_INCREMENT
getGeneratedKeys()
это предпочтительный метод, если необходимо получить
AUTO_INCREMENT
через JDBC, это иллюстрировано в
первом примере ниже. Второй пример показывает, как можно получить то же самое
значение, используя стандартный запрос
SELECT LAST_INSERT_ID()
.
Заключительный пример показывает, как обновляемые наборы результатов могут
получить значение AUTO_INCREMENT
, используя
метод insertRow()
.AUTO_INCREMENT
через
Statement.getGeneratedKeys()
Statement stmt = null;
ResultSet rs = null;
try {
// Create a Statement instance that we can use for
// 'normal' result sets assuming you have a
// Connection 'conn' to a MySQL database already available
stmt = conn.createStatement();
// Issue the DDL queries for the table for this example
stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
stmt.executeUpdate("CREATE TABLE autoIncTutorial ("
+ "priKey INT NOT NULL AUTO_INCREMENT, "
+ "dataField VARCHAR(64), PRIMARY KEY (priKey))");
// Insert one row that will generate an AUTO INCREMENT
// key in the 'priKey' field
stmt.executeUpdate("INSERT INTO autoIncTutorial (dataField) "
+ "values ('Can I Get the Auto Increment Field?')",
Statement.RETURN_GENERATED_KEYS);
// Example of using Statement.getGeneratedKeys()
// to retrieve the value of an auto-increment value
int autoIncKeyFromApi = -1;
rs = stmt.getGeneratedKeys();
if (rs.next()) {
autoIncKeyFromApi = rs.getInt(1);
} else {
// throw an exception from here
}
System.out.println("Key returned from getGeneratedKeys():"
+ autoIncKeyFromApi);
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException ex) {
// ignore
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException ex) {
// ignore
}
}
}
AUTO_INCREMENT
через
SELECT LAST_INSERT_ID()
Statement stmt = null;
ResultSet rs = null;
try {
// Create a Statement instance that we can use for
// 'normal' result sets.
stmt = conn.createStatement();
// Issue the DDL queries for the table for this example
stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
stmt.executeUpdate("CREATE TABLE autoIncTutorial ("
+ "priKey INT NOT NULL AUTO_INCREMENT, "
+ "dataField VARCHAR(64), PRIMARY KEY (priKey))");
// Insert one row that will generate an AUTO INCREMENT
// key in the 'priKey' field
stmt.executeUpdate("INSERT INTO autoIncTutorial (dataField) "
+ "values ('Can I Get the Auto Increment Field?')");
// Use the MySQL LAST_INSERT_ID()
// function to do the same thing as getGeneratedKeys()
int autoIncKeyFromFunc = -1;
rs = stmt.executeQuery("SELECT LAST_INSERT_ID()");
if (rs.next()) {
autoIncKeyFromFunc = rs.getInt(1);
} else {
// throw an exception from here
}
System.out.println("Key returned from " + "'SELECT LAST_INSERT_ID()': " +
autoIncKeyFromFunc);
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException ex) {
// ignore
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException ex) {
// ignore
}
}
}
AUTO_INCREMENT
в
Updatable ResultSets
Statement stmt = null;
ResultSet rs = null;
try {
// Create a Statement instance that we can use for
// 'normal' result sets as well as an 'updatable'
// one, assuming you have a Connection 'conn' to
// a MySQL database already available
stmt = conn.createStatement(java.sql.ResultSet.TYPE_FORWARD_ONLY,
java.sql.ResultSet.CONCUR_UPDATABLE);
// Issue the DDL queries for the table for this example
stmt.executeUpdate("DROP TABLE IF EXISTS autoIncTutorial");
stmt.executeUpdate("CREATE TABLE autoIncTutorial ("
+ "priKey INT NOT NULL AUTO_INCREMENT, "
+ "dataField VARCHAR(64), PRIMARY KEY (priKey))");
// Example of retrieving an AUTO INCREMENT key
// from an updatable result set
rs = stmt.executeQuery("SELECT priKey, dataField "+"FROM autoIncTutorial");
rs.moveToInsertRow();
rs.updateString("dataField", "AUTO INCREMENT here?");
rs.insertRow();
// the driver adds rows at the end
rs.last();
// We should now be on the row we just inserted
int autoIncKeyFromRS = rs.getInt("priKey");
System.out.println("Key returned for inserted row: " + autoIncKeyFromRS);
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException ex) {
// ignore
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException ex) {
// ignore
}
}
}
Key returned from getGeneratedKeys(): 1
Key returned from SELECT LAST_INSERT_ID(): 1
Key returned for inserted row: 1
SELECT LAST_INSERT_ID()
,
поскольку значение привязано к соединению. Так, если некоторый другой запрос
происходит на той же самой связи, значение переписано. С другой стороны,
метод getGeneratedKeys()
относится к экземпляру
Statement
, таким образом, это может
использоваться, даже если другие запросы происходят на той же самой связи, но
не на том же самом Statement
.
Найди своих коллег! |
Вы можете направить письмо администратору этой странички, Алексею Паутову.