Dies ist ein beiläufiges Studienmemo zum Erwerb der Gold-Qualifikation von Java8. Es scheint, dass es in Scala keinen "Try-with-Resource" -Mechanismus gibt, daher beschreibt die zweite Hälfte, wie man ihn in Scala implementiert.
Java
Erstellen Sie eine Verbindungsverwaltungsklasse.
import java.sql.*;
/**
*DB-Verbindungserfassungsklasse
*/
public class DbConnector {
public static Connection getConnect() throws SQLException {
String url = "jdbc:mysql://localhost/golddb";
String user = "username";
String password = "password";
Connection connection = DriverManager.getConnection(url, user, password);
return connection;
}
}
Verbinden Sie sich mit "Try-with-Resource". Die grundlegenden Punkte sind wie folgt.
Statement
-Objekt.Statement
ausexecuteUpdate
.execute
kann referenziert und aktualisiert werden, sollte aber nicht so oft wie möglich verwendet werden.import java.sql.*;
public class JDBCExecuteQuerySample {
public static void main(String[] args) {
String sql = "SELECT dept_name FROM department";
try (Connection connection = DbConnector.getConnect();
Statement stmt = connection.createStatement()) {
ResultSet rs = stmt.executeQuery(sql);
if (rs != null) {
System.out.println("rs != null");
}
while (rs.next()) {
System.out.println("dept_name : " + rs.getString(1));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
import java.sql.*;
public class JDBCExecuteUpdateSample {
public static void main(String[] args) {
try (Connection connection = DbConnector.getConnect();
Statement stmt = connection.createStatement()) {
String sql =
"INSERT INTO department VALUES (6 , 'Plannning', 'Yokohama', '909-000-0000')";
int col = stmt.executeUpdate(sql);
System.out.println("col : " + col);
} catch (SQLException e) {
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
import java.sql.*;
public class JDBCExecuteSample {
public static void main(String[] args) {
try (Connection connection = DbConnector.getConnect();
Statement statement = connection.createStatement()) {
String[] sqls = {
//"insert into department values " + "(7, 'Planning', 'Yokohama', '055-555-5555')",
"select dept_name from department where dept_code = 2"
};
for (String sql : sqls) {
//Der Rückgabewert der Methode execute ist boolesch
boolean isResultSet = statement.execute(sql);
if (isResultSet) { //Bei Auswahl ist das Ergebnis von isResultSet wahr.
//Bei Ausführung durch execute das Objekt von ResultSet
// getResultSet()Get by Methode
ResultSet rs = statement.getResultSet();
rs.next();
System.out.println(rs.getString(1));
} else { //IsResultSet ist zum Einfügen falsch
int count = statement.getUpdateCount();
System.out.println(count);
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
PreparedStatement
Verwenden Sie in den meisten Fällen PreparedStatement anstelle von Statement, um die SQL-Injection zu verhindern.
import java.sql.*;
public class JDBCPreparedStatementSample {
public static void main(String[] args) {
String sql = "SELECT dept_code, dept_name FROM department WHERE dept_name = ?";
try (Connection connection = DbConnector.getConnect();
PreparedStatement statement = connection.prepareStatement(sql)) {
// ?Stellen Sie den Teil von ein und führen Sie ihn aus.
statement.setString(1, "Education");
ResultSet resultSet = statement.executeQuery();
resultSet.next();
System.out.format("dept_code: %d, dept_name: %s",
resultSet.getInt(1), resultSet.getString(2));
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Neben der Verwendung des "ResultSet" -Objekts im Vorwärtsmodus und schreibgeschützt können auch die folgenden Funktionen verwendet werden.
Konstanter Name | Erläuterung |
---|---|
CONCUR_READ_ONLY | Parallelverarbeitungsmodus für ResultSet-Objekte, die nicht aktualisiert werden können |
CONCUR_UPDATABLE | Parallelverarbeitungsmodus von resultSet-Objekten, die aktualisiert werden können |
TYPE_FORWARD_ONLY | Der Typ des ResultSet-Objekts, in dem sich der Cursor nur vorwärts bewegt |
TYPE_SCROLL_INSENTIVE | Ein Typ von ResultSet-Objekt, der scrollbar ist, jedoch keine Änderungen an den Daten in der Datenbank widerspiegelt |
TYPE_SCROLL_SENSITIVE | ResultSet-Objekttyp, der scrollbar ist und den neuesten Inhalt der Datenbank widerspiegelt |
Um es zu verwenden, geben Sie eine Konstante im Argument der Methode "createStatement" an, wie unten gezeigt.
Statement stmt = connection.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, //Geben Sie an, dass die Datenbank nicht in Vorwärts- oder Rückwärtsrichtung geändert werden soll
ResultSet.CONCUR_READ_ONLY //Kann nicht aktualisiert werden, nur als Referenz angeben
)
[Vorsichtsmaßnahmen] Dies hängt auch von der Implementierung von JDBC (Oracle, PostgreSQL, MySQL usw.) ab, die vom DB-Produkt implementiert wird. Im Fall von MySQL unterstützte der JDBC-Treiber (mysql-connector-java-5.1.42.jar) beispielsweise nur "TYPE_SCROLL_INSENSITIVE". Selbst wenn angegeben, wird es zu einem implizit scrollbaren "ResultSet" -Objekt.
import java.sql.*;
public class JDBCGetMetaDataSample {
public static void main(String[] args) {
try (Connection connection = DbConnector.getConnect()) {
DatabaseMetaData metaData = connection.getMetaData();
System.out.println("TYPE_SCROLL_SENSITIVE: " + metaData.supportsResultSetType(
ResultSet.TYPE_SCROLL_SENSITIVE));
System.out.println("TYPE_SCROLL_INSENSITIVE: " + metaData.supportsResultSetType(
ResultSet.TYPE_SCROLL_INSENSITIVE));
System.out.println("TYPE_FORWARD_ONLY: " + metaData.supportsResultSetType(
ResultSet.TYPE_FORWARD_ONLY));
System.out.println("CONCUR_READ_ONLY: " + metaData.supportsResultSetType(
ResultSet.CONCUR_READ_ONLY));
System.out.println("CONCUR_UPDATABLE: " + metaData.supportsResultSetType(
ResultSet.CONCUR_UPDATABLE));
} catch (SQLException e) {
e.printStackTrace();
}
}
}
TYPE_SCROLL_SENSITIVE: false
TYPE_SCROLL_INSENSITIVE: true
TYPE_FORWARD_ONLY: false
CONCUR_READ_ONLY: false
CONCUR_UPDATABLE: false
mysql> select * from department;
+-----------+-------------+--------------+--------------+
| dept_code | dept_name | dept_address | pilot_number |
+-----------+-------------+--------------+--------------+
| 1 | Sales | Tokyo | 03-3333-xxxx |
| 2 | Engineer | Yokohama | 045-444-xxxx |
| 3 | Development | Osaka | NULL |
| 4 | Marketing | Fukuoka | 092-222-xxxx |
| 5 | Education | Tokyo | NULL |
| 6 | Plannning | Yokohama | 909-000-0000 |
| 7 | Planning | Yokohama | 055-555-5555 |
+-----------+-------------+--------------+--------------+
7 rows in set (0.00 sec)
Probieren Sie hierfür die Cursorbewegungsmethode aus.
import java.sql.*;
public class JDBCCursorMoveSample {
public static void main(String[] args) {
//Sortieren Sie in aufsteigender Reihenfolge, um die Ergebnisse verständlicher zu machen.
String sql = "SELECT dept_code, dept_name FROM department ORDER BY dept_code";
try (Connection con = DbConnector.getConnect();
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet rs = stmt.executeQuery(sql)) {
//Bewegen Sie den Cursor zur letzten Zeile
rs.absolute(-1);
System.out.format("cursor: %d, dept_code: %d, dept_name: %s\n",
rs.getRow(), rs.getInt(1), rs.getString(2));
//Bewegen Sie den Cursor an den Anfang
rs.absolute(1);
System.out.format("cursor: %d, dept_code: %d, dept_name: %s\n",
rs.getRow(), rs.getInt(1), rs.getString(2));
//Bewegen Sie den Cursor in die letzte Zeile
rs.last();
System.out.format("cursor: %d, dept_code: %d, dept_name: %s\n",
rs.getRow(), rs.getInt(1), rs.getString(2));
//Bewegen Sie den Cursor auf die Zeile nach der letzten Zeile
rs.afterLast();
System.out.format("cursor: %d\n", rs.getRow());
//Bewegen Sie den Cursor an den Anfang
rs.first();
System.out.format("dept_code: %d, dept_name: %s\n",
rs.getInt(1), rs.getString(2));
//Bewegen Sie den Cursor auf die Zeile vor dem Anfang
rs.beforeFirst();
System.out.format("cursor: %d\n", rs.getRow());
//Gehen Sie zur nächsten Zeile nach der letzten Zeile und scrollen Sie dann in die entgegengesetzte Richtung
rs.afterLast();
System.out.println("Ausgabeergebnis durch umgekehrtes Scrollen----");
while (rs.previous()) { //Bildlauf umkehren
System.out.format("dept_code: %d, dept_name: %s\n",
rs.getInt(1), rs.getString(2));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Scala
In Scala gibt es also kein "Try-with-Resources" Implementieren Sie es selbst. Definieren und verwenden Sie die Methode using.
Zunächst bereiten wir ein Singleton-Objekt vor, das die using-Methode implementiert.
Die Funktion f
verwendet die Ressource, um etwas zu tun und
Wenn der Prozess abgeschlossen ist, wird die Methode close () ausgeführt.
object LoanPattern {
/**
*mit Methode
*Die Verarbeitung wird geschlossen, wenn die Verarbeitung abgeschlossen ist
*Java versuchen-catch-Alternative Methode der Ressource
*
* @Methode zum endgültigen Schließen mit param resource aufrufen
* @param f Prozess, der mit der Argumentressource ausgeführt werden soll
* @Ein Typ mit einer tparam A close-Methode
* @Rückgabewert der Funktion tparam B f
*/
def using[A <: {def close() : Unit}, B](resource:A)(f:A=>B): B = {
try {
f(resource) //Ausführung verarbeiten
} finally {
if (resource != null) resource.close()
}
}
Enthält den in der Fallklasse erhaltenen Wert.
case class UserAccount(id: Long, firstName: String, lastName: String)
DAO-Merkmal. Wenn Sie das Repository für RDB oder KVS ändern möchten, erben Sie dieses Merkmal.
trait UserDao {
//Holen Sie sich alle Benutzer
def getUsers(): Seq[UserAccount]
//Benutzer anhand der ID abrufen
def getById(id: Long): Option[UserAccount]
}
Implementierungsklasse. Diesmal ist MySQL.
/**
*UserDao-Implementierungsklasse
*Stellen Sie eine Verbindung zu MySQL her.
*/
class UserDaoOnMySQL extends UserDao {
import java.sql._
import scala.collection.mutable.ArrayBuffer
import LoanPattern.using
override def getUsers(): Seq[UserAccount] = {
using(getConnection()) { dbResource =>
val stmt = dbResource.createStatement()
val rs = stmt.executeQuery("select * from customers")
val arrayBuffer = ArrayBuffer[UserAccount]()
while (rs.next()) {
arrayBuffer += UserAccount(
rs.getInt("id"),
rs.getString("first_name"),
rs.getString("last_name"))
}
arrayBuffer.toList
}
}
override def getById(id: Long): Option[UserAccount] = {
using(getConnection()) { dbResource =>
val stmt = dbResource.createStatement()
val rs = stmt.executeQuery(s"select * from customers where id = ${id}")
val arrayBuffer = ArrayBuffer[UserAccount]()
while (rs.next()) {
arrayBuffer += UserAccount(
rs.getInt("id"),
rs.getString("first_name"),
rs.getString("last_name"))
}
arrayBuffer.find(_.id == id)
}
}
private def getConnection() =
DriverManager.getConnection("jdbc:mysql://localhost/db", "username", "password")
}
Die Benutzerseite.
object SampleLoanPatternApp extends App {
val dao = new UserDaoOnMySQL
println(dao.getUsers())
println(dao.getById(1))
}
Recommended Posts