이 글에서는 JDBC에 대한 기본 지식과 기술을 예제와 함께 설명합니다. 참고할 수 있도록 모든 사람과 공유하세요. 구체적인 분석은 다음과 같습니다.
1. JDBC란 무엇인가요?
일반인의 관점에서 JDBC 기술은 Java 프로그램을 사용하여 SQL 문을 데이터베이스에 전송하고, 데이터베이스는 SQL 문을 수신한 후 실행하고, 그 결과를 Java 프로그램에 반환하여 관리합니다.
2. JDBC 이용조건은 어떻게 되나요?
A) 대상 데이터베이스 호스트의 주소
B) 호스트의 데이터베이스 소프트웨어가 차지하는 포트 번호
C) 데이터베이스에 로그인하는 데 사용되는 사용자 이름
D) 해당 사용자 이름의 비밀번호
E) 데이터베이스에 연결
3.JDBC 기술의 원리
우리는 다양한 유형의 데이터베이스가 있고, 서로 다른 제조업체에서 생산하는 데이터베이스 표준 및 사양이 다르다는 것을 알고 있습니다. 이때 JAVA 코드를 사용하여 SQL 문을 보내면 서로 다른 데이터베이스에 따라 하나씩 세트를 작성해야 합니다. 프로그램 개발자에게 막대한 개발 비용이 드는 연산 코드 세트이므로 SU N사는 JDBC 기술을 개발할 때 일련의 표준 인터페이스를 규정했습니다. 데이터베이스 제조업체는 이 인터페이스 세트를 구현하기 위한 드라이버를 제공해야 하며, 프로그램 개발자는 개발 중에 데이터베이스의 드라이버를 사용하는 한 일관된 방법을 사용해야 합니다. . 개발을 위해 다양한 데이터베이스에 맞게 코드 세트를 작성할 필요가 없습니다.
4. JDBC의 핵심 API
|- 드라이버: 드라이버 클래스에 의해 구현된 인터페이스입니다.
|-Connection connect(String url, Properties info) --데이터베이스에 연결하고 연결 개체를 가져오는 데 사용됩니다.
속성에서 설정해야 하는 매개변수:
url: 데이터베이스 연결의 URL 문자열입니다. 프로토콜+데이터베이스 하위 프로토콜+호스트+포트+데이터베이스
사용자: 데이터베이스 사용자 이름
비밀번호: 사용자의 비밀번호
|-Connection: 데이터베이스에 연결하기 위한 인터페이스
|- 명령문 createStatement() --SQL 명령문을 전송하기 위한 명령문 객체를 생성합니다.
|- ReadyStatement prepareStatement(String sql) - 미리 컴파일된 SQL 문을 전송하기 위한 ReadyStatement 객체를 생성합니다.
|-CallableStatement prepareCall(String sql) --저장 프로시저 호출을 위한 CallableStatement 객체를 생성합니다.
|-Statement: 정적 SQL 문을 실행하는 데 사용됩니다.
|-int excuteUpdate(String sql) --업데이트 작업 실행(DDL+DML)
|-ResultSet ExecuteQuery(String sql) --쿼리 작업 실행(DQL)
|- ReadyStatement: 미리 컴파일된 SQL 문을 실행하는 데 사용됩니다.
|- int excuteUpdate() -- 업데이트 작업을 수행합니다.
|- ResultSet excuteQuery() -- 쿼리 작업 실행
|- CallableStatement: 저장 프로시저를 실행하는 데 사용되는 SQL
|- ResultSet excuteQuery() --저장 프로시저 호출
|- ResultSet: 결과 세트입니다. 데이터베이스의 쿼리 데이터를 캡슐화하는 데 사용됩니다.
|- boolean next() --레코드 커서를 다음 줄로 이동합니다.
|- Object getObject(int columnIndex) -- 필드 값을 가져옵니다.
어떤 API인지 파악한 후 JDBC를 이용해 SQL문을 보내보겠습니다~
5. Database를 운용하기 위해 State 객체를 사용한다.
DDL 및 DML 작업
1단계
저는 MySQL 데이터베이스를 사용하고 있으므로 JDBC 기술을 사용하려면 MySQL 데이터베이스 제조업체에서 제공하는 데이터베이스 드라이버를 사용해야 합니다. 따라서 첫 번째 단계는 데이터베이스 드라이버 패키지를 프로젝트로 가져오는 것입니다.
사용된 패키지 이름: mysql-connector-java-5.1.7-bin.jar
2단계
일반 클래스를 만들고 그 안에 메서드를 추가한 후 다음과 같이 메서드에 코드를 복사합니다. //URL
개인 문자열 url = "jdbc:mysql://localhost:3306/vmaxtam";
//사용자
개인 문자열 사용자 = "루트";
//비밀번호
개인 문자열 비밀번호 = "루트";
public void testDDL()에서 예외 발생{
//1.드라이버 등록
Class.forName("com.mysql.jdbc.Driver");
//2. 연결을 얻습니다.
연결 conn = DriverManager.getConnection(url, 사용자, 비밀번호);
//3.Statement 객체 생성
명령문 stmt = conn.createStatement();
//4.SQL문 준비
String sql = "CREATE TABLE 학생(학번 INT PRIMARY KEY, 이름 VARCHAR(20), 나이 INT)";
//5.Statement 객체를 통해 SQL 문을 보내고 실행 결과를 반환합니다.
int count = stmt.executeUpdate(sql);
//6.실행 결과 인쇄
System.out.println("영향을 받은 "+count+" 레코드");
}
//7. 리소스 닫기
if(문!=null)
{
성명.닫기();
}
if(conn!=null)
{
conn.close();
}
DQL 및 DDL 작업을 수행하려는 경우 SQL 문을 작성한 다음 해당 문의 excutlUpdate 메서드를 호출하여 데이터베이스에 대한 SQL 문을 실행할 수 있습니다. 이 메서드는 영향을 받는 데이터베이스의 행 수를 나타내는 정수 값을 반환합니다.
위 프로그램을 변경하지 않고 다시 데이터베이스에 SQL 문을 발행하려면 다시 연결하는 프로그램을 작성해야 하고, 작업 후에는 명령문 객체와 연결 객체를 닫아야 하는데 이는 매우 번거롭다. . 따라서 우리는 일반적으로 연결 프로세스와 객체 해제 프로세스를 도구 클래스로 추출합니다. 도구 클래스의 코드는 다음과 같습니다.
다음과 같이 코드를 복사합니다. public class sqlUtil {
개인 정적 문자열 url = "jdbc:mysql://localhost:3306/vmaxtam";
개인 정적 문자열 사용자 = "루트";
개인 정적 문자열 비밀번호 = "루트";
// 연결 얻기
공개 정적 연결 getconnection() {
연결 연결 = null;
노력하다 {
// 1. 드라이버 등록
Class.forName("com.mysql.jdbc.Driver");
// 2. 연결 얻기
conn = DriverManager.getConnection(url, 사용자, 비밀번호);
// 3. 명령문 객체 가져오기
문 문 = conn.createStatement();
} 잡기(예외 e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
반환 연결;
}
// 7. 리소스 닫기
public static void close(문장, 연결 연결) {
{
노력하다 {
if(문 != null)
성명.닫기();
if (연결 != null) {
연결.닫기();
}
} 잡기(SQLException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
}
}
}
고려해야 할 사항은 다음과 같습니다.
1) 사용자는 드라이버를 한 번만 등록하면 됩니다. 데이터베이스에 연결할 때마다 드라이버를 등록할 필요가 없으므로 드라이버를 등록하는 프로세스를 정적 코드 블록에 작성합니다.
2) URL, 사용자 이름, 비밀번호 및 드라이버 클래스 이름은 프로그램에 하드 코딩되어 있으며 코드를 변경하지 않고 데이터베이스나 사용자를 변경할 수 있도록 일반적으로 이 정보를 구성 파일에 기록합니다.
구성 파일은 프로젝트의 src 디렉터리에 작성되며 이름은 db.properties입니다.
다음과 같이 코드를 복사합니다: url=jdbc:mysql://localhost:3306/vmaxtam
사용자=루트
비밀번호=루트
드라이버클래스=com.mysql.jdbc.Drive
그런 다음 sqlUtil에서 구성 파일을 읽고 마지막으로 다음 코드로 최적화합니다. public class sqlUtil {
개인 정적 문자열 url = null;
개인 정적 문자열 사용자 = null;
개인 정적 문자열 비밀번호 = null;
개인 정적 문자열 드라이버 클래스= null;
공전{
노력하다 {
//1. 바이트코드 객체를 얻습니다.
Classclazz = sqlUtil.class;
//2. getResourceAsStream을 호출하여 경로를 가져옵니다.
InputStream inputStream = clazz.getResourceAsStream("/db.properties");
속성 pro = 새 속성();
pro.load(inputStream);
//3. 매개변수 읽기
url=pro.getProperty("url");
비밀번호=pro.getProperty("비밀번호");
user=pro.getProperty("사용자");
DriverClass=pro.getProperty("driverClass");
Class.forName(driverClass);
} 잡기(예외 e) {
e.printStackTrace();
System.out.println("등록 실패!" + e.getMessage());
새로운 RuntimeException(e)을 던져라;
}
}
// 연결 얻기
공개 정적 연결 getconnection() {
연결 연결 = null;
노력하다 {
// 연결 얻기
conn = DriverManager.getConnection(url, 사용자, 비밀번호);
// 명령문 객체 가져오기
문 문 = conn.createStatement();
} 잡기(예외 e) {
e.printStackTrace();
}
반환 연결;
}
// 리소스를 닫습니다.
public static void close(문장문, 연결 연결) {
{
노력하다 {
if(문 != null)
성명.닫기();
if (연결 != null) {
연결.닫기();
}
} 잡기(SQLException e) {
// TODO 자동 생성된 캐치 블록
e.printStackTrace();
}
}
}
}
DQL 작업
그렇다면 JDBC를 사용하여 데이터베이스의 데이터를 쿼리하는 방법은 무엇입니까?
다음과 같이 코드 코드를 복사합니다. @Test
public void testdsl()에서 예외가 발생합니다.
//연결 얻기
cnn2=sqlUtil.getconnection();
성명문 = cnn2.createStatement();
//SQL문 준비
String sql = "제목에서 * 선택";
//executeQuery를 호출하여 쿼리 문을 실행합니다.
ResultSet res = 문.executeQuery(sql);
//쿼리가 완료된 후 res는 테이블 헤더를 가리킵니다. 데이터를 얻으려면 쿼리 결과의 다음 행을 계속 가리켜야 합니다. 데이터의 다음 행이 없으면 0이 반환됩니다.
동안(res.next())
{
//쿼리 결과에서 "sjid" 필드의 값을 가져오고 유형이 명확한지 확인합니다.
int id = res.getInt("sjid");
//쿼리 결과에서 "sjname" 필드의 값을 가져옵니다. 유형은 명확해야 합니다.
문자열 이름 = res.getString("sjname");
System.out.println("ID:" + id + "NAME:" + 이름);
}
sqlUtil.close(statement, cnn2);
}
위는 데이터베이스를 운영하기 위해 Database 객체를 사용하는 것입니다~
6.PreparedStatement를 사용하여 데이터베이스 운영
ReadyStatement 개체는 실제로 SQL 문을 미리 컴파일할 수 있는 특수한 문 개체입니다. 매개 변수를 설정하면 SQL 문을 실행할 수 있습니다~
DDL 및 DML 작업 복사 코드는 다음과 같습니다. package com.vmaxtam.sqltest;
import java.sql.Connection;
import java.sql.PreparedStatement;
org.junit.Test 가져오기;
공개 클래스 ReadyStatementTest {
연결 연결 = null;
@시험
public void ddldmlTest()에서 예외 발생 {
// 1. 연결 얻기
연결 = sqlUtil.getconnection();
// 2. SQL 문, 미리 컴파일된 문 및 매개 변수를 준비합니까? 숫자 자리 표시자
String sql = "주제 값에 삽입(?,?)";
// 3. 객체 가져오기
ReadyStatement prepareStatement = 연결.prepareStatement(sql);
/*
* 4. SQL 매개변수를 설정하려면 매개변수 번호와 해당 유형을 알아야 합니다. 아래 첫 번째 문장은 SQL 문의 첫 번째 매개변수가 int 유형이고 매개변수 값이 3으로 설정되어 있음을 나타냅니다. 에.
*/
prepareStatement.setInt(1, 3);
prepareStatement.setString(2, "영어");
// 5. SQL을 실행하기 위해 데이터베이스에 전달합니다.
int num = prepareStatement.executeUpdate();
System.out.println("다음이 있습니다." + num + "영향을 받은 레코드입니다.");
sqlUtil.close(preparedStatement, 연결);
}
}
위의 내용은 삽입문을 보내기 위해 preparedStatement 객체를 사용하는 것입니다. 마찬가지로 DDL, DML 문도 이런 식으로 보낼 수 있습니다.
ReadyStatement 사전 컴파일의 이점:
preparedStatement의 사전 컴파일을 사용하면 서로 다른 매개변수를 설정하여 서로 다른 대상을 쿼리할 수 있습니다. 데이터베이스 측에서는 사전 컴파일된 명령문만 저장되지만, 명령문을 보내기 위해 명령문을 사용하면 명령문이 전송될 때마다 해당 명령문이 저장됩니다. 데이터베이스를 사용하면 많은 메모리를 차지할 수 있습니다.
DQL 작업 복사 코드 코드는 다음과 같습니다. @Test
public void dqlTest()에서 예외가 발생합니다.
// 1. 연결 얻기
연결 = sqlUtil.getconnection();
// 2. SQL 문, 미리 컴파일된 문 및 매개 변수를 준비합니까? 숫자 자리표시자
String sql = "sjid=? 또는 sjname=?인 주제에서 *를 선택하세요.";
// 3. 객체 가져오기
ReadyStatement prepareStatement = 연결.prepareStatement(sql);
/*
* 4. SQL 매개변수를 설정하려면 매개변수 번호와 해당 유형을 알아야 합니다. 아래 첫 번째 문장은 SQL 문의 첫 번째 매개변수가 int 유형이고 매개변수 값이 3으로 설정되어 있음을 나타냅니다. 에.
*/
prepareStatement.setInt(1, 2);
prepareStatement.setString(2, "중국어");
// 5. SQL을 실행하기 위해 데이터베이스에 전달합니다.
ResultSet rst = prepareStatement.executeQuery();
//6.결과 세트 반복
동안(rst.next())
{
int id = rst.getInt("sjid");
문자열 이름 = rst.getString("sjname");
System.out.println("ID:" + id + "NAME:" + 이름);
}
//7. 연결을 닫습니다.
sqlUtil.close(preparedStatement, 연결);
}
ExecuteQuery() 메소드를 호출하고 결과 세트를 얻은 후 출력을 반복할 수도 있습니다~
Statement와 preparedStatement는 매우 유사하므로 장단점을 비교해보겠습니다~
Statement와 ReadyStatement의 차이점은 다음과 같습니다.
1. 다른 문법
문은 정적 컴파일만 지원하며 SQL 문은 하드 코딩됩니다.
ReadyStatement는 사전 컴파일을 지원합니다. 사용하시겠습니까? 와서 자리에 앉으세요.
2. 다양한 효율성
SQL 문을 매번 보내는 SQL 문이며 캐싱을 지원하지 않으며 실행 효율성이 낮습니다.
ReadyStatement는 사전 컴파일을 지원하고 데이터베이스에 캐시되기 때문에 매개변수만 전송하면 실행 효율성이 빠릅니다.
3. 다양한 보안
명령문은 쉽게 주입됩니다.
주입: 교활한 요소는 특수 SQL 문을 작성하여 데이터베이스를 손상시킬 수 있습니다.
예: 특정 사용자의 정보를 조회하려면
일반 상황: SELECT * FROM user_list 여기서 사용자 이름=xxx 및 비밀번호=xxx(여기서 xxx는 사용자 자신의 사용자 이름과 비밀번호를 입력해야 합니다)
주입 상황: SELECT * FROM user_list 여기서 사용자 이름='abc' 또는 1=1 -- 비밀번호=xxx;
이렇게 하면 1=1이 동일하고, 비밀번호 앞에 "--" 기호가 추가되고, 다음 내용은 코멘트가 되어 실행되지 않게 됩니다. 즉, 비밀번호 없이 모든 사용자 정보를 조회할 수 있습니다.
PreparedStatement는 SQL 문에 매개 변수를 지정하므로 주입을 방지할 수 있습니다.
결론: 더 빠르고 안전하므로 ReadyStatement를 사용하는 것이 좋습니다 .
7. CallableStatement를 사용하여 저장 프로시저 실행
CallableStatement를 사용하면 저장 프로시저만 실행됩니다. 저장 프로시저를 생성하려면 데이터베이스에 저장 프로시저를 생성해야 합니다.
1단계
이제 데이터베이스에 저장 프로시저가 생성되었습니다.
코드를 다음과 같이 복사하세요: DELIMITER $
프로시저 생성 pro_add(IN a INT , IN b VARCHAR(20),OUT c INT)
시작하다
SELECT * FROM SUBJECT WHERE sjid=a OR sjname=b;
SET c=a+a+a+a;
종료 $
2단계
Java 코드를 사용하여 출력 매개변수를 실행하고 가져옵니다. @Test.
public void calaST()에서 예외가 발생합니다. {
//연결 얻기
연결= sqlUtil.getconnection();
//SQL문 준비
String sql = "pro_add 호출(?,?,?)";
//callableStatement 객체를 가져옵니다.
CallableStatement cbs = 연결.prepareCall(sql);
//preparedStatement와 동일하게 입력 매개변수 설정
cbs.setInt(1, 3);
cbs.setString(2, "수학");
/*그렇다면 출력 매개변수를 어떻게 설정하나요?
* 출력 매개변수 등록이 필요합니다!
*/
cbs.registerOutParameter(3, java.sql.Types.INTEGER);//매개변수 유형을 설정하려면 내장 객체를 사용해야 합니다.
//SQL문 실행
cbs.executeQuery();
//getXXX 메소드를 사용하여 해당 위치의 출력 매개변수를 가져옵니다.
정수 num= cbs.getInt(3);
System.out.println("a*4는 " + num);
//리소스 닫기
sqlUtil.close(cbs, 연결);
}
이 글이 모든 사람의 Java 프로그래밍에 도움이 되기를 바랍니다.