try
DB Connection
catch
조회가 안됨
finally
DB.close
위와 같이 db.close()는 finally 구문에 넣어주는것이 좋습니다.
예를 들어 close 는 이전 포스팅의 예에서 들었던
화장실이라고 해봅시다
만약 수많은 db들을 열고 catch에서 일일이 다 close를 잡아주어야 한다면 어떨까요?
너무 복잡하겠지요?
buffer와 flush()는 수동으로 화장실물을 내리는거였지만
close는 그 공간 자체를 나오는것을 말합니다.
그러니까 화장실에서 어떤 자원을 할당받고 어떤일을 하든
나올때는 무조건 그냥 한번만 전체다 close 시켜주면
화장실문들을 일일이 close 시켜주지 않아도 된다는 편리성이 있는거에요~ !!
package org.techtown.diary_20191225;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
public class DBHelper extends SQLiteOpenHelper{
public static String NAME="diary.db";
public static int VERSION=1;
public static String USER_TABLE_NAME="user";
public DBHelper(Context context){
super(context,NAME,null,VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
String sql="CREATE TABLE IF NOT EXISTS user("+
"id TEXT PRIMARY KEY,"+
"password TEXT,"+
"name TEXT,"+
"birth TEXT,"+
"email TEXT )";
db.execSQL(sql);
}
public void insertUser(User user){
SQLiteDatabase db=this.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("id",user.getId());
values.put("password",user.getPw());
values.put("name",user.getName());
values.put("birth",user.getBirth());
values.put("email",user.getEmail());
db.insert(USER_TABLE_NAME,null,values);
db.close();
}
public ArrayList<User> getAllUser(){
ArrayList<User> UserList= new ArrayList<User>();
String selectQuery="SELECT * FROM "+ USER_TABLE_NAME;
SQLiteDatabase db=this.getWritableDatabase();
Cursor cursor=db.rawQuery(selectQuery,null);
if(cursor.moveToFirst()){
do{
User user=new User();
user.setId(cursor.getString(0));
user.setPw(cursor.getString(1));
user.setName(cursor.getString(2));
user.setBirth(cursor.getString(3));
user.setEmail(cursor.getString(4));
UserList.add(user);
}while(cursor.moveToNext());
}
return UserList;
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if(newVersion >1){
db.execSQL("DROP TABLE IF EXISTS user");
}
}
}
그리고 위 코드를 보시면 rawQuery라고 나와있는데 이게 무슨 역할을 하는지 볼까요~
package jdbc0102;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class Test01_selectOne {
public static void main(String[] args) {
// TODO Auto-generated method stub
Connection con= null;
PreparedStatement pstmt=null;
//select 문 실행 시 반환
ResultSet rs=null;
try {
String url ="jdbc:oracle:thin:@localhost:1521:xe";
String user ="system";
String password="1234";
String driver ="oracle.jdbc.driver.OracleDriver";//ojdbc.jar
Class.forName(driver);
con=DriverManager.getConnection(url, user, password);
System.out.println("오라클 DB 서버 연결 성공");
StringBuilder sql=new StringBuilder();
sql.append(" SELECT sno,uname,kor,eng,mat,tot,aver,addr,wdate ");
sql.append(" FROM sungjuk ");
sql.append(" WHERE sno=? ");
//sno=22 행 조회하기
pstmt=con.prepareStatement(sql.toString());
pstmt.setInt(1, 22);
//DML (insert,update,delete)
//int cnt=pstmt.executeUpdate();
//select문 실행
rs=pstmt.executeQuery();
//cursor: 현재 가리키는 값. 이동할 수 있다 .
if(rs.next()) { // cursor가 존재하는지 ?
System.out.println("자료 있음 ! ");
//1)칼럼 순서
// ->> select 칼럼 1번 , 칼럼 2번 ~~~
System.out.print(rs.getInt(1)+ " "); // sno칼럼
System.out.print(rs.getString(2)+ " "); // uname칼럼
System.out.print(rs.getInt(3)+ " "); // kor칼럼
System.out.print(rs.getInt(4)+ " "); // eng칼럼
System.out.print(rs.getInt(5)+ " "); // mat칼럼
System.out.print(rs.getInt(6)+ " "); // tot칼럼
System.out.print(rs.getInt(7)+ " "); // aver칼럼
System.out.print(rs.getString(8)+ " "); // addr칼럼
System.out.print(rs.getString(9)+ " "); // wdate칼럼
//2) 칼럼명
System.out.print(rs.getInt("sno")+ " "); // sno칼럼
System.out.print(rs.getString("uname")+ " "); // uname칼럼
System.out.print(rs.getInt("kor")+ " "); // kor칼럼
System.out.print(rs.getInt("eng")+ " "); // eng칼럼
System.out.print(rs.getInt("mat")+ " "); // mat칼럼
System.out.print(rs.getInt("tot")+ " "); // tot칼럼
System.out.print(rs.getInt("aver")+ " "); // aver칼럼
System.out.print(rs.getString("addr")+ " "); // addr칼럼
System.out.print(rs.getString("wdate")+ " "); // wdate칼럼
}else {
System.out.println("자료 없음 ! ");
}
}catch(Exception e) {
System.out.println("실패 : "+ e);
}finally {
try {
if(rs!=null)
rs.close();
rs=null;
} catch (Exception e) {}
try {
if(pstmt!=null)
pstmt.close();
pstmt=null;
} catch (Exception e) {}
try {
if(con!=null)
con.close();
con=null;
} catch (Exception e) {}
}
}
}
위 코드에서는 preparestatement와 비슷한 역할을하고있는건데요~
JAVA
STRING SQL
SELECT
DB ------------------DB
이렇게 외부 DB랑 연결하고잇는역할을 하는것이 preparestatment이고
rawquery 입니다.
public void serverCreate() {
Collections.synchronizedMap(clientsMap);
try {
serverSocket = new ServerSocket(7777);
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
/** XXX 01. 첫번째. 서버가 할일 분담. 계속 접속받는것. */
Log.v("", "서버 대기중...");
try {
socket = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
Log.v("", socket.getInetAddress() + "에서 접속했습니다.");
msg = socket.getInetAddress() + "에서 접속했습니다.\n";
handler.sendEmptyMessage(SERVER_TEXT_UPDATE);
new Thread(new Runnable() {
private DataInputStream in;
private DataOutputStream out;
private String nick;
@Override
public void run() {
try {
out = new DataOutputStream(socket.getOutputStream());
in = new DataInputStream(socket.getInputStream());
nick = in.readUTF();
addClient(nick, out);
} catch (IOException e) {
e.printStackTrace();
}
try {// 계속 듣기만!!
while (in != null) {
msg = in.readUTF();
sendMessage(msg);
handler.sendEmptyMessage(SERVER_TEXT_UPDATE);
}
} catch (IOException e) {
// 사용접속종료시 여기서 에러 발생. 그럼나간거에요.. 여기서 리무브 클라이언트 처리 해줍니다.
removeClient(nick);
}
}
}).start();
}
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
여기 이부분을 보시면
스레드 안에 스레드가 들어간 것을 확인할 수 있습니다.
thread A thread B
accept 닉네임
채팅
threadA가 accept되면 thread B에서
닉네임을 받고 채팅도 할 수 있도록 짜보았습니다.
참고
동기 비동기 처리도 있는데요
package io_stream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Vector;
public class ServerEx4 {
private Vector handlers;
public ServerEx4(int port) {
try {
ServerSocket server= new ServerSocket(port);
handlers=new Vector();
System.out.println("ServerEx4 is ready.");
while(true) {
Socket client=server.accept();
ChatHandler c=new ChatHandler(this,client);
c.start();
}
}catch(Exception e) {}
}
public Object getHandler(int index) {
return handlers.elementAt(index); // Ư���� ����ϰ� ���� ���� ��
}
public void register(ChatHandler c) {
handlers.addElement(c);
}
public void unregister(Object o) {
handlers.removeElement(o);
}
public void broadcast (String message) {
synchronized(handlers) {
int n=handlers.size();
for (int i=0; i<n; i++) {
ChatHandler c= (ChatHandler) handlers.elementAt(i);
c.println(message);
}
}
}
public static void main(String[] args) {
new ServerEx4(9830);
}
}
위 예제는 브로드 캐스트 될때 동기화 처리를 해준 코드 입니다.
브로드 캐스트할때는 다른 작업이 처리 되지 못하도록 코드를 작성한 것인데요~
비동기 처리를 해줄 수도 있겠죠~ ?
예를 들어 옥돌이가 강아지와 고양이 둘 다 키운다고 해봅시다
같은 화장실안에서
강아지 가 변기에서 메모리를 할당받고 있다고 하더라도
강아지 친구 고양이는 별개로 샤워하기 메모리를 할당 받을 수있겠죠 ??
마찬가지 동기 , 비동기 처리는 같은 공간안에서
개발자의 마음대로 처리해주면 되는것입니다.