[안드로이드강좌] 5. Intent 와 Intent filter |
인텐트는 안드로이드 구성요소중의 세가지(Activity, Service, Broadcast Receiver)를 활성화시키는 역할을
담당합니다. 이는 메시지로 보면 편한데 일단 앞으로 실행된 작업에 대한 정보를 가지고 있다고 생각하면 됩니다. Broadcast의 경우 이는
무슨일이 일어났다는 정보도 포함하고 있습니다.
Activity에 대해서는 startActivity() 나 startActivityForResult() 를 이용 다른 Activity
를 시작시키거나 현재의 Activity가 무언가 다른 일을 하게 합니다.
Service에 대해서는 startService() 로 Intent가 넘겨지면서 서비스를 시작하거나 현재 실행되고있는 서비스에 다른
작업지시를 하게 됩니다. 또한 bindService()를 이용 부르고 있는 Activity와 불리워지는 Service사이에 연결을 하는 것도
가능합니다.
Broadcast에 대해서는 sendBroadcast(), sendOrderedBroadcast(),
sendStickyBroadcast() 를 이용 다른 Broadcast receiver로 메시지를 보내게 됩니다.
각 경우 넘겨진 Intent에 대해 안드로이드 시스템은 적절한 Activity를 찾아 다음작업으로 넘어가는것을 도와주게 됩니다.
이과정에서 Intent란 보내어지고 받는 오브젝트를 지칭하는것이고, Intent filter란 다음 작업이 정확히 명시되지 않은상태에서
보내진 Intent에 대해 안드로이드시스템이 연결시키는 과정에서 어느 Activity/Service/Broadcast가 받을것인가를 찾는
Intent Resolution 작업시 참조하는 정보입니다.
Intent Object
인텐트 오브젝트는 번들의 개념에서 보는데 이것저것 다 집어놓은 주머니 같다 생각하면 됩니다.
이 안에는
1. Component Name: 인텐트를 받을 클라스. 주어지지 않은 경우 안드로이드 시스템은 Intent Resolution 을
통해 다음 클라스를 찾아냅니다.
2. Action: 앞으로 해야할 작업을 칭합니다. 이미 정의된것을 사용할수도 있고 만들어 쓸수도 있습니다. 만들어 사용하는것에
대해서는 안드로이드 패키지 이름이 앞에 붙어있어야한 합니다. 이미 정의되어있는것은 아래에서 확인할 수 있습니다.
http://developer.android.com/reference/android/content/Intent.html
3. Data: 데이타의 URI 나 MIME 타입이 해당됩니다.
데이터는 직접 해당 Class를 부르면서 데이터 스트링을 직접 보낼수도, URI의 개념을 이용해 보내질 수 있습니다. URI의 개념을 이용하는 경우 데이터가 직접보내지는것이 아니라 데이터가 있는곳을 가르키는 URI를 Intent에 포함시키는 것입니다. URI의 경우 예들을 보면, Action이 ACTION_EDIT일때는 그 데이터는 수정으로 위해 보여져야 할 데이터의 URI로 추측할 있을 겁니다. ACTION_CALL이면 데이터는 tel: 에 전화번호의 URI가 되야합니다. ACTION_VIEW면, 데이터는 http: 에 화면에 보여질 정보를 가진 URI가 있을 겁니다. MIME타입이 중요한 이유는 데이터의 그림, 음악과 같이 그 종류가 명시되어야 할 경우가 있기 때문입니다.
4. Category: 인텐트를 핸들할 콤포넌트의 종류를 말합니다.
이제 Intent가 준비되면 한 Activity는 다음 Activity를 startActivity나
startActivityForResult 를 이용해 부르고 Intent를 넘깁니다. startActivity는 단순히 다음 Activity를
부르는데 쓰며 startActivityForResult 는 다음 Activity를 부르고 그 Activity가 되돌려주는 Intent 를
onActivityResult() 로 받아야 할 경우 씁니다. Notepad Tutorial 은 startActivityForResult 를
기준으로 Sample Notepad 예제는 startActivity를 기준으로 만들어져 있습니다.
Sample Notepad 예제에서 노트를 새러 생성될때의 상황을 보면 메뉴에서 MENU_ITEM_INSERT 가 선택되며
onOptionsItemSelected() 가 불려집니다. 이 메소드는 내부적으로 다음과 같이 startActivity() 실행시키데 됩니다.
startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
이과정에서 AndroidManifest.xml이 참조되어지는데 Activity는 ACTION_INSERT라는 작업을 어디서 해야하는지를
찾게 됩니다. 결국 Manifest의 내용에서 NoteEdit을 찾아내고 해당 Activity 를 시작합니다. Manifest를 사용하지 않고
아예 Intent 에 불리워 질 클라스 이름을 적어넣는 것도 가능합니다. 이것이 바로 Notepad tutorial에서 소개된 방법입니다.
Intent Resolution
인텐트는 component 이름 필드에 대상이 정확히 명시되어있는 Explicit intent와 대상이 없는 Implicit
intent가 있습니다. 문제는 이 Implicit intent입니다. 대상이 없으므로 안드로이드 시스템은 필요한 정보들을 모아서 대상을
찾아내는 작업을 수행합니다. 이를 Intent resolution이라합니다. 이과정에서 안드로이드시스템은 액션, 데이터, 카테고리의 세가지
정보를 가지고 Intent filter를 쭉 훝어봅니다. Intent filter라는 것은 어떤 클라스와 같은 Component가 만들어질때 이
Component는 어떤 작업을 수행할 수 있다고 명시해놓은 것을 칭합니다. 일반적으로 Manifest 파일에 아래와 같이 정의됩니다.
<intent-filter . . . > <action android:name="code android.intent.action.MAIN" /> <category android:name="code android.intent.category.LAUNCHER" /></intent-filter>
이 작업수행의 수행에 있어 시스템은 세가지 테스트를 모두 다 통과하는지를 확인하게 됩니다. 세가지 테스트가 다 통과되지 않으면
안드로이드 시스템은 인텐트를 받을 대상이 없다고 판단하는것입니다.
먼저, Action 을 보고 이텐트에 있는것 과 같은 것이 있는지 봅니다.
다음은 카테고리를 봅니다. 인텐트에 카테고리 정보가 없다면 어떨까요. 이경우 테스트를 통과하고 싶으면 implicit intent의
경우 대상 component에 android.intent.category.DEFAULT가 명시되어 있어야 합니다. explicit은 상관
없습니다. 여기에 예외가 있는데 android.intent.action.MAIN 과 android.intent.category.LAUNCHER은
이 DEFAULT가 필요 없습니다.
|
2015년 12월 23일 수요일
Java RMI CallBack 채팅 소스
package pejb.rmi.chat.client;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.rmi.*;
import java.rmi.server.*;
import pejb.rmi.chat.server.Server;
public class ChatClient extends JApplet implements Receiver, ActionListener
{
private String login_name=" ";
private boolean isApplet, loggedIn;
private static final int LOGIN=1, LOGOUT=2, CLEAR=3, COLOR=4, OK=5, CANCEL=6, BLUE=7, GREEN=8, BLACK=9;
private JButton jb_logout, jb_login, jb_clear, jb_color, jb_ok, jb_cancel, jb_blue, jb_green, jb_black;
private JTextArea jta_chatDisplay;
private JTextField jtf_chat_string, jtf_avatar_name;
private JDialog jd_chat_name, jd_chat_color;
private JScrollPane scrollPane;
private Server server = null;
public ChatClient() throws RemoteException
{
UnicastRemoteObject.exportObject(this);
}
public void init()
{
isApplet = true;
initUI();
addListeners();
}
public void destroy()
{
try
{
if (server != null) server.removeReceiver(this);
}
catch(RemoteException e) {}
}
private void createComponents()
{
jb_logout= new JButton("Log Out");
jb_login = new JButton("Log In");
jb_clear = new JButton("Clear Messages");
jb_color = new JButton("COLOR");
jb_blue = new JButton("BLUE");
jb_green = new JButton("GREEN");
jb_black = new JButton("BLACK");
jb_ok = new JButton("OK");
jb_cancel = new JButton("Cancel");
jtf_avatar_name = new JTextField(10);
jtf_chat_string = new JTextField();
jd_chat_name = new JDialog();
jd_chat_color = new JDialog();
jta_chatDisplay = new JTextArea();
}
private void initUI()
{
createComponents();
jb_logout.setActionCommand(LOGOUT +"");
jb_login.setActionCommand(LOGIN+"");
jb_clear.setActionCommand(CLEAR+"");
jb_color.setActionCommand(COLOR+"");
jb_blue.setActionCommand(BLUE+"");
jb_green.setActionCommand(GREEN+"");
jb_black.setActionCommand(BLACK+"");
jb_ok.setActionCommand(OK +"");
jb_cancel.setActionCommand(CANCEL + "");
jb_login.setToolTipText("login with new chat name");
jb_logout.setToolTipText("logout chatRoom");
jb_clear.setToolTipText("clear chat messages since started...");
jb_color.setToolTipText("changing color...");
jd_chat_color.setTitle("changed color!!");
jd_chat_name.setTitle("Input Avatar Name");
jd_chat_name.setTitle("Select Color");
JPanel color = new JPanel ();
color.add(jb_blue);
color.add(jb_green);
color.add(jb_black);
color.add(new Label("Color changed!!"));
jd_chat_color.getContentPane().add(color, BorderLayout.CENTER);
jd_chat_color.pack();
JPanel dummy = new JPanel ();
dummy.add(jb_ok);
dummy.add(jb_cancel);
JPanel p = new JPanel ();
p.add(new Label("Avatar Name: "));
p.add(jtf_avatar_name);
jd_chat_name.getContentPane().add(p, BorderLayout.NORTH);
jd_chat_name.getContentPane().add(dummy, BorderLayout.SOUTH);
jd_chat_name.pack();
jta_chatDisplay.setBackground(Color.pink);
jta_chatDisplay.setForeground(Color.green);
jta_chatDisplay.append("반갑습니다... ^^ 이 프로그램은 RMI Callback Based ChatClient 입니다.\n");
jta_chatDisplay.append("사용법 ==> 입장 : Click 'Log In', 퇴실 : 'Log Out' \n");
jta_chatDisplay.setEditable(false);
jb_logout.setEnabled(false);
JPanel tmpPanel = new JPanel();
tmpPanel.add(jb_login);
tmpPanel.add(jb_logout);
tmpPanel.add(jb_clear);
tmpPanel.add(jb_color);
scrollPane = new JScrollPane(jta_chatDisplay);
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(tmpPanel , BorderLayout.NORTH);
contentPane.add(scrollPane, BorderLayout.CENTER);
contentPane.add(jtf_chat_string, BorderLayout.SOUTH);
}
private void addListeners()
{
ActionListener tf_listener = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(!loggedIn)
{
jtf_chat_string.setText("Please Login First...");
return;
}
try
{
send(jtf_chat_string.getText());
jtf_chat_string.setText("");
}
catch(RemoteException ex)
{
ex.printStackTrace();
}
}
};
jb_logout.addActionListener(this);
jb_login.addActionListener(this);
jb_clear.addActionListener(this);
jb_color.addActionListener(this);
jb_blue.addActionListener(this);
jb_green.addActionListener(this);
jb_black.addActionListener(this);
jb_ok.addActionListener(this);
jb_cancel.addActionListener(this);
jtf_chat_string.addActionListener(tf_listener);
}
private void openConnection() throws RemoteException
{
if(server == null)
{
try
{
server = (Server)Naming.lookup("rmi://localhost:2000/ChatServer");
System.out.println("Looked Up Remote Object...");
server.addReceiver(this);
send(login_name + " entered ...\n");
loggedIn = true;
}
catch( Exception e)
{
throw new RemoteException("Couldn't get a valid remote refrence ...["+ e + "]");
}
}
jb_login.setEnabled(false);
jb_logout.setEnabled(true);
jb_color.setEnabled(true);
jb_blue.setEnabled(true);
jb_green.setEnabled(true);
jb_black.setEnabled(true);
jtf_chat_string.requestFocus();
jtf_chat_string.setText(" ");
}
private void closeConnection() throws RemoteException
{
server.broadcast(" " + login_name + " 님이 퇴실 했습니다...");
server.removeReceiver(this);
loggedIn = false;
server = null;
jb_logout.setEnabled(false);
jb_login.setEnabled(true);
jb_color.setEnabled(true);
jb_blue.setEnabled(true);
jb_green.setEnabled(true);
jb_black.setEnabled(true);
}
private void go()
{
JFrame jf = new JFrame ();
jf.getContentPane().add(this);
init();
isApplet = false;
jf.setSize(400, 600);
jf.setVisible(true);
jf.addWindowListener(new WindowCloser());
}
private void send(String msg) throws RemoteException
{
server.broadcast("[" + login_name + "] " + msg);
jtf_chat_string.setText("");
}
public void printMsg(String msg) throws RemoteException
{
jta_chatDisplay.append(msg+ "\n");
JScrollBar vScroll = null;
vScroll = scrollPane.getVerticalScrollBar();
vScroll.setValue(vScroll.getMaximum());
}
public static void main(String [] args)
{
try
{
new ChatClient().go();
}
catch(RemoteException ex)
{
ex.printStackTrace();
}
}
class WindowCloser extends WindowAdapter
{
public void windowClosing(WindowEvent we)
{
if(server != null)
{
try
{
closeConnection();
}
catch(RemoteException e)
{
e.printStackTrace();
}
}
System.exit(0);
}
}
public void actionPerformed(ActionEvent ae)
{
int buttonId = Integer.parseInt(ae.getActionCommand());
switch(buttonId)
{
case LOGOUT:
try
{
closeConnection();
}
catch (RemoteException e)
{
e.printStackTrace();
}
break;
case LOGIN:
jd_chat_name.setLocation(ChatClient.this.getLocationOnScreen().x + 50,
ChatClient.this.getLocationOnScreen().y + 50);
jd_chat_name.setVisible(true);
break;
case COLOR:
jd_chat_color.setLocation(ChatClient.this.getLocationOnScreen().x + 50,
ChatClient.this.getLocationOnScreen().y + 50);
jd_chat_color.setVisible(true);
break;
case BLUE:
jta_chatDisplay.setForeground(Color.blue);
jd_chat_color.setVisible(false);
break;
case GREEN:
jta_chatDisplay.setForeground(Color.green);
jd_chat_color.setVisible(false);
break;
case BLACK:
jta_chatDisplay.setForeground(Color.black);
jd_chat_color.setVisible(false);
break;
case OK:
login_name = jtf_avatar_name.getText();
try
{
openConnection();
jta_chatDisplay.setText("방가방가\n" + login_name + "으로 로그인 하셨습니다. 즐거운 시간 되십시요.\n");
jd_chat_name.setVisible(false);
}
catch(RemoteException e)
{
e.printStackTrace();
}
break;
case CANCEL:
jd_chat_name.setVisible(false);
break;
case CLEAR:
jta_chatDisplay.setText("Cleard the diplay area.\n");
break;
}
}
}
package pejb.rmi.chat.server;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.util.*;
import pejb.rmi.chat.client.*;
public class ChatServer extends UnicastRemoteObject implements Server
{
private ArrayList allClients = new ArrayList(100);
public ChatServer() throws RemoteException
{
super();
}
public void addReceiver(Receiver client) throws RemoteException
{
allClients.add(client);
System.out.println("Added a client...");
}
synchronized public void broadcast(String msg) throws RemoteException
{
int count = allClients.size();
System.out.println("현재 접속중인 클라이언트::: " +count);
Receiver client = null;
for ( int i=0 ; i<count ; i++ )
{
client = (Receiver)allClients.get(i);
client.printMsg(msg);
}
}
synchronized public void removeReceiver(Receiver client) throws RemoteException
{
allClients.remove(allClients.indexOf(client));
}
public static void main(String[] args)
{
try
{
Server server = new ChatServer();
Naming.rebind("rmi://localhost:2000/ChatServer", server);
System.out.println("Remote Object[" +Server.CHAT_SERVER + "] bound... on port 2000");
}
catch (Exception e)
{
System.err.println("RMI 서버 생성시 오류 발생::: " + e);
System.exit(1);
}
}
}
package pejb.rmi.chat.client;
import java.rmi.*;
public interface Receiver extends Remote
{
public void printMsg(String msg) throws RemoteException;
}
package pejb.rmi.chat.server;
import java.rmi.*;
import pejb.rmi.chat.client.Receiver;
public interface Server extends Remote
{
public String CHAT_SERVER = "chatserver";
public void broadcast(String msg) throws RemoteException;
public void addReceiver(Receiver client) throws RemoteException;
public void removeReceiver(Receiver client) throws RemoteException;
}
[출처] 오라클자바커뮤니티 - http://ojc.asia/bbs/board.php?bo_table=LecJavaNet&wr_id=90
package pejb.rmi.chat.client;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.rmi.*;
import java.rmi.server.*;
import pejb.rmi.chat.server.Server;
public class ChatClient extends JApplet implements Receiver, ActionListener
{
private String login_name=" ";
private boolean isApplet, loggedIn;
private static final int LOGIN=1, LOGOUT=2, CLEAR=3, COLOR=4, OK=5, CANCEL=6, BLUE=7, GREEN=8, BLACK=9;
private JButton jb_logout, jb_login, jb_clear, jb_color, jb_ok, jb_cancel, jb_blue, jb_green, jb_black;
private JTextArea jta_chatDisplay;
private JTextField jtf_chat_string, jtf_avatar_name;
private JDialog jd_chat_name, jd_chat_color;
private JScrollPane scrollPane;
private Server server = null;
public ChatClient() throws RemoteException
{
UnicastRemoteObject.exportObject(this);
}
public void init()
{
isApplet = true;
initUI();
addListeners();
}
public void destroy()
{
try
{
if (server != null) server.removeReceiver(this);
}
catch(RemoteException e) {}
}
private void createComponents()
{
jb_logout= new JButton("Log Out");
jb_login = new JButton("Log In");
jb_clear = new JButton("Clear Messages");
jb_color = new JButton("COLOR");
jb_blue = new JButton("BLUE");
jb_green = new JButton("GREEN");
jb_black = new JButton("BLACK");
jb_ok = new JButton("OK");
jb_cancel = new JButton("Cancel");
jtf_avatar_name = new JTextField(10);
jtf_chat_string = new JTextField();
jd_chat_name = new JDialog();
jd_chat_color = new JDialog();
jta_chatDisplay = new JTextArea();
}
private void initUI()
{
createComponents();
jb_logout.setActionCommand(LOGOUT +"");
jb_login.setActionCommand(LOGIN+"");
jb_clear.setActionCommand(CLEAR+"");
jb_color.setActionCommand(COLOR+"");
jb_blue.setActionCommand(BLUE+"");
jb_green.setActionCommand(GREEN+"");
jb_black.setActionCommand(BLACK+"");
jb_ok.setActionCommand(OK +"");
jb_cancel.setActionCommand(CANCEL + "");
jb_login.setToolTipText("login with new chat name");
jb_logout.setToolTipText("logout chatRoom");
jb_clear.setToolTipText("clear chat messages since started...");
jb_color.setToolTipText("changing color...");
jd_chat_color.setTitle("changed color!!");
jd_chat_name.setTitle("Input Avatar Name");
jd_chat_name.setTitle("Select Color");
JPanel color = new JPanel ();
color.add(jb_blue);
color.add(jb_green);
color.add(jb_black);
color.add(new Label("Color changed!!"));
jd_chat_color.getContentPane().add(color, BorderLayout.CENTER);
jd_chat_color.pack();
JPanel dummy = new JPanel ();
dummy.add(jb_ok);
dummy.add(jb_cancel);
JPanel p = new JPanel ();
p.add(new Label("Avatar Name: "));
p.add(jtf_avatar_name);
jd_chat_name.getContentPane().add(p, BorderLayout.NORTH);
jd_chat_name.getContentPane().add(dummy, BorderLayout.SOUTH);
jd_chat_name.pack();
jta_chatDisplay.setBackground(Color.pink);
jta_chatDisplay.setForeground(Color.green);
jta_chatDisplay.append("반갑습니다... ^^ 이 프로그램은 RMI Callback Based ChatClient 입니다.\n");
jta_chatDisplay.append("사용법 ==> 입장 : Click 'Log In', 퇴실 : 'Log Out' \n");
jta_chatDisplay.setEditable(false);
jb_logout.setEnabled(false);
JPanel tmpPanel = new JPanel();
tmpPanel.add(jb_login);
tmpPanel.add(jb_logout);
tmpPanel.add(jb_clear);
tmpPanel.add(jb_color);
scrollPane = new JScrollPane(jta_chatDisplay);
Container contentPane = getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(tmpPanel , BorderLayout.NORTH);
contentPane.add(scrollPane, BorderLayout.CENTER);
contentPane.add(jtf_chat_string, BorderLayout.SOUTH);
}
private void addListeners()
{
ActionListener tf_listener = new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(!loggedIn)
{
jtf_chat_string.setText("Please Login First...");
return;
}
try
{
send(jtf_chat_string.getText());
jtf_chat_string.setText("");
}
catch(RemoteException ex)
{
ex.printStackTrace();
}
}
};
jb_logout.addActionListener(this);
jb_login.addActionListener(this);
jb_clear.addActionListener(this);
jb_color.addActionListener(this);
jb_blue.addActionListener(this);
jb_green.addActionListener(this);
jb_black.addActionListener(this);
jb_ok.addActionListener(this);
jb_cancel.addActionListener(this);
jtf_chat_string.addActionListener(tf_listener);
}
private void openConnection() throws RemoteException
{
if(server == null)
{
try
{
server = (Server)Naming.lookup("rmi://localhost:2000/ChatServer");
System.out.println("Looked Up Remote Object...");
server.addReceiver(this);
send(login_name + " entered ...\n");
loggedIn = true;
}
catch( Exception e)
{
throw new RemoteException("Couldn't get a valid remote refrence ...["+ e + "]");
}
}
jb_login.setEnabled(false);
jb_logout.setEnabled(true);
jb_color.setEnabled(true);
jb_blue.setEnabled(true);
jb_green.setEnabled(true);
jb_black.setEnabled(true);
jtf_chat_string.requestFocus();
jtf_chat_string.setText(" ");
}
private void closeConnection() throws RemoteException
{
server.broadcast(" " + login_name + " 님이 퇴실 했습니다...");
server.removeReceiver(this);
loggedIn = false;
server = null;
jb_logout.setEnabled(false);
jb_login.setEnabled(true);
jb_color.setEnabled(true);
jb_blue.setEnabled(true);
jb_green.setEnabled(true);
jb_black.setEnabled(true);
}
private void go()
{
JFrame jf = new JFrame ();
jf.getContentPane().add(this);
init();
isApplet = false;
jf.setSize(400, 600);
jf.setVisible(true);
jf.addWindowListener(new WindowCloser());
}
private void send(String msg) throws RemoteException
{
server.broadcast("[" + login_name + "] " + msg);
jtf_chat_string.setText("");
}
public void printMsg(String msg) throws RemoteException
{
jta_chatDisplay.append(msg+ "\n");
JScrollBar vScroll = null;
vScroll = scrollPane.getVerticalScrollBar();
vScroll.setValue(vScroll.getMaximum());
}
public static void main(String [] args)
{
try
{
new ChatClient().go();
}
catch(RemoteException ex)
{
ex.printStackTrace();
}
}
class WindowCloser extends WindowAdapter
{
public void windowClosing(WindowEvent we)
{
if(server != null)
{
try
{
closeConnection();
}
catch(RemoteException e)
{
e.printStackTrace();
}
}
System.exit(0);
}
}
public void actionPerformed(ActionEvent ae)
{
int buttonId = Integer.parseInt(ae.getActionCommand());
switch(buttonId)
{
case LOGOUT:
try
{
closeConnection();
}
catch (RemoteException e)
{
e.printStackTrace();
}
break;
case LOGIN:
jd_chat_name.setLocation(ChatClient.this.getLocationOnScreen().x + 50,
ChatClient.this.getLocationOnScreen().y + 50);
jd_chat_name.setVisible(true);
break;
case COLOR:
jd_chat_color.setLocation(ChatClient.this.getLocationOnScreen().x + 50,
ChatClient.this.getLocationOnScreen().y + 50);
jd_chat_color.setVisible(true);
break;
case BLUE:
jta_chatDisplay.setForeground(Color.blue);
jd_chat_color.setVisible(false);
break;
case GREEN:
jta_chatDisplay.setForeground(Color.green);
jd_chat_color.setVisible(false);
break;
case BLACK:
jta_chatDisplay.setForeground(Color.black);
jd_chat_color.setVisible(false);
break;
case OK:
login_name = jtf_avatar_name.getText();
try
{
openConnection();
jta_chatDisplay.setText("방가방가\n" + login_name + "으로 로그인 하셨습니다. 즐거운 시간 되십시요.\n");
jd_chat_name.setVisible(false);
}
catch(RemoteException e)
{
e.printStackTrace();
}
break;
case CANCEL:
jd_chat_name.setVisible(false);
break;
case CLEAR:
jta_chatDisplay.setText("Cleard the diplay area.\n");
break;
}
}
}
package pejb.rmi.chat.server;
import java.rmi.*;
import java.rmi.server.*;
import java.rmi.registry.*;
import java.util.*;
import pejb.rmi.chat.client.*;
public class ChatServer extends UnicastRemoteObject implements Server
{
private ArrayList allClients = new ArrayList(100);
public ChatServer() throws RemoteException
{
super();
}
public void addReceiver(Receiver client) throws RemoteException
{
allClients.add(client);
System.out.println("Added a client...");
}
synchronized public void broadcast(String msg) throws RemoteException
{
int count = allClients.size();
System.out.println("현재 접속중인 클라이언트::: " +count);
Receiver client = null;
for ( int i=0 ; i<count ; i++ )
{
client = (Receiver)allClients.get(i);
client.printMsg(msg);
}
}
synchronized public void removeReceiver(Receiver client) throws RemoteException
{
allClients.remove(allClients.indexOf(client));
}
public static void main(String[] args)
{
try
{
Server server = new ChatServer();
Naming.rebind("rmi://localhost:2000/ChatServer", server);
System.out.println("Remote Object[" +Server.CHAT_SERVER + "] bound... on port 2000");
}
catch (Exception e)
{
System.err.println("RMI 서버 생성시 오류 발생::: " + e);
System.exit(1);
}
}
}
package pejb.rmi.chat.client;
import java.rmi.*;
public interface Receiver extends Remote
{
public void printMsg(String msg) throws RemoteException;
}
package pejb.rmi.chat.server;
import java.rmi.*;
import pejb.rmi.chat.client.Receiver;
public interface Server extends Remote
{
public String CHAT_SERVER = "chatserver";
public void broadcast(String msg) throws RemoteException;
public void addReceiver(Receiver client) throws RemoteException;
public void removeReceiver(Receiver client) throws RemoteException;
}
[출처] 오라클자바커뮤니티 - http://ojc.asia/bbs/board.php?bo_table=LecJavaNet&wr_id=90
자바웹(JAVA,
JSP,Spring,MyBatis,XPlatform)프로젝트과정
자바웹(JSP,Spring,MyBatis,XPlatform)프로젝트과정
강좌명 | 자바웹(JSP,Spring,MyBatis,XPlatform)프로젝트과정(평일야간) 오라클자바커뮤니티(ojc.asia) 추천 실전강좌 |
---|---|
교재 | PDF or 자체교재(교재비 무료) |
강좌 일정 | 상단 URL 참조(최소 개강인원은 5명이며, 5명 미만인 경우 1~2주 정도 강좌가 연기될 수 있습니다.) |
강의 장소 | [D강의장]구로디지털단지역2번 출구 -> 미니스톱끼고 우회전 -> 100m 직진 후 골목길 끝에서
횡단보도 건너기 --> 우회전 후 구로호텔 직전 좌측길, 호텔 바로 뒤편 파트너스타워2차 301호 [약도보기] |
지원절차 | -
강좌내용 확인 후 페이지 하단 "지원하기" 버튼 클릭 - 고용보험 가입자인 경우 관련 서류 제출(아래 "제출서류" 확인) - 교육전 : 개강일자/시간 및 공지사항에 대하여 전화 또는 문자 공지 - 교육당일 : 교육 전 설문 작성(직무, 간단한 개발 경력, 수강 목적, 강좌 진행방식 등) - 교육 중 : 수시로 제출되는 이론/실습 과제에 대하여 제출하면서 SKILL UP - 교육후 : 메인 페이지 좌측 배너 클릭 후 교육 후 설문 작성 |
근로자개인 지원/결제안내 |
-
평일주간 교육은 사업주환급 교육만 가능하며 근로자 개인수강지원(근로자카드,내일배움카드)은 불가능 함. - 근로자 개인수강지원의 경우 재직자내일배움카드 또는 근로자카드 발급 받으신분만 수강 가능 - 카드를 수령하지 않았더라도 근로자카드 신청 후 노동부 승인 받은 상태(2~3일 이후)라면 수강 가능. - 근로자 카드는 고용보험 가입자라면 누구나 간단한 절차를 통해 발급가능.(근로자카드제도 및 발급안내) - 본인부담액은 교육비의 0~20% 이며 계좌이체 ,근로자카드 또는 개인카드로 결제가능 |
사업주훈련 지원/결제안내 |
-
고용보험 가입자에 대하여 환급교육 가능 - 채용예정(확정)된 분은 현재 고용보험 미가입이라도 교육가능.(채용예정 기업에서 결제하고 해당 기업으로 환급) - 교육비는 전액 계좌이체 또는 카드(내방결제만 가능)로 교육전 결제 해야 하며 출석룔80% 이상 수료후 회사에서 관할 산업인력 공단으로 환급신청서 제출해서 환급절차 진행해야 되고, 보통 2~3주 정도 후 회사로 환급됨.(환급룔은 과정마다 다르니 확인필요) |
수강료 입금안내 |
-
계좌이체(메인페이지 좌측 신한은행 계좌) - 카드결제는 방문 카드 결제만 가능하며 온라인 카드결제는 지원하지 않습니다. - 평일주간 기업100%환급 교육은 계좌이체만 가능합니다.(계산서 발급) |
제출서류 | -
고용주/사업주 환급 : 상단 정보마당/자료실의 1번 근로자동의서, 2번 훈련위탁계약서(평일주간 교육은 2번만 필요) - 근로자/내일배움 카드과정 : 상단 정보마당/자료실의 5번 근로자카드,내일배움카드지원자용 신청서 - 제출방법 : 이메일(webmaster@oraclejavacommunity.com) or 팩스(0505-719-4790) or 내방 |
수강료
및 환급금액 강사소개 |
- 상단 URL 참조 |
문의안내 | 02-851-4790 번으로 연락 부탁 드립니다. |
교육개요 | 본
과정은 단기간에 자바의 필요한 부분만을 습득하고 개발자로 거듭날 수 있는 실무프로젝트형 과정 입니다. 자바초보자나 초보자를 대상으로 최소/최적의
이론을 습득 후 팀 단위로 Eclipse/Maven/Gradle/Tomcat/Spring.X/Mibatis/jQUERY/XPlatform
환경에서 미니프로젝트 개발을 하는 과정 입니다. 기반기술은 JAVA, JSP/Servlet, Ajax, jQUERY, Spring4.X, Spring MVC, spring JDBC, Spring DI/DL, Spring AOP, MyBatis, XPlatform이며 수강생들의 수준에 맞게 최적화된 이론수업을 거친 후 프로젝트를 진행합니다. 이론교육시에도 실습을 통한 이론취득에 중점을 두는 과정 입니다. (이론교육의 깊이는 수강생분들의 현재 수준에 따라 조절됩니다!) 자바웹,스프링 개발의 세계에 동참하시기를 바랍니다! |
교육목표 | 자바/스프링/웹개발자
양성 Xplatform 개발환경 습득 스프링전문 실무개발 이론에 충실한 자바 웹개발자로서 SKILL UP 개발력이 있는, 개발가능한 프로그래머 양성 |
교육대상 | 자바개발자가
되고픈 초보자 초보자 or 초보자바개발자 스프링 기반 웹개발을 하고싶은 개발자 |
선수학습 | 프로그래밍기본 데이터베이스기본 |
자바기본 | JDK7/JDK8,
이클립스, KEPLER, MAVEN, Gradle설치 객체지향개요 클래스 패스(Class Path) 개요 Array 이론/실습 클래스와 객체(Class & Object) Abstarct Data Type, 상속(Inheritance)과 다형성 추상클래스(Abstract Class)와 다형성 인터페이스(Interface)와 다형성 추상클래스와 인터페이스의 구별 및 필요성 이해 구현을 인터페이스 뒤로 숨기기 연관(Aggregation & Composition) 오버로딩(OverLoading)과 오버라이딩(Overriding) this/super/constructor 자바 자료 구조 클래스(JCF) List, Set, Map 계열 스트림(Stream) 입출력 관련 클래스, InputStream/OutputStream, FileInputStream/FileOutputStream Reader/Writer등 입출력 관련 클래스 표준 입출력/FILE 처리, 객체 직렬화 이론/실습 Thread 개요 Java에서의 Process Thread Joining/Interrupt Thred동기화 |
---|---|
Servlet/JDBC/JSP | [Servlet] 서블릿 개요 작동원리 web.xml 매핑 방법, @WebServlet 어노테이션 Servlet 라이프 사이클 HttpServletRequest/HttpServletResponse Cookie, Session JDBC 소개 Connection Statement, PreparedStatement, ResultSet CallableStatement JDBC를 이용한 SQL 함수 프로시져 다루는 방법 Insert/Update/Delete/Select 예제 작성하기 [JSP] JSP작성법, Life Cycle 동작원리 기본문법(지시자, 내장객체, 스크립틀릿, 표혐식, 액션태그 등) 쿠키, 세션 다루기 JSTL, EL MVC Model소개, JSP & Model Layer |
AJAX/jQUERY | [AJAX] Ajax개요 Ajax의 기본 구성 XMLHttpRequest 객체 innerHTML, iFrame, XMLDocument 객체 DOM(Document Object Model) 다루기 Ajax에서의 Model Ajax에서의 View Ajax에서의 Controller AJAX 자동 Refresh 예제 [jQUERY] jQuery 개요, 다운로드, 설치 $(document).ready() 메소드 Selector $(“*"), $("#ID"), $("DIV"),$(".classname"), $("p > a"), $(“elementname.classname") 속성 선택자, 속성(attr) 입력양식 필터 선택자 위치와 관련된 필터 선택자 jQuery 배열(Array) 관리 jQuery 객체 확장 기본 필터링 메소드 특정 위치 문서 객체 선택 문서 객체에서 특정 태그를 선택하는 방법 innerHTML 속성과 관련된 jQuery 메서드 문서객체 생성 , 제거 jQuery Event 이벤트 관련 메소드(발생, 제거) 이벤트 자동 발생 마우스/키보드/윈도우/입력양식 이벤트 jQuery 기본효과, 사용자지정효과 jQuery, Ajax 관련 메소드 XML 문서 다루기 입력양식 전송 AJAX & jQUERY |
Spring Framework3.X | JAVA
Bean vs EJB vs Spring J2EE Framework에 대한 흐름과 Spring Framework에 대한 이해 개발 환경 설정(Eclipse4.4, Tomcat8, Spring4, MAVEN, Gradle, STS 다운로드 및 설치) Spring IoC DL(Dependency LookUp) &DI(Dependency Injection) Dependency Pull, CDL(Contaxtualized Lookup) Setter/Constructor/Method Injection DL. DI 예제를 통한 이해 Spring 설정(XML, Annotation) Spring AOP 란 ?Code, Advice, JoinPoint,PointCut Aspect, Weaving, ProxyFactoryBean Annotation기반 AOP(AspectJ) Auto Scanning 컴포넌트 (@Component,@Repository,@Service,@Contoroller) @Resource vs @Autowired ProxyFactoryBean을 통한 AOP 구현 AOP NAMESPACE를 통한 AOP 구현 @AspectJ Annotation을 통한 AOP 구현 Spring JDBC(이론 및 실습) Spring Web MVC (이론 및 실습) Spring4 @MVC MVC관련 Annotation Spring Controller Spring MVC Interceptor @Controller, RequestMapping Spring MVC Multiple File Upload Spring MVC 장바구니 구현, XML응답처리 JSON 응답처리, 컨트롤러 예외처리 Spring 표현언어 SpEL Spring Transaction 관리 @Transactional Annotation, XML설정방식, 프로그래밍적 트랜잭션 처리방법의 이해 Spring Interceptor Spring Scheduling(Quartz연동) Spring4를 이용한 게시판 작성 - 리스트보기,글쓰기,읽기,댓글,답변글처리 - @Controller, @Request매핑 적용 - 주입(DI)를 Annotatrion으로 변경 - Spring AOP를 적용하여 게시판 DML 로깅 하기 - 스프링 게시판에 MyBatis 적용하여 SQL문을 XML안으로 |
MyBatis/Hibernate | [MyBatis] 개요 및 소개 개발환경 설정 및 설치 Data Mapper란 sqlMapConfig 이해 및 환경설정 Spring, MyBatis 연동 SQL Map XML File 이해 SqlMapClient 이해 SQL의 실행(Insert/update/delete) 이해와 실습 고급 쿼리 사용방법의 이해와 실습 Spring MyBatis 응용예제 작성 Spring3.X, MyBatis3 Transaction이론/실습 [Hibernate] Hibernate 소개 SessionFactory 설정 1:1, 1:다 매핑 Session Interface Hibernate DML Spring, Hibernate 예제 프로그램 작성 Hibernate 설정을 Annotation으로...@Entity, @Table, @Id, @Column Spring, Hinernate Transaction 실습 |
Xplatform | Xplatform
소개 설치 및 환경설정 컴포넌트 디자님, 기본화면실습 조회 및 저장 기능 실습 비동기/동기 통신 SDI, M야, 화면상속 MLM 배포 |
Spring,MyBatis,XPlatform 기반 프로젝트 | 프로젝트
주제선정 : Spring @MVC, MyBatis 기반의 쇼핑몰 사용기술요소 : JAVA, JSP, Servlet, AJAX, jQUERY, Spring4, @MVC, MyBatis 기본설계 개발환경구축(Eclipse, SVN, Gradle, MAVEN, STS, Spring4, MyBatis, XPlatform) 기본기능정의 DB모델링 개발 및 시연 |
급여순위 4위 추출 쿼리 튜닝(RANK, INDEX HINT비교)
myemp1은 1000만건... SAL 칼럼은 인덱스 있음
-- 급여순위 4위 추출
1. RANK 분석함수 이용, 8초
SQL> set linesize 130
SQL> SELECT 급여순위, EMPNO,ENAME,SAL
2 FROM (
3 SELECT EMPNO, ENAME, SAL, RANK() OVER(ORDER BY SAL DESC) "급여순위"
4 FROM MYEMP1
5 )
6 WHERE 급여순위=4;
Execution Plan
----------------------------------------------------------
Plan hash value: 2012555084
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10M| 867M| | 95812 (2)| 00:19:10 |
|* 1 | VIEW | | 10M| 867M| | 95812 (2)| 00:19:10 |
|* 2 | WINDOW SORT PUSHED RANK| | 10M| 247M| 345M| 95812 (2)| 00:19:10 |
| 3 | TABLE ACCESS FULL | MYEMP1 | 10M| 247M| | 21377 (1)| 00:04:17 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("급여순위"=4)
2 - filter(RANK() OVER ( ORDER BY INTERNAL_FUNCTION("SAL") DESC )<=4)
2. INDEX_DESC 힌트이용, 0초
SQL> SELECT RNUM, EMPNO,ENAME,SAL
2 FROM (
3 SELECT /*+ index_desc(myemp1 idx_myemp1_sal) */
4 ROWNUM rnum, EMPNO, ENAME, SAL
5 FROM MYEMP1
6 WHERE SAL > 0
7 AND ROWNUM <= 4
8 )
9 WHERE rnum = 4;
Execution Plan
----------------------------------------------------------
Plan hash value: 1328080881
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 364 | 7 (0)| 00:00:01 |
|* 1 | VIEW | | 4 | 364 | 7 (0)| 00:00:01 |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID | MYEMP1 | 5 | 130 | 7 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN DESCENDING| IDX_MYEMP1_SAL | 10M| | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
myemp1은 1000만건... SAL 칼럼은 인덱스 있음
-- 급여순위 4위 추출
1. RANK 분석함수 이용, 8초
SQL> set linesize 130
SQL> SELECT 급여순위, EMPNO,ENAME,SAL
2 FROM (
3 SELECT EMPNO, ENAME, SAL, RANK() OVER(ORDER BY SAL DESC) "급여순위"
4 FROM MYEMP1
5 )
6 WHERE 급여순위=4;
Execution Plan
----------------------------------------------------------
Plan hash value: 2012555084
-------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 10M| 867M| | 95812 (2)| 00:19:10 |
|* 1 | VIEW | | 10M| 867M| | 95812 (2)| 00:19:10 |
|* 2 | WINDOW SORT PUSHED RANK| | 10M| 247M| 345M| 95812 (2)| 00:19:10 |
| 3 | TABLE ACCESS FULL | MYEMP1 | 10M| 247M| | 21377 (1)| 00:04:17 |
-------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("급여순위"=4)
2 - filter(RANK() OVER ( ORDER BY INTERNAL_FUNCTION("SAL") DESC )<=4)
2. INDEX_DESC 힌트이용, 0초
SQL> SELECT RNUM, EMPNO,ENAME,SAL
2 FROM (
3 SELECT /*+ index_desc(myemp1 idx_myemp1_sal) */
4 ROWNUM rnum, EMPNO, ENAME, SAL
5 FROM MYEMP1
6 WHERE SAL > 0
7 AND ROWNUM <= 4
8 )
9 WHERE rnum = 4;
Execution Plan
----------------------------------------------------------
Plan hash value: 1328080881
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 4 | 364 | 7 (0)| 00:00:01 |
|* 1 | VIEW | | 4 | 364 | 7 (0)| 00:00:01 |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | TABLE ACCESS BY INDEX ROWID | MYEMP1 | 5 | 130 | 7 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN DESCENDING| IDX_MYEMP1_SAL | 10M| | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
[평일주간,기업전문교육]닷넷,C#기초에서ADO.NET,ASP.NET까지
http://www.ojcedu.com/onj/curri/curri-master.html?command=1835
닷넷,C#기초에서ADO.NET,ASP.NET까지
|
[평일주간]SQL기초에서Schema Objects까지-재직자환급,근로자카드,SQL학원
평일주간 : http://www.ojcedu.com/onj/curri/curri-master.html?command=1820
강좌명 | SQL기초에서Schema
Objects,힌트,튜닝까지(평일주간(단기)) 오라클자바커뮤니티(ojc.asia) 추천 실전강좌 |
---|---|
교재 | (교재비
30,000원 별도) 본원에서 SQL실무교육을 위해 자체 제작한 교재(SQL초보에서Schema Object까지, PL/SQL,HINT,TUNING) |
강좌 일정 | 상단
URL 참조 (최소 개강인원은 5명이며, 5명 미만인 경우 1~2주 정도 강좌가 연기될 수 있습니다.) |
강의 장소 | [B강의장]구로디지털단지역2번 출구 -> 미니스톱끼고 우회전 -> 100m 직진 후 골목길 끝에서
횡단보도 건너기 --> 우회전 후 구로호텔 직전 좌측길, 호텔 바로 뒤편 파트너스타워2차 301호 [약도보기] |
지원절차 | -
강좌내용 확인 후 페이지 하단 "지원하기" 버튼 클릭 - 고용보험 가입자인 경우 관련 서류 제출(아래 "제출서류" 확인) - 교육전 : 개강일자/시간 및 공지사항에 대하여 전화 또는 문자 공지 - 교육당일 : 교육 전 설문 작성(직무, 간단한 개발 경력, 수강 목적, 강좌 진행방식 등) - 교육 중 : 수시로 제출되는 이론/실습 과제에 대하여 제출하면서 SKILL UP - 교육후 : 메인 페이지 좌측 배너 클릭 후 교육 후 설문 작성 |
근로자개인 지원/결제안내 |
-
평일주간 교육은 사업주환급 교육만 가능하며 근로자 개인수강지원(근로자카드,내일배움카드)은 불가능 함. - 근로자 개인수강지원의 경우 재직자내일배움카드 또는 근로자카드 발급 받으신분만 수강 가능 - 카드를 수령하지 않았더라도 근로자카드 신청 후 노동부 승인 받은 상태(2~3일 이후)라면 수강 가능. - 근로자 카드는 고용보험 가입자라면 누구나 간단한 절차를 통해 발급가능.(근로자카드제도 및 발급안내) - 본인부담액은 교육비의 0~20% 이며 계좌이체 ,근로자카드 또는 개인카드로 결제가능 |
사업주훈련 지원/결제안내 |
-
고용보험 가입자에 대하여 환급교육 가능 - 채용예정(확정)된 분은 현재 고용보험 미가입이라도 교육가능.(채용예정 기업에서 결제하고 해당 기업으로 환급) - 교육비는 전액 계좌이체 또는 카드(내방결제만 가능)로 교육전 결제 해야 하며 출석룔80% 이상 수료후 회사에서 관할 산업인력 공단으로 환급신청서 제출해서 환급절차 진행해야 되고, 보통 2~3주 정도 후 회사로 환급됨.(환급룔은 과정마다 다르니 확인필요) |
수강료 입금안내 |
-
계좌이체(메인페이지 좌측 신한은행 계좌) - 카드결제는 방문 카드 결제만 가능하며 온라인 카드결제는 지원하지 않습니다. - 평일주간 기업100%환급 교육은 계좌이체만 가능합니다.(계산서 발급) |
제출서류 | -
고용주/사업주 환급 : 상단 정보마당/자료실의 1번 근로자동의서, 2번 훈련위탁계약서(평일주간 교육은 2번만 필요) - 근로자/내일배움 카드과정 : 상단 정보마당/자료실의 5번 근로자카드,내일배움카드지원자용 신청서 - 제출방법 : 이메일(webmaster@oraclejavacommunity.com) or 팩스(0505-719-4790) or 내방 |
수강료
및 환급금액 강사소개 |
- 620,000원 [고용주환급] 교육비 62만원 선 결제 후 중소기업: 336,384원 전후, 대기업(1000인 미만) : 252,288원 전후, 대기업(1000인 이상) : 168,192전후 환급 [근로자직업능력개발훈련(근로자카드, 재직자내일배움카드)]중소기업 정규직 20% 본인부담, 중소기업 비정규직/이직예정자/무급휴직자 무료, 대기업 정규직은 전액본인부담, 정규직50세이상/이직예정자 20% 본인부담, 비정규직/정규직무급휴직자 무료 근로자카드 본인부담액은 284,096원 입니다. [휴강] :법정공휴일 |
문의안내 | 02-851-4790 번으로 연락 부탁 드립니다. |
교육개요 | 실무에서
다 년간 SQL튜닝을 경험한 실전 DBA, SQL튜닝 전문가가 진행하는 본 과정은 개발 시 흔히 겪게 되는 최적의 SQL 사용법에 중점을
둔 강좌로서 기본적인 SQL문법, SQL기본함수, 서브쿼리, 조인, 효율적인 인덱스 사용법을 세분화해서 집중적으로 학습합니다. 또한 개발하면서 자주 보게되는 스키마 객체(Schema Object, Table, Index, View, Sequence, Synonym, DBLink)들에 대해 다루며 PL/SQL, Stored Program(Procedure, Function, Oracle Cursor, Package, Trigger)을 마스터 후 오라클 옵티마이저, 실행계획, 오라클의 힌트구문를 통해 실행계획을 효율적으로 수립하는 방법을 학습하며 SQL문의 튜닝의 기본에 대해 학습 합니다. 고급SQL, 효과적인 Index사용, Oracle Hint 등을 적절히 이용 한다면 데이터 검색 시 수분이상 걸리는 SQL문장을 수 초안에 데이터가 검색되도록 SQL튜닝 가능하죠^^, 개발자라면 꼭 알고 있어야 합니다! 고급 SQL 사용법, 그룹함수의 튜닝, 각종 인덱스에 대한 이해, 인덱스 활용법, 조인의 원리, 세미조인, 안티조인의 이해 및 관련된 여러가지 힌트구문을 통해 SQL튜닝에 대한 이해를 철저한 실습을 통해 이해하게 되실 것 입니다. 본 과정은 철저한 실습,실무위주의 교육으로 과정을 수료함으로써 SQL 사용에 대한 자신감 및 SQL SKILL을 향상시킬 수 있을 것 입니다. |
교육목표 | ○
SQL*Plus 사용법에 대한 이해 ○ SQL 기본함수에 대한 이해 ○ SQL 고급함수에 대한 이해 ○ Join 및 Sub Query에 대한 이해 ○ DML, DDL, DCL에 대한 이해 ○ Oracle Index에 대한 이해 ○ Oracle Schema Object 에 대한 이해 (Table, View, Index, Synonym, Trigger, DataBase Link, Sequence등) ○ Oracle Stored Program(Procedure, Function)에 대한 이해 ○ 인덱스를 선정하는 기준에 대한 이해 ○ 효율적인 인덱스 운영 및 관리 ○ B*Tree 인덱스의 단점을 보완하기 위한 기타 인덱스에 대한 이해. ○ Bitmap, Function Based Index, Recerse Key Index에 대한 이해. ○ 대용량 데이터를 효율적으로 저장을 위한 구조에 대한 이해 ○ 실행계획 해석방법의 이해 ○ 통계정보의 이해 ○ Optimizer 구성요소 및 작동원리에 대한 이해 ○ 옵티마이저의 기능과 역할을 실행계획을 통해서 정확히 이해 ○ INDEX생성, DRIVING TABLE의 ACCESS 순서 변경 및 HINT, 분석함수 등을 사용하여 SQL QUERY 의 응답 속도 향상. ○ 조인방식에 대한 이해 및 CASE별 최적의 조인메카니즘을 이해 ○ 오라클 힌트 구문에 대한 이해 ○ 힌트의 사용을 통한 SQL튜닝의 이해 ○ 본인이 작성한 SQL문에 대하여 옵티마이저의 작동 원리를 파악하고 실행계획을 분석 ○ 본인이 작성한 SQL문에 대하여 드라이빙 테이블 및 조인방법/순서를 예측하고실행계획을 분석 ○ 현실 실무에서의 튜닝 사례를 설명하고 튜닝을 위한 명확한 실무 활용기준 가이드를 제시 |
교육대상 | 초보
개발자 or DB에 관심있는 일반인 SQL에 관심있는 개발자 DB전문가가 되기 위한 개발자 |
선수학습 | 데이터베이스에 대한 이해 |
SQL기초에서Schema Objects까지 | 1.
개요 및 실습데이터 설치 1-1. 오라클, 데이터베이스관련 용어 1-2. 오라클 에디션(ORACLE EDITION) 1-3. 오라클 버전 변화 1-4. 실습데이터 설치 및 SQL*PLUS 실행환경 설정 1-4. 실습데이터 구조(테이블 정의서) 1-5. 데이터베이스 무결성(DataBase Integrity) 2. SQL*Plus 2-1. 개요, 시작, 종료 2-2. 데이터베이스 시작, 종료 2-2. SQL*Plus 명령어 2.2.1 주요 명령어 2.2.2 편집 명령어 2.2.3 파일관련 명령어 2.2.4 SET 명령어 2.2.5 형식 명령어 3. 기본 SQL 명령어 3.1 Schema 계정에서의 기본 쿼리문 3.2 기본 쿼리문 3.2.1 SELECT문 3.2.2 산술 표현식(Arithmetic __EXPRESSION__) 3.2.3 칼럼 별명(Column Alias) 3.2.4 합성 연산자(Concatenated Operator) 3.2.5 조건질의와 ORDER BY 3.2.6 SQL 조건연산자를 이용한 조건검색 3.2.7 ANY(SOME), ALL, EXISTS 3.2.8 집합 연산자 3.3 ROWNUM 및 NULL값, NLS_DATE_FORMAT 3.3.1 ROWNUM 3.3.2 NULL이란? 3.3.3 NLS Parameters 3.4 데이터 타입(Data Type) 4. SQL 함수 4.1 문자함수 4.2 집합 함수(Aggreation Function), GROUP BY, HAVING 4.3 숫자 및 날짜 함수(Number And Date Function) 4.3 변환 함수(Conversion Function) 4.4 일반 함수 및 조건식(General Functions and Conditional __EXPRESSION__s) 5. 서브 쿼리(SUB QUERY) 5.1 서브 쿼리(SUB QUERY) 개요 5.2 복수행 서브쿼리(Multi-Row Sub Query) 5.3 상관 서브쿼리(Correlated Sub Query) 5.4 Scalar SubQuery 5.5 인라인뷰(IN_LINE VIEW) 5.6 WITH 구문 6. 조인(JOIN) 6.1 테이블 별명(Table Alias) 6.2 카티션 프로덕트(Cartesian Product) 6.3 EquiJoin, Non EquiJoin 6.4 Self Join 6.5 Outer Join 6.6 계층형 쿼리(Hierarchical Query) 7. 오라클 분석함수(Analytic Function) 및 SQL 활용 7.1 분석함수란? 7.2 분석함수 기본형식(PARTITION BY, ORDER BY, WINDOW구, MAX, MIN, SUM, AVG, DENSE RANK FIRST/LAST, KEEP, OVER) 7.3 분석함수(LISTAGG) 7.4 분석함수(FIRST_VALUE, LAST_VALUE, RANK, DENSE_RANK, ROW_NUMBER) 7.5 SQL활용 8. 테이블(Table) 8.1 테이블(Table)이란? 8.1.1 Create Table 8.1.2 테이블 구조 변경 8.1.3 테이블 이름변경 및 삭제, 주석추가 8.1.5 FlashBack Drop 및 Recycle Bin 8.1.6 데이터 무결성(Data Integrity) 제약조건(Constraints) 8.1.7 오라클11g 읽기전용 테이블 8.1.8 오라클11g 가상 칼럼(Virtual Column) 9. 데이터 딕셔너리(Data Dictionary) 9.1 데이터 딕셔너리 개요 9.2 USER_ 데이터 딕셔너리 뷰 10. DML(Data Manipulation Language) 10.1 DML 개요 10.2 INSERT 명령어 10.2.1 단일행 입력 10.2.2 복수행 입력(Multi Row Insert) 10.3 UPDATE 명령어 10.4 DELETE 명령어 10.5 MERGE 명령어 11. 인덱스(INDEX) 11.1 단일/복합(결합) 인덱스(Single Column/Composite Index) 11.2 고유/비고유 인덱스(Unique/Non Unique Index) 11.3 Descending Index 11.4 함수기반 인덱스(Function Based Index) 11.5 인덱스 재구성 및 삭제 11.6 인덱스 숨기기(Index Invisible) 12. 뷰(VIEW) 12.1 단순 뷰(Simple View) 12.2 복합 뷰(Complex View) 12.3 인라인 뷰(Inline View) 12.4 WITH CHECK OPTION 12.5 DROP VIEW 13. 동의어(Synonym) 14. 시퀀스(Sequence) |
---|---|
PL/SQL, Hint, tuning | 1.
PL/SQL 개요 1-1. PL/SQL 이란? 1-2. PL/SQL 장점 1-3. PL/SQL 작성방법 1-4. PL/SQL 블록 구조 1-5. PL/SQL과 관련된 SQL*Plus 명령어 2. PL/SQL 프로그램 2-1. 함수(Function) 2-2 프러시저(Procedure) 2-3. Stored Program과 Dictionary View 2-4. Function Result Caching 3. PL/SQL 변수, 데이터 타입 3.1 변수, 데이터타입 3.1.1 Scalar Data Type 3.1.2 Composite Data Type(Table Type/Record Type) 3.1.2 %TYPE 속성 3.1.3 %ROWTYPE 속성 3.1.4 Bind(Host) 변수 3.2 PL/SQL에서 SQL문장 사용 3.2.1 SELECT문의 사용 3.2.2 INSERT/UPDATE/DELETE문의 사용 4. PL/SQL 프로그래밍(제어문, 반복문) 4.2 BASIC LOOP문 4.3 FOR LOOP문 4.4 WHILE LOOP문 5. PL/SQL Cursor(커서) 5.2 명시적 커서(Explicit Cursor) 5.3 WHERE CURRENT OF 커서 5.4 Parameterized 커서 5.5 참조커서(REF CURSOR) 5.6 DBMS_SQL 패키지를 이용한 REF CURSOR 6. PL/SQL Exception 6.1 Predefined Exception 6.2 Non-Predefined Exception 6.3 사용자 정의 오류(User Defined Exception) 6.3.1 RAISE 구문을 이용하는 방법 59 6.3.2 RAISE_APPLICATION_ERROR 구문을 이용하는 방법 6.4 예외처리와 SQLCODE, SQLERRM 함수 7. Dynamic SQL 7.1 Dynamic SQL 이란? 7.1.1 동적 SQL을 이용하여 DDL을 실행 7.1.2 Dynamic SQL 사용하기(SQL문을 동적으로 생성) 7.1.3 컴파일 타임에 존재하지 않는 데이터베이스 객체 참조 7.1.4 PL/SQL 블록에서 다른 프러시저, 함수 호출하기 8. 패키지(Package) 8.1 개요 및 기본문법 8.2 전위적 선언(Forward Declaration) 8.3 ONE TIME ONLY PROCEDURE 9. 트리거(Trigger) 9.1 트리거 개요, 기본문법 9.2 Setting Trigger Order 9.3 Trigger Mutating Table Exception 9.4 Compound Triggers 9.5 Trigger Enable/Disable/Drop 10.1 DBMS_STATS 패키지 사용하기 10.2 Optimizer Statistics(Table/Column 통계정보) 10.3 Literal SQL & Bind Variable SQL(Soft Parsing/Hard Parsing) 10.4 CURSOR_SHARING 파라미터 10.5 튜닝의 도구 - SQL AUTOTRACE 10.6 튜닝의 도구 – DBMS_XPLAN 10.7 실행계획 해석 10.8 초기화 파라미터 OPTIMIZER_MODE 10.9 Optimizer Mode Setting 방법 10.10 규칙 기반 옵티마이저(Rule-Based Optimizer) 10.11 비용기반 옵티마이저(Cost-Based Optimizer) 11.1 Optimizer Mode를 변경하는 힌트 (RULE) 11.2 Optimizer Mode를 변경하는 힌트(FIRST_ROWS) 11.3 Optimizer Mode를 변경하는 힌트(ALL_ROWS) 11.4 Optimizer Mode를 변경하는 힌트(CHOOSE) 12.1 실행계획 SQL 연산(AND-EQUAL) 12.2 실행 계획 SQL 연산(CONCATENATION) 12.3 실행계획 SQL 연산(COUNT) 12.4 실행계획 SQL 연산(COUNT STOPKEY) 12.5 실행계획 SQL 연산(FILTER) 12.6 실행계획 SQL 연산(HASH ANTI-JOIN) 12.7 실행계획 SQL 연산(HASH SEMI-JOIN) 12.8 실행계획 SQL 연산(NESTED LOOP SEMI-JOIN) 12.9 실행계획 SQL 연산(INDEX RANGE SCAN) 12.10 실행계획 SQL연산(INDEX RANGE SCAN DESCENDING) 12.11 실행계획 SQL연산(INLIST ITERATOR) 12.12 실행계획 SQL연산(MERGE JOIN) 12.13 실행계획 SQL연산(MERGE SEMI JOIN) 12.14 실행계획 SQL연산(MERGE ANTI-JOIN) 13.1 Hints For Online Application Upgrade (CHANGE_DUPKEY_ERROR_INDEX) 13.2 Hints For Online Application Upgrade (IGNORE_ROW_ON_DUPKEY_INDEX) 13.3 Hints For Online Application Upgrade (RETRY_ON_ROW_CHANGE) 14.1 Oracle Index 구조(B*Tree Index) 14.2 Oracle Index 구조(Bitmap Index) 14.3 비트맵 조인 인덱스(Bitmap Join Index) 14.4 Oracle Index 구조(Reverse Key Index) 15.1 Hints For Access Paths(FULL) 15.2 Hints For Access Paths(CLUSTER) 15.3 Hints For Access Paths(HASH) 15.4 Hints For Access Paths(INDEX, INDEX_COMBINE) 15.5 Hints For Access Paths(INDEX_ASC) 15.6 Hints For Access Paths(INDEX_DESC) 15.7 Hints For Access Paths(NO_INDEX) 15.8 INDEX힌트와 복합(결합)인덱스 15.9 Hints For Access Paths(NO_EXPAND) 15.10 Materialized View(구체화뷰) 15.12 Hints For Access Paths(REWRITE) 15.13 Hints For Access Paths(INDEX_FFS) 15.14 Hints For Access Paths(INDEX_SS) 15.15 Hints For Access Paths(INDEX_JOIN) 15.16 Hints For Access Paths(NATIVE_FULL_OUTER_JOIN) 16.1 중첩루프조인(Nested Loop Join) 16.2 Hints for Join Orders(ORDERED) 16.3 Hints for Join Orders(USE_NL) 16.4 Hints for Join Orders(USE_NL_WITH_INDEX) 16.5 Hints for Join Orders(NO_USE_NL) 16.6 해시조인(HASH JOIN, USE_HASH, NO_USE_HASH) 16.7 Hints for Join Orders(HASH_AJ) 16.8 Hints for Join Orders(HASH_SJ, NL_SJ) 16.9 Hints for Join Orders(USE_MERGE) 16.10 Hints for Join Orders(LEADING) 16.11 RBO에서의 드라이빙 테이블 선정 16.12 CBO에서의 드라이빙 테이블 선정 16.13 Semi Join(세미 조인) 16.14 Anti Join(안티조인) 17.1 Additional Hints(DRIVING_SITE) 17.2 Additional Hints(CACHE, NO_CACHE) 17.3 Additional Hints(CURSOR_SHARING_EXACT) 17.4 Additional Hints(GATHER_PLAN_STATISTCS) 17.5 Additional Hints(DYNAMIC_SAMPLING) 17.6 Additional Hints(RESULT_CACHE) 17.7 Additional Hints(QB_NAME) 18.1 Hints For Query Transformations(UNNEST, NO_UNNEST) 19.1 SQL문 튜닝을 위한 접근 19.2 SQL 작성 TIP |
SQL튜닝 실전사례연구 | SQL튜닝의
도구 AUTO TRACE, EXPLAIN PLAN, 현장 사례연구 INline View, With구문을 활용한 SQL문 튜닝 ORDER BY 튜닝(INDEX, INDEX_ASC, INDEX_DESC를 이용한 튜닝) MAX, MIN 값의 튜닝(INDEX관련 힌트를 이용한 튜닝, MVIEW를 통한 튜닝) MINUS를 사용한 그룹함수 튜닝 COUNT(*) 튜닝(index_ffs를 이용한 튜닝, MVIEW를 이용한 성능 튜닝) Query 및 오라클함수에 대한 RESULT_CACHE 힌트를 이용한 튜닝 DISTINCT의 튜닝(EXISTS) INDEX를 이용한 튜닝(Bitmap, Function Based Index) 비트맵 인덱스를 이용한 OR연산 튜닝 index_ss(SKIP SCANNING)을 이용한 리딩 칼럼이 없는 경우 튜닝 게시판 페이지 나누기 쿼리문 튜닝 순위 매기기 튜닝 서브쿼리 및 조인 튜닝 SQL문 작성 TIP |
피드 구독하기:
글 (Atom)