본문 바로가기
Today I learned

12월28일

by soheemon 2019. 1. 2.


*액션태그<jsp:/>

*useBean 

JSP에서(HTML 태그로) JAVA 객체를 생성하기 위해 사용한다.

<new로 생성하는거는 JAVA코드이다..>

JSP에는 JAVA코드가 들어가면 복잡해지니까.. HTML태그로 JAVA객체를 생성하기 위해서 

useBean액션태그를 사용한다.


*useBean액션태그를 생성한다. id는 name이고, class는 생성할 객체의 class이다. 

<jsp:useBean  id=“connection” class=“myapp.Connection” />


위 액션태그는 아래의 JAVA 코드와 같다.

myapp.Connection connection = new myapp.Connection();


*setProperty 액션태그로 생성한 name객체에 멤버변수 timeout을 value로 설정한다.

<jsp:useBean  id=“connection” class=“myapp.Connection” >

      <jsp:setProperty name=“connection” property=“timeout” value=“33”/>

</jsp:useBean>


위 액션태그는 아래의 JAVA 코드와 같다.

 myapp.Connection connection = new myapp.Connection();

   connection.setTimeout(“33”);



*useBean객체를 이용하여 form데이터 전송하기.

예를들어 만약 client에서 form의 submit을 이용하여 request로 각각의 parameter를 전송한다고 하자.

서버에서 이 데이터를 받기 위해서는 request.getParamter('파라미터이름');으로 하나하나 가져와야 할것이다.

폼에서 받을 데이터가 기하급수적으로 늘어나면 getParameter 메서드를 수십번 호출해야하는 아찔한 현상이 발생한다.

JAVA를 배웠던것을 돌이켜보면 

이런 상황에서 수십개의 파라미터를 객체화 해서 던질거라고 짐작 할 수 있다.

어떻게 할까?


*useBean으로 객체를 생성하여 request.getParameter 메서드 대체하기.

<!> 위 예제의 전제조건은, 뷰에서 사용자에게 입력을 받는 input태그의 이름이, 

JAVA클래스의 멤버변수 이름과 같아야 하며

setter getter 메서드가 있어야 한다.

//setProperty 예제 board객체를 생성해서 board객체에 전달인자를 각각 맵핑해서 설정한다.

//이것이 가능한것은, input태그의 이름과 Board클래스의 멤버변수 이름과 같기 때문이다!

//전달인자가 Board클래스 멤버변수 갯수보다 적어도 괜찮다. 




//form에서 작성자, 제목, 내용을 입력받아서 콘솔에 출력해보는 간단한 게시판 예제

기존과 같은 request.getParameter()메서드를 이용해 전달인자를 받는것이 아닌,
useBean액션태그를 이용해 Board객체를 생성하여
Paramter를 한번에 받아 올 수 있는 예제.

1) Form

2)Board클래스
위에서 언급했던것과 마찬가지로 input태그의 name과 멤버변수의 이름이 일치해야 하며
setter, getter 메서드가 있어야 한다.

3)DAO
BoardDao는 DB에 데이터를 입력하기 위한 클래스라고 가정하고,
싱글톤패턴으로 객체를 생성하며
동작결과를 확인하기위해 임시적으로 Board객체를 전달인자로 받아서 콘솔에 출력한다. <따라서 toString 메서드도 필요하다>

4)form에서 submit을 하면 해당 페이지로 전달된다.
우선 useBean사용전에 인코딩을 위해 request.setCharacterEncoding()를 사용하여 utf-8로 인코딩으로 해주고
useBean액션태그를 사용하여 id board로 객체를 생성한다.<이것은 스크립트릿코드에서 변수명이 된다>
class속성은 서버상에서 생성할 클래스의 경로이다.

setProperty액션태그와 property=”*”를 사용하면 name과 일치하는 id의 넘어오는 모든 파라미터를 전부 가져온다. 
*property에서 적절하게 받고싶은 파라미터만 넘겨받을 수도 있다.
물론 위에서 언급한바와 같이, input name과 클래스의 멤버변수의 이름이 일치하는 파라미터만 받을 수 있다.

그리고 스크립트릿에서 BoardDao객체를 최초 1회 생성 한다.
이는 매번 DB에 접근 할 때 마다 new로 새롭게 객체를 생성하면 메모리를 낭비하기 때문이다.
그래서 싱글톤패턴으로 최초1회 생성해서 사용한다.
객체 생성시 usebean으로 생성한 객체 board를 insertBoard로 콘솔에 출력하게 된다.

*JDBC
데이터베이스를 연결할 수 있는 매개체라고 할 수 있다.
각각의 회사에서 제공한다.
톰캣 라이브러리폴더에 JDBC 라이브러리를 넣는다.

*Oracle 서버와 직접 연결을 시도하는 방식!
1)JDBC 드라이버 로드
2)데이터베이스와 연결
3)SQL문 실행
4)데이터베이스와 연결을 끊는다.

1)JDBC 드라이버 로드


import java.sql.*;

Class.forName("oracle.jdbc.driver.OracleDriver");


2)데이터베이스 연결 객체인 Connection 생성


Connection con = null;

con = DriverManager.getConnection(url, uid, pwd);


//url JDBC형식 URL, uid 사용자명, pwd 패스워드 지정

//예> DriverManager.getConnection('jdbc:oracle:thin:@localhost:1521:XE', kosta192, 1234);


localhost: oracle이 설치된 IP주소

1521: oracle port 번호

XE: oracle 서버 버전



3)Statement 객체 생성하기


Statement stmt = con.createStatement();

//prepareStatement가 성능이 좋아서 이거를 쓰자.


4)SQL문을 실행하여 결과 처리


String str = "select * from member";

ResultSet rs = stmt.executeQuery(str);


//executeQuery() = SELECT문과 같이 결과값이 여러개의 레코드로 구해지는 경우에 사용한다.

//executeUpdate() INSERT, UPDATE, DELETE문과 같은 내부으로 테이블의 내용이 변경만 되고 결과값이 없는경우 사용


4-1) executeQuery()메서드와 SELECT 문

SELECT 실행시 BOF(Before the First)에 커서가 위치한다.

따라서 resultSet메서드의 next()메서드를 사용하여 다음행에 접근하자.

-next() 현재 행에서 한행 다음으로 커서 이동

-previous() 현재 행에서 한행 이전으로 커서 이동

-first() 현재 행에서 첫번째 행으로 커서 이동

-last() 현재 행에서 마지막 행으로 커서 이동


String str = "select * from member";

ResultSet rs = stmt.executeQuery(str);

while(rs.next()){

<%= rs.getString("id")%>

<%= rs.getString(1)%>//컬럼 순서대로 숫자로 접근 가능

}



*DAO 클래스 = Data Access Object

데이터에 접근하기 위한 객체.

DB에 데이터를 읽고 쓰고 삭제하기 위한 객체.


*Board객체의 두가지 종류

1)form에있는 데이터를 담기위한 역할<BoardForm 혹은 BoardCommand>


2)결과가 여러개면 DB의 데이터를 객체화해서 리스트화한다.

하나의 로우를 하나의 객체로 맵핑하는 역할=이름:VO, DTO


*예제



하지만.. 이방식은 DBMS에 접근할때마다

connection을 새로 생성해줘야 한다. => 비효율적!


*톰캣에서 연결해주는 방식 DBCP

데이터베이스 처리속도가 올라간다.

이전 예제는 connection객체를 새로 만들고.. 사용하고 버린다.

=> 많은 자원을 낭비하게 된다ㅠ


DBCP 기법

미리 POOL에 커넥션 객체를 담아놓고 커넥션 객체를 사용한다. 다 사용하면 반납한다.

새롭게 생성하는 일이 없다!


DBCP는 DBCP매니저가 어느 정도의 연결을 확보해 놓고 있다가 클라이언트의 요청이 들어오면 연결해 주고, 클라이언트 작업이 다 끝나면 연결을 다시 풀 매니저에게 반환하게 만드는 것이다.


*리소스 태그

리소스를 사용 할 수 있는 naming


DataSource객체를 얻을 수 있다.

=커넥션풀이라고 생각하자.

=커넥션객체가 들어가 있다.


<Resource auth="Container" driverClassName="oracle.jdbc.driver.OracleDriver" maxActive="100" maxIdle="30" maxWait="10000" name="jdbc/oracle" password="1234" type="javax.sql.DataSource" url="jdbc:oracle:thin:@localhost:1521:XE" username="kosta192"/>


name: java:comp/env와 관련하여 생성되어지는 자원의 이름을 기술한다. 여기서는 "jdbc/oracle"이라 작성했다.

auth: 컨테이너의 자원 관리자로 기술할 수 있는데 
Application 혹은 Container가 속성값으로 온다. 
대부분 Container를 사용한다.
type: 웹에서 수행되어질 때 웹상에서 자원의 이름을 찾으면 type 속성 값에 기술된 클래스로 내보내진다. 
여기서는 javax.sql.DataSource를 속성값으로 사용했다. 
jdbc/oracle이라는 이름을 찾으면 이름에 해당되는 객체 타입이 javax.sql.DataSource으로 리턴된다. 


=server.xml 가보면 이런게 나온다.

:이후가(여기선jsp) 프로젝트 이름인데 프로젝트 마다 설정 할 수 있다.

//아래에는 설정 전이다.

 

//해당 프로젝트의 Context 태그 에 Resource 태그를 넣어준다.


*커넥션풀을 활용한 예제




//글을 클릭하면 상세글을 볼 수 있는 기능



* JAVA JDBC 에러날때

네트워크 어댑터 에러 => 해당부분 다시시작한다.


*에러정리

classes12.zip 이 연결이 안된 경우입니다.

java.lang.ClassNotFoundException: oracle.jdbc.driver.OracleDriver

at java.net.URLClassLoader$1.run(URLClassLoader.java:200)

at java.security.AccessController.doPrivileged(Native Method)

at java.net.URLClassLoader.findClass(URLClassLoader.java:188)

at java.lang.ClassLoader.loadClass(ClassLoader.java:297)

at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:286)

at java.lang.ClassLoader.loadClass(ClassLoader.java:253)

at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:313)

at java.lang.Class.forName0(Native Method)

at java.lang.Class.forName(Class.java:120)

at getEmp.main(getEmp.java:18)


해결1: classes12.zip을 classes12.jar 로 이름을 바꾼 뒤에 <CATALINA_HOME>/common/lib 에 놓고 재시동



host 주소가 맞지 않은 경우입니다.

또는 listener가 떠있지 않은 상태입니다.

java.sql.SQLException: IO 예외 상황: The Network Adapter could not establish the connection

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:156)

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:269)

at oracle.jdbc.driver.OracleConnection.(OracleConnection.java:210)

at oracle.jdbc.driver.OracleDriver.getConnectionInstance(OracleDriver.java:251)

at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:224)

at java.sql.DriverManager.getConnection(DriverManager.java:517)

at java.sql.DriverManager.getConnection(DriverManager.java:177)

at getEmp.main(getEmp.java:20)


db명이 틀릴경우입니다. 호스트스트링이라고도 합니다.

java.sql.SQLException: IO 예외 상황: Connection refused(DESCRIPTION=(TMP=)(VSNNUM=135290880)(ERR=12505)(ERROR_STACK=(ERROR=(CODE=12505)(EMFI=4))))

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:156)

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:269)

at oracle.jdbc.driver.OracleConnection.(OracleConnection.java:210)

at oracle.jdbc.driver.OracleDriver.getConnectionInstance(OracleDriver.java:251)

at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:224)

at java.sql.DriverManager.getConnection(DriverManager.java:517)

at java.sql.DriverManager.getConnection(DriverManager.java:177)

at getEmp.main(getEmp.java:20)


아이디와 패스워드가 틀릴경우입니다.

java.sql.SQLException: 널 사용자나 암호가 THIN 드라이버에서 지원되지 않습니다

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:114)

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:156)

at oracle.jdbc.dbaccess.DBError.check_error(DBError.java:803)

at oracle.jdbc.ttc7.TTC7Protocol.logon(TTC7Protocol.java:179)

at oracle.jdbc.driver.OracleConnection.(OracleConnection.java:198)

at oracle.jdbc.driver.OracleDriver.getConnectionInstance(OracleDriver.java:251)

at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:224)

at java.sql.DriverManager.getConnection(DriverManager.java:517)

at java.sql.DriverManager.getConnection(DriverManager.java:177)

at getEmp.main(getEmp.java:20)


//출처: https://okky.kr/article/307


*당신을 구원할, Mybatis

뻘유머) Mybatis의 다음버전 이름은 Mebatis이다.

I My Me

ㅋ...

(사실이 아닙니다)


프레임워크다.: 잘 짜여진 틀이다.

Mybatis 프레임워크다.


프레임워크 사용하는이유: 코드의 일관성을 위하여

틀이기 때문에 일관성있는 코드를 사용 할 수 있다.


lowlevel에 있는 get..set..했던 low레벨 개발을 프레임워크가 대신해준다.


스프링프레임워크도 많은 작업들을 대신해주고… 개발자는 비즈니스로직에 집중 할 수 있고….! 아주좋다

=프레임워크 사용은 개발의 역량과 직결이 됩니다..!


DB와 데이터 = 프리젠테이션 티어 데이터 접근 긴 트랜잭션의 

퍼시스턴스 티어 :

오브젝트 릴레이셔널 매핑 ORM 프레임워크

mybatis = sql 결과값이랑 자바 오브젝트랑 맵핑해주는 방식!

하이버네이트 JPA = 각 테이블과 객체들간의 1:1 맵핑방식 = 복잡해 ㅜ.ㅜ.ㅜ



아래 이미지와 같이 JDBC를 그냥 사용하는거랑, 프레임워크로 사용하는거랑은 천차 만별이다.
그러니까 프레임워크 쓰자!


+Mybatis는 이어집니다.


'Today I learned' 카테고리의 다른 글

1월3일  (0) 2019.01.03
2019년 1월2일  (0) 2019.01.02
12월14일  (0) 2018.12.27
12월27일  (0) 2018.12.27
12월13일  (0) 2018.12.26

댓글