728x90
300x250

[Spring-Framework] 3. Eclipse와 Apache Maven 프로젝트 - 구축하기(1)


Spring-Framework의 배경이 되는 Maven(이하 "Apache Maven") 프로젝트에 대해서 소개하려고 한다.


비고: 최신 Eclipse 개발도구에는 Maven Project가 내장되어 있음.


수동으로 콘솔 환경 등의 명령어로 Maven 개발환경을 구축하는 방법부터 시작해서 Eclipse 내장기능으로 사용하는 방법에 대해서 소개하겠다.



[Maven 개발방법]

1. 콘솔 등으로 수작업 개발 및 코딩
   (1, 2항목을 잘 읽어보면 도움이 될 것으로 보인다.)

2. Eclipse IDE 등을 활용한 Maven 개발환경 구축





1. Apache Maven Project


Apache Maven Project 사이트에 들어가면, Maven 프로젝트에 대해서 소개 및 자세한 내용을 살펴볼 수가 있다.


아파치 메이븐?

Apache Maven은 소프트웨어 프로젝트 관리 및 이해 도구이다.
프로젝트 개체 모델 (POM)의 개념을 기반으로 Maven은 중앙 정보에서 프로젝트의 빌드,보고 및 문서를 관리 할 수 있다.


URL: https://maven.apache.org/



그림 1. Apache Maven Project



그림 2. Apache Maven - Download


그림 2의 사이트에서 apache-maven-3.6.3.bin.zip을 내려받아서 수동으로 설치할 수 있다.





2. Maven 개발환경 - 설치하기


내려받은 apache-maven-3.6.3-bin을 압축푼다.



그림 3. apache-maven-3.6.3-bin 압축 풀기


apache-maven-3.6.3-bin.zip을 압축 푼다.

그러면, 폴더 하나가 생성되는 것을 확인할 수 있다.



그림 4. apache-maven-3.6.3


경로를 메모해둔다.

-> D:\apache-maven-3.6.3-bin\apache-maven-3.6.3





3. Maven 개발환경 - 시스템 환경설정


방금 전에 압축 푼 폴더를 바탕으로 Maven 개발환경을 셋팅할 것이다.



그림 5. apache-maven-3.6.3 - 시스템 환경 변수(N)


"시스템 -> 오른쪽 버튼 -> 속성"을 누른다.

"고급 시스템 설정 -> 고급 탭 -> 환경 변수(N)"을 클릭한다.



그림 6. apache-maven-3.6.3 - 시스템 환경 변수(N)


시스템 변수(S)에서 "Path" 변수를 찾아서 클릭한다.

"편집(I)"을 누른다.




그림 7. apache-maven-3.6.3 - 시스템 환경 변수(N)


맨 아래 항목에 아까 메모해둔 경로를 입력해준다. ("복사", "붙여넣기"를 권장함.)



4. Maven 개발환경 - 명령 프롬프트로 구축환경 확인하기


앞에 단계를 잘 했다면, 확인해야 할 것이다.

아래의 과정을 잘 따라하도록 하자.



그림 8. 명령 프롬프트 - 관리자 권한으로 실행하기


시작 메뉴에 cmd라고 입력 후 "관리자 권한으로 실행"을 클릭한다.



그림 9. 명령 프롬프트 - 관리자 권한으로 실행하기


mvn -version


이라고 명령어를 입력하면, 그림 9의 출력화면을 볼 수 있다.



5. Maven - Repository 경로 변경


기본 Maven Repository는 ${user.home}/.m2/repository 라는 폴더에서 관리한다.
dev 폴더에서 관리하도록 저장소를 로컬로 바꿀것이다.
dev 폴더에서 관리하길 원하지 않는다면, 이 단계는 넘어가도 된다.


[경로 변경 방법]

1. D:\.........중략......\apache-maven-3.6.2 에서 repository 폴더를 생성한다.

2. D:\.........중략......\apache-maven-3.6.2\conf 에서 settings.xml 파일을 연다. 

3. setting.xml 파일에서 <localRepository> 주석 처리된 부분을 찾은 뒤, 그 위에다 로컬 저장소를 등록한다.



그림 10. 폴더 만들기


임의의 폴더명 "repository"라는 폴더를 만들어본다.



그림 11. 환경설정 변경하기(1) - 변경 전


약 53줄에 있는 <localRepository>~</localRepository>를 복사해서 (빈 줄) 55줄 정도에 붙여넣는다.

[주석이 없는 빈줄에 넣어주기]



그림 12. 환경설정 변경하기(1) - 변경 후


입력을 완료하였다면, 저장을 누른다.





6. 응용 - Eclipse 프로젝트에 수동 설치한 Apache Maven 적용하기


최근 eclipse는 기본적으로 Apache Maven을 내장하고 있다.

하지만, 굳이 수동으로 설치한 Maven을 사용하고 싶다면, 다음처럼 사용할 수도 있다.



그림 13. Preferences 설정하기


"Window->Preferences"를 클릭한다.



그림 14. Preferences 셋팅하기


Maven 탭에서 Installations을 클릭한다.

그리고 "Add..." 버튼을 클릭한다.




그림 15. Preferences 셋팅하기


Directory 버튼을 누른다.



그림 16. Preferences 셋팅하기


apache-maven-3.6.3의 설치 경로를 선택한 후 "폴더 선택"을 누른다.




그림 17. Preferences 셋팅하기


설정을 확인한 후 "Finish"를 누른다.



그림 18. Preferences 셋팅하기


"apache-maven-3.6.3"을 체크한다.

그리고 "Apply"를 누르면 적용이 완료된다.



그림 19. Preferences 셋팅하기


사용자 환경설정에 관한 것이다.

Maven 탭에서 User Settings를 클릭한다.


[기본값]

User Settings: C:\Users\사용자계정명\.m2\settings.xml

Local Repository: C:\Users\사용자계정명\.m2\repository




그림 20. Preferences 셋팅하기


앞서 환경설정을 변경한 경로를 찾아서 선택한 후 "settings"를 열기한다.

(비고: Apache-maven-3.6.3\conf폴더 내에 settings.xml 파일이 존재함)



그림 21. Preferences 셋팅하기


그림 21처럼 변경한 후 "Apply"를 누르면 적용이 완료된다.



7. 맺음글(Conclusion)


Apache Maven 프로젝트를 설치하는 방법과 개발 환경 구축이라는 주제를 소개하였다.



* 참고 자료(Reference)


1. Maven - Welcome to Apache Maven, https://maven.apache.org/, Accessed by 2020-09-19, Last Modified 2020-09-10

반응형
728x90
300x250

[JSP] 8. 영속프레임워크 MyBatis를 활용한 CRUD 구현 - JSP와 Oracle(XML 방식)


조금 알기 쉽게 작성하였다.

"영속 프레임워크"라고 보면 된다.

영속 프레임워크라는 것은 DAO 객체에서 데이터베이스 데이터의 처리 기능을 제공하는 프레임워크이다.


대표적인 것: myBatis, Hibernate가 있다.


* 사용되는 언어: JSP / Servlet,
* 데이터베이스: Oracle 12 이상 (Oracle 18g에서 태스트 완료 하였음.)

* 프레임워크: mybatis-3.5.5

[첨부(Attachments)]

mybatis-3.5.5.jar

mybatis-3.5.5(원본).7z



1. 최소한 관련 프레임워크에 대해서 이해해보기


프레임워크의 특징에 대해서 간단하게 작성해보았다.


[특징]


myBatis란 그나마 학습하기 쉽고, 사용방법이 간단함.

초기 셋팅을 조금한 후에 나머지는 SQL명령문과 간단한 자바 소스코드로 구현하여 사용할 수 있음.

(iBatis 프로젝트로 시작해서 현재는 Apache Foundation에서 관리하는 자바 오픈소스 프레임워크)


http://www.mybatis.org


hibernate란 ORM(Object-Relational Mapping) 프레임워크라는 영속 프레임워크로서 자바와 객체와 데이터베이스를 매핑하여 데이터를 처리하므로 엔터프라이즈 환경에 적합한 특징을 가지고 있음.

(배우기 어려움. - 객체 모델링 경험이 요구됨.)


http://hibernate.org 



[생각해보기]


생각을 조금해본다면, 꼭 반드시 웹 프로젝트에만 MyBatis를 활용할 필요가 없음.
일반적인 Swing 프로젝트 연습 등에서도 사용해볼 수도 있겠음.

- 프레임워크 사용하기 전에 고민해야 할 점

1. 기본적으로 제공하는 JDBC 구현에 대해서도 생각해보기

(이유: 자바에서 자체적으로 제공하는 jdbc 구현(예: ResultSet, prepareStatement 등)에 대해서 이해하고 있으면 좋음.)


2. 프레임워크를 사용하는 것이 만능인지, 고민하기

3. SQL Injection 등의 보안 문제에 대해서 생각하기

   (프레임워크를 사용하면, SQL Injection 문제는 간단하게 해소된다.)


결론은 좋긴 좋다. 프레임워크!!!


[코드 비교하기] 


 Mybatis 사용전 코드 방식

 Mybatis 사용후 코드 방식

 

public Entity selectFAQList(UserConnection conn, Entity param)  throws SQLException 

{

    UserStatement stmt = null; //stmt 초기값 선언
    ResultSet rslt = null; //rslt 초기값 선언
    StringBuffer sql = new StringBuffer();
    sql.append("\n SELECT *"); //
    sql.append("\n FROM"); //코드 추가
    sql.append("\n TABLE1");
    stmt = conn.prepareStatement(sql.toString());
    rslt = stmt.executeQuery();
    Entity _DATA = new Entity();
    _DATA.put("_DATA", EntityUtil.ResultSetToClobList(rslt));
    return _DATA;
}

 <?xml version="1.0" encoding="UTF-8"?>

  <ENTITY id="table.getTable1List" type="SQL" return="List">
    <![CDATA[
        SELECT *
            FROM
            TABLE1
    ]]>
    <PARAMS>    
    </PARAMS>
  </ENTITY>

// xml로 빼내서 쿼리문을 작성하면 내부적 처리는 Mybatis에서 // 모두 처리해주므로
// Entity ID값을 java에서 호출만하면 된다.




2. 초기 환경설정 셋팅하기


시중 블로그를 다수 검색하고, 교제등을 참고하였으나 왕초보 수준으로 알기 쉽게 적용하는 방법은 나오지 않은 거 같아서 작성해보려고 한다.



그림 1. 초기 셋팅해줘야 하는 프로젝트 파일


최소 못해도 기본적으로 갖춰줘야 하는 소스 파일들을 몇 개 찝어보았다.


"Address_****.파일확장자명"으로 구성된 파일은 사용자에 따라 임의적으로 구성해봐도 무방하다.


ojdbc8_g.jar은 어디에 있는가?

오라클 설치파일이 있는 폴더에 보면 jdbc 폴더가 있는데 해당 위치에 있다.



그림 2. 오라클 설치 파일이 있는 폴더



그림 3. jdbc 폴더에 있는 readme.txt



그림 4. jdbc/lib 폴더 내에 있음.



[첨부(Attachments)]

oracle12lib.z01

oracle12lib.z02

oracle12lib.zip


(참고로 반디집을 통해서 압축을 풀 수 있음.)


소스코드를 통해서 살펴보는 것이 조금 빠를 수 있다고 주장해 본다.



3. 데이터베이스 설계하기


예제 데이터베이스를 설계하도록 하겠다.


tableName(테이블명): addressbook


 키

 항목명

 속성 

 PK(기본키)

num

인덱스(ID)

 

name

nvarchar

 

address

nvarchar

 

birthdate

date




그림 5. 테이블 만들기(오라클)


그림 5는 SQL Developer를 통해서 테이블을 생성한 모습이다. 

원래 복잡하게 쿼리라는 것을 통해서 작성해야 하는데, 세상이 시간이 지나다보니 편리해진 것도 있다고 주장한다.


CREATE TABLE "C##USER"."ADDRESSBOOK" 

   ( "NUM" NUMBER(*,0) NOT NULL ENABLE, 

"NAME" NVARCHAR2(20), 

"ADDRESS" NVARCHAR2(100), 

"BIRTHDATE" DATE, 

CONSTRAINT "ADDRESSBOOK_PK" PRIMARY KEY ("NUM")



  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

...............................

(중략)


ALTER TRIGGER "C##USER"."ADDRESSBOOK_TRG" ENABLE;



그림 6. SQL문으로 Create Table 구성하기


그림 6은 흔히 CRUD(Create Read Update Delete)에서의 Create를 의미하는 작업이다.

예를 들면 원래는 이렇게 복잡하게 작성해야 하는데 지금은 훨씬 편하게 만들 수 있다고 보면 된다.




4. 프로젝트 구성하기 - 과정 소개 (소스코드를 통해서 살펴보는 프로젝트 구성)


1단계 설계

SQL - 테이블 작성


2단계 기본 환경설정 작성(준비)

web.xml을 먼저 작성한다.              (암기가 되는 부분인가? 불가능. 이거 외우는 거 불가능.)

mybatis-config.xml                     (암기가 되는 부분인가? 불가능. 이거 외우는 거 불가능.)

SqlMapSessionFactory.java           (암기가 되는 부분인가? 불가능. 이거 외우는 거 불가능.)

AddressDto.java 

addressMapper.xml                    (암기가 되는 부분인가? 불가능. 이거 외우는 거 불가능.)


3단계(간단한 CRUD 템플릿 준비)

addressDao.java                       (암기가 되는 부분인가? 코드는 간단하나 2단계 셋팅이 안 되어 있으면 의미 없음.)


4단계(인터페이스 설계 및 구현부 작성)

address.java 

addressImpl.java


5단계(뷰 페이지 구성하기)

web.xml (수정 - 작업)

servlet 페이지로 진행 또는 jsp파일로 진행해도 무방




5. 소스코드


소스코드는 순서대로 소개하겠다.


(2단계 - 소스코드)


<?xml version="1.0" encoding="UTF-8"?>


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"

version="3.1">


<display-name>edu-mybatis</display-name>

<welcome-file-list>

<welcome-file>index.html</welcome-file>

<welcome-file>index.htm</welcome-file>

<welcome-file>index.jsp</welcome-file>

<welcome-file>default.html</welcome-file>

<welcome-file>default.htm</welcome-file>

<welcome-file>default.jsp</welcome-file>

</welcome-file-list>

<!-- Board List -->

<servlet>

<servlet-name>boardList</servlet-name>

<servlet-class>com.edu.view.BoardListServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>boardList</servlet-name>

<url-pattern>/board/list.do</url-pattern>

</servlet-mapping>

<!-- Board Insert -->

<servlet>

<servlet-name>boardInsert</servlet-name>

<servlet-class>com.edu.view.BoardInsertServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>boardInsert</servlet-name>

<url-pattern>/board/insert.do</url-pattern>

</servlet-mapping>

<!-- Board Delete -->

<servlet>

<servlet-name>boardDelete</servlet-name>

<servlet-class>com.edu.view.BoardDeleteServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>boardDelete</servlet-name>

<url-pattern>/board/delete.do</url-pattern>

</servlet-mapping>

</web-app>


* 파일명: web.xml


[첨부(Attachments)]

web.zip



예를 들면, 이런 형태로 구성해서 사용할 수 있다.

크게 어렵게 작성하진 않았으니 참고하면 도움이 될 것 같다.


<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 

"http://mybatis.org/dtd/mybatis-3-config.dtd">


<configuration>


<environments default="development">

    <environment id="development">

      <transactionManager type="JDBC"/>

      <dataSource type="POOLED">

        <property name="driver" value="oracle.jdbc.driver.OracleDriver" />

        <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>

        <property name="username" value="사용자 계정"/>

        <property name="password" value="비밀번호"/>

      </dataSource>

    </environment>

  </environments>


  <mappers>

    <mapper resource="com/edu/db/addressMapper.xml"/>              // 리소스 증가시 추가해서 사용해보기

  </mappers>


</configuration>


* 파일명: mybatis-config.xml



[첨부(Attachments)]

mybatis-config.zip



package com.edu.db;


import java.io.IOException;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;

import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.ibatis.session.SqlSessionFactoryBuilder;


public class SqlMapSessionFactory {

public static SqlSessionFactory ssf;


    static{


        String resource = "com/edu/db/mybatis-config.xml";

        InputStream inputStream = null;


        try {

            inputStream = Resources.getResourceAsStream(resource);

        } catch (IOException e) {

            e.printStackTrace();

        }


        ssf = new SqlSessionFactoryBuilder().build(inputStream);


    }

    

    public static SqlSessionFactory getSqlSessionFactory(){

        return ssf;

    }

    

}



* 파일명: SqlMapSessionFactory.java


[첨부(Attachments)]

SqlMapSessionFactory.zip


package com.edu.db;


import java.sql.Timestamp;


public class AddressDto {

private int num;

private String name;

private String address;

private Timestamp birthdate;

public int getNum() {

return num;

}

public void setNum(int num) {

this.num = num;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

public Timestamp getBirthdate() {

return birthdate;

}

public void setBirthdate(Timestamp birthdate) {

this.birthdate = birthdate;

}

}



* 파일명: AddressDto.java


[첨부(Attachments)]

AddressDto.zip


<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE mapper

  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<mapper namespace="com.edu.db.mappers.addressMapper">

<select id="allAddress" resultType="com.edu.db.AddressDto">

select * from addressbook

</select>


<select id="selectAddress" parameterType="Integer" resultType="com.edu.db.AddressDto">

select NUM, NAME, ADDRESS, BIRTHDATE

from addressbook

  where num=#{num}

</select>


<insert id="insertAddress" parameterType="com.edu.db.AddressDto">

insert into

addressbook(NAME, ADDRESS, BIRTHDATE)

values

(#{name},#{address},#{birthdate})

</insert>


<delete id="deleteAddress" parameterType="Integer">

DELETE FROM AddressBook

WHERE NUM = #{num}

</delete>

<update id="updateAddress" parameterType="com.edu.db.AddressDto" >

update addressbook

set birthdate = #{birthdate}, name = #{name}, address =#{address}

where num = #{num}

</update>

</mapper>


* 파일명: addressMappper.xml


[첨부(Attachments)]

addressMapper.zip


(3단계 - 소스코드)


package com.edu.db;

import java.io.*;

import java.util.*;

import org.apache.ibatis.io.*;

import org.apache.ibatis.session.*;


public class AddressDao {

private AddressDao() {}

    private static AddressDao dao;


    public static AddressDao getInstance(){


        if(dao == null){

            dao = new AddressDao();

        }


        return dao;

    }

    

    // SQL 세션 열기

    SqlSessionFactory factory = SqlMapSessionFactory.getSqlSessionFactory();


    public AddressDto selectAddress(Integer num) {


        SqlSession session = factory.openSession();


        AddressDto addressDTO = session.selectOne("com.edu.db.mappers.addressMapper.selectAddress", num);

        session.close();


        return addressDTO;


    }


 


    public int updateAddress(AddressDto addressDTO) {


        SqlSession session = factory.openSession();


        int update = session.update("com.edu.db.mappers.addressMapper.updateAddress", addressDTO);


        // update나 delete의 경우 반드시 커밋 필요.

        // session.commit();을 해주거나 factory.openSession(true);로 설정하면 자동 커밋된다.

        session.commit(); 

        session.close();


        return update;


    }

    

    

    public int insertAddress(AddressDto addressDTO) {

   

    SqlSession session = factory.openSession();

    int insert = session.insert("com.edu.db.mappers.addressMapper.insertAddress", addressDTO);

   

    session.commit();

    session.close();

   

    return insert;

   

    }

    

    public int deleteAddress(Integer num) {

   

    SqlSession session = factory.openSession();

    int delete = session.delete("com.edu.db.mappers.addressMapper.deleteAddress", num);

   

    session.commit();

    session.close();

   

    return delete;

    }


}


* 파일명: AddressDao.java


특징: Singleton 패턴을 적용함.


[첨부(Attachments)]

AddressDao.zip



(4단계 - 소스코드)


package com.edu.db;


public interface Address {


public AddressDto getAddress(Integer num);

public int updateAddress(AddressDto addressDTO);

public int insertAddress(AddressDto addressDTO); 

public int deleteAddress(Integer num);

}


* 파일명: Address.java


특징: Interface 파일


[첨부(Attachments)]

Address.zip


package com.edu.db;


public class AddressImpl implements Address {


AddressDao dao = AddressDao.getInstance();

@Override

public AddressDto getAddress(Integer num) {

return dao.selectAddress(num);

}


@Override

public int updateAddress(AddressDto addressDTO) {

return dao.updateAddress(addressDTO);

}

@Override

public int insertAddress(AddressDto addressDTO) {

return dao.insertAddress(addressDTO);

}

@Override

public int deleteAddress(Integer num) {

return dao.deleteAddress(num);

}


}


* 파일명: AddressImpl.java


특징: Address 인터페이스 구현파일


[첨부(Attachments)]

AddressImpl.zip


(5단계 - Servlet 파일 예)


package com.edu.view;


import java.io.IOException;

import java.io.PrintWriter;

import java.sql.Timestamp;

import java.text.SimpleDateFormat;


import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.edu.db.Address;

import com.edu.db.AddressDto;

import com.edu.db.AddressImpl;


/**

 * Servlet implementation class boardListServlet

 */

public class BoardListServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

       

    /**

     * @see HttpServlet#HttpServlet()

     */

    public BoardListServlet() {

        super();

    }


/**

* @see HttpServlet#doGet(HttpServletRequest req, HttpServletResponse res)

*/

protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

res.setContentType("text/html;charset=UTF-8");

PrintWriter out = res.getWriter();

out.print("<br/>");

AddressImpl address = new AddressImpl();

AddressDto addressDto = address.getAddress(1);

out.println("<html><head><title>CRUD - List2</title></head>");

out.println("<body><h2>MyBatis - List</h2>");

SimpleDateFormat format1 = new SimpleDateFormat ( "yyyy-MM-dd" );

String birthdate = format1.format(addressDto.getBirthdate());

out.print(addressDto.getNum() + "/" + addressDto.getName() + "/");

out.print(addressDto.getAddress() + "/" + birthdate);

out.print("<br/>");

out.println("</body></html>");

out.close();

}

/**

* @see HttpServlet#doPost(HttpServletRequest req, HttpServletResponse res)

*/

protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doGet(req, res);

}


}



* 파일명: boardListServlet.java


어노테이션으로 맵핑하지 않고, web.xml에 URL 맵핑하였음.


[첨부(Attachments)]

BoardListServlet.zip


package com.edu.view;


import java.io.IOException;

import java.io.PrintWriter;

import java.sql.Timestamp;


import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.edu.db.Address;

import com.edu.db.AddressDto;

import com.edu.db.AddressImpl;


/**

 * Servlet implementation class boardInsertServlet

 */

public class BoardInsertServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

       

    /**

     * @see HttpServlet#HttpServlet()

     */

    public BoardInsertServlet() {

        super();

    }


/**

* @see HttpServlet#doGet(HttpServletRequest req, HttpServletResponse res)

*/

protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

res.setContentType("text/html;charset=UTF-8");

PrintWriter out = res.getWriter();

out.print("<br/>");

AddressImpl address = new AddressImpl();

AddressDto dbNode = new AddressDto(); 

dbNode.setName("도도" + serialVersionUID);

dbNode.setAddress("행복시 행복동");

// 버그1: new Date() 사용안됨. (2020을 3920으로 인식함.) 

// 버그2: new Timestamp() 사용안됨. (2020을 3920으로 인식함.)

String userDate = "2020-02-01";

java.sql.Timestamp sqlDate = java.sql.Timestamp.valueOf(userDate);

dbNode.setBirthdate(sqlDate);

int result = address.insertAddress(dbNode);

AddressDto addressDto = address.getAddress(1);

out.println("<html><head><title>CRUD - Insert</title></head>");

out.println("<body><h2>MyBatis - Insert</h2>");

out.print("<br/>");

out.print("등록여부:" + result + "</br>");

out.print("<br/>");

out.print(addressDto.getNum() + "/" + addressDto.getName() + "/");

out.print(addressDto.getAddress() + "/" + addressDto.getBirthdate());

out.println("</body></html>");

out.close();

}

/**

* @see HttpServlet#doPost(HttpServletRequest req, HttpServletResponse res)

*/

protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doGet(req, res);

}


}


* 파일명: boardInsertServlet.java


[첨부(Attachments)]

BoardInsertServlet.zip



package com.edu.view;


import java.io.IOException;

import java.io.PrintWriter;

import java.sql.Timestamp;


import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.edu.db.Address;

import com.edu.db.AddressDto;

import com.edu.db.AddressImpl;


/**

 * Servlet implementation class boardInsertServlet

 */

public class BoardDeleteServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

       

    /**

     * @see HttpServlet#HttpServlet()

     */

    public BoardDeleteServlet() {

        super();

    }


/**

* @see HttpServlet#doGet(HttpServletRequest req, HttpServletResponse res)

*/

protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

res.setContentType("text/html;charset=UTF-8");

PrintWriter out = res.getWriter();

out.print("<br/>");

AddressImpl address = new AddressImpl();

int result = address.deleteAddress(5);

AddressDto addressDto = address.getAddress(5);

out.println("<html><head><title>CRUD - Delete</title></head>");

out.println("<body><h2>MyBatis - Delete</h2>");

out.print("<br/>");

out.print("삭제여부:" + result + "</br>");

out.print("<br/>");

if ( addressDto != null ) {

out.print(addressDto.getNum() + "/" + addressDto.getName() + "/");

out.print(addressDto.getAddress() + "/" + addressDto.getBirthdate());

}

out.println("</body></html>");

out.close();

}


/**

* @see HttpServlet#doPost(HttpServletRequest req, HttpServletResponse res)

*/

protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doGet(req, res);

}


}



* 파일명: BoardDeleteServlet.java


[첨부(Attachments)]

BoardDeleteServlet.zip



package com.edu.view;


import java.io.IOException;

import java.io.PrintWriter;

import java.sql.Timestamp;


import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;


import com.edu.db.AddressDto;

import com.edu.db.AddressImpl;


@WebServlet("/board/update.do")

public class BoardUpdateServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

       

    /**

     * @see HttpServlet#HttpServlet()

     */

    public BoardUpdateServlet() {

        super();

    }


/**

* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

*/

protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

res.setContentType("text/html;charset=UTF-8");

PrintWriter out = res.getWriter();

out.print("<br/>");

AddressImpl address = new AddressImpl();

AddressDto dbNode = new AddressDto();

dbNode.setNum(3);

dbNode.setName("도도수정" + serialVersionUID);

dbNode.setAddress("행복시 행복동");


// 버그1: new Date() 사용안됨. (2020을 3920으로 인식함.) 

// 버그2: new Timestamp() 사용안됨. (2020을 3920으로 인식함.)

String userDate = "2020-07-01";

java.sql.Timestamp sqlDate = java.sql.Timestamp.valueOf(userDate);

dbNode.setBirthdate(sqlDate);

int result = address.updateAddress(dbNode);

AddressDto addressDto = address.getAddress(3);

out.println("<html><head><title>CRUD - Update</title></head>");

out.println("<body><h2>MyBatis - Update</h2>");

out.print("<br/>");

out.print("수정여부:" + result + "</br>");

out.print("<br/>");

out.print(addressDto.getNum() + "/" + addressDto.getName() + "/");

out.print(addressDto.getAddress() + "/" + addressDto.getBirthdate());

out.println("</body></html>");

out.close();

}


/**

* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

*/

protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {

doGet(req, res);

}


}



* 파일명: BoardUpdateServlet.java


특징: web.xml으로 맵핑하지 않고, @WebServlet으로 어노테이션을 사용하여 매핑처리함.


[첨부(Attachments)]

BoardUpdateServlet.zip




6. 맺음글


순수한 JSP 기반의 MyBatis 프레임워크 사용방법에 대해서 소개해보았다.

많은 도움이 되었으면 좋겠다.


1. [JSP] 19. MyBatis-3.5.5 와 Maven / Servlet 연동하기 (Oracle 19g) - Java 방식, 2020-10-01

https://yyman.tistory.com/1434



[참고 자료(Reference)]


1. [Java, OpenJDK] Timestamp 형식 변환, https://infotake.tistory.com/16, Accessed by 2020-09-18, Last Modified 2018-09-13.

-> 참고 이유: Timestamp 명령 사용방법 참고함.


2. 내가 그리는 세상  DB(mysql)에 timestamp로 저장된 값 java에서 불러오기_getTimestamp(), https://yoonka.tistory.com/450, Accessed by 2020-09-18, Last Modified 2013-10-28.


3. [JSP] Mybatis 사용하기  또리야 개발하자, https://ddoriya.tistory.com/entry/JSP-Mybatis-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0, Accessed by 2020-09-17, Last Modified 2014-11-18.

-> 추천(60점 이상): 이 사이트의 글만 가지고 따라하면, 완벽하게 동작이 되진 않음. 몇 가지 보충을 해줘야 해서 추가적으로 검색하였음.
그래도 순수한 MyBatis 원리에 대해서 많은 영감을 얻었음.


4. Oracle와 mybatis 연동 실습, https://dlgkstjq623.tistory.com/228, Accessed by 2020-09-18, Last Modified 2019-06-05.

-> 추천(40점 이상): 이 사이트의 글을 이해하려면, Spring Framework 지식과 JSTL 지식이 있어야 함.

   기본적인 흐름 정도 파악하는데 참고하였음. (이론적인 느낌을 얻었음.)


5. MyBatis – 마이바티스 3 | 소개, https://mybatis.org/mybatis-3/ko/index.html, Accessed by 2020-09-18, Last Modified 2020-06-05.

-> 추천(20점 이상): 설명서가 조금 어렵게 되어 있음. 셋팅 파일을 가지고 셋팅한 후 설명서를 참고하면 도움이 될 수도 있음.


6. 4. Spring Boot Oracle DB 연동(JSP, MyBatis), https://dotheright.tistory.com/173, Accessed by 2020-09-18, Last Modified 2020-07-15.

-> 삽질하여 실패와 탐구 등의 횟수 기록이 담겨져 있음. ("삽질을 하게 된다.??" 이런 느낌을 보여줌.)

-> Spring Framework 기반으로 만든 소스코드를 소개하고 있음. (이 게시글 작성에 있어서 크게 영향을 주지 못함.)


7. [JSP] JSP에 MyBatis 연결하기, https://yuja-kong.tistory.com/8, Accessed by 2020-09-18, Last Modified 2018-04-17.

-> 추천(50점 이상): 순수한 JSP와 MyBatis 연결에 대해서 소개하고 있는데, 이 글을 작성할 수 있는 가능성을 만들어 줌.


8. JSP 서블릿 한글 세팅(한글 깨짐 해결 하기), https://developsd.tistory.com/100, Accessed by 2020-09-18, Last Modified 2019-05-18.

-> 추천(20점): 오라클DB(이하 "UTF-8 셋팅한 오라클")로 데이터를 불러오려고 했을 때, ?????라고 한글을 인식하지 못했음.

   간단한 명령어 하나로 해결하는 데 도움을 받았음. (가끔은 쉬운 게 어렵고, 어려운 게 쉬울 때도 있다는 생각이 듬.)


1. 파일의 인코딩 속성을 "UTF-8"으로 변경

2. response.setContentType("text/html;charset=UTF-8");


반응형
728x90
300x250

[Spring-Framework] 2. Eclipse의 UTF-8 프로젝트로 환경설정하기


Eclipse의 UTF-8 프로젝트로 환경설정하는 방법에 대해 소개하겠다.


적용 대상: Eclipse IDE 기반의 프로그램 (사용가능) // 웹 프로젝트의 예



- 문자 집합(Character Set): 사람이 사용하는 문자를 컴퓨터가 이해하는 기호로 표현하기 위해 문자를 각 코드(숫자)에 매칭 시킨 것


  컴퓨터에서 문자를 처리하려면 인코딩, 디코딩 과정이 필요하다.
  (예: 컴퓨터라는 게 아날로그, 디지털 이런 형태가 있다고 하면 흔히 1,0로 구성되어 있기 때문이다. - 쉽게 이해를 돕기 위해서 작성함.)

- 인코딩(Encoding)/부호화: 각 문자를 특정 기호로 변환.

  ex) 유니코드를 UTF-8로 인코딩


- 디코딩(Decoding)/복호화: 변환된 기호를 다시 문자로 변환


웹에서는 문자열 처리가 무척 중요하다고 할 수 있다.

Euc-kr로 했다가 UTF-8로 변경하면 문자가 깨져버리는 현상이 발생할 수 있다. (이유: 문자 집합이 다르기 때문)


1. Window의 Preferences 변경 


Window의 Preferences를 클릭한다.



그림 1. Preferences 클릭하기




그림 2. Encoding 검색하기 - Eclipse Preference


General -> Workspace -> Text file encoding -> Other: UTF-8


Web -> CSS Files -> UTF-8로 변경

Web -> HTML Files -> UTF-8로 변경

Web -> Jsp Files -> UTF-8로 변경



그림 3. Css Files -> 인코딩 Unicode(UTF-8)로 변경하기



그림 4. HTML Files 인코딩 형식 바꾸기



그림 5. JSP Files 인코딩 형식 바꾸기

반응형
728x90
300x250

[Spring-Framework] 1. 간단한 소개, STS 4 설치와 실행


오랜만에 글을 작성한다.

스프링 프레임워크에 대해서 간단하게 소개하려고 한다.

Java 기반으로 만든 프레임워크라고 이해하면 되겠다.

과거의 전자정부 프레임워크의 기반이 되는 원래 프레임워크는 Spring Framework Project라고 보면 되겠다.


https://egovframe.go.kr/   (이 게시글에서는 기억할 필요가 없음. 초간단하게 작성하기 위함)

http://spring.io


기본적인 셋팅은 간단하다고 보면 된다.

주로 어디에 사용되는 프레임워크냐면, 국내에서는 웹 개발 프로젝트에 많이 사용되는 것으로 알려져 있다.


물론 순수하게 jsp model1기반으로 작성된 웹 페이지도 있다.




[1. Spring Framework 사이트에서 프로젝트 내려받기]


https://spring.io/tools



그림 1. Spring Tools 4 for Eclipse 사이트(2020-09-15)


Projects에서 Development Tools의 Spring Tools 4를 클릭한다.


그림 2. Spring Tools 4 for Eclipse 사이트(2020-09-15)


버전은 크게 리눅스(Linux 64-BIT), MACOS 64-BIT, 윈도우 64비트(Windows 64bit) 버전으로 3가지로 구성된다.

운영체제에 맞는 걸로 내려받으면 된다.



2. 압축 풀기


spring-tool-suite-4-4.7.2.RELEASE-e4.16.0-win32.win32.x86_64.self-extracting.zip을 압축풀면 내부 폴더에 contents.zip이라는 파일이 있다.

이 파일도 압축을 풀어준다.



그림 3. 프로그램 설치 완료


이렇게 되어있으면 설치는 완료된 것이라고 보면 되겠다.



4. 프로그램 실행


Spring Tools Suites는 SpringToolSuite4.exe 파일을 실행시키면 된다.



그림 4. SpringToolSuite4 - 위치 찾기


IDE 사용자체를 놓고 본다면, Eclipse 기반이므로 친숙하게 적응할 수 있다.
(MVC패턴, 프레임워크 사용방법 등 생략하고 IDE만 놓고 보면)



그림 5. SpringToolSuites 4-4.7.2 (2020-09-15)


신 버전과 이전 버전의 차이점
신 버전에서는 Legacy Project 등을 사용하려면, Help->Eclipse MarketPlace에서 STS를 검색하여 Add-On을 설치해야 한다.




5. MarketPlace의 STS 검색 후 Add-On 설치하기


Spring Tools 3 Add-On for Spring Tools 4 3.9.14.CI를 찾으면 된다. (Legacy Project 등 이전 버전의 부가기능을 사용하고자 할 때)



그림 6. Eclipse Marketplaces의 모습(2020-09-15)


"Install"을 클릭한다.



그림 7. Install 모습


Confirm을 눌러서 다음 과정을 진행한다.



그림 8. 라이선스에 관한 것


오픈소스 라이선스에 관한 것이다. I accept the terms of the.....을 체크하고 Finish를 누른다.



그림 9. 설치중 모습(2020-09-15)


기다리면 된다.



그림 10. Restart Now 누르기 전 모습 - Eclipse(STS)


Restart Now를 누르면 STS 프로그램이 다시 시작된다.



6. Spring Project -> 새 프로젝트 확인해보기


이전 "STS3"버전에서 사용했던 부가 기능이 존재하는지 확인할 수 있다.



그림 11. File -> New -> Project 모습


File -> New -> Other를 클릭한다.



그림 12. Spring 프로젝트 내에 이전의 부가 기능


STS3 하위 버전을 설치하지 않아도 부가 기능 추가로 다시 활용할 수도 있다.

반응형
728x90
300x250

[PHP] Oracle, MySQL - PDO 사용방법

 

간결하게 요약해서 작성해보았다.

 


1. Oracle, MySQL 데이터베이스 설계하기

 

데이터베이스를 하나 생성한다.

Member를 생성한다.

 

 

그림 1) Oracle SQL Developer에서 Member 테이블 생성하기(Oracle 18c Express Edition)

 

 

그림 2) HeidiSQL에서 Member 테이블 생성하기(MySQL)

 

 
  CREATE TABLE "C##RABBITSUN2"."MEMBER"
   ( "ID" VARCHAR2(20 BYTE) NOT NULL ENABLE,
 "SUBJECT" VARCHAR2(20 BYTE),
  CONSTRAINT "MEMBER_PK" PRIMARY KEY ("ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE
  PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
 NOCOMPRESS LOGGING
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" ;

  CREATE OR REPLACE EDITIONABLE TRIGGER "C##RABBITSUN2"."MEMBER_TRG"
BEFORE INSERT ON MEMBER
FOR EACH ROW
BEGIN
  <<COLUMN_SEQUENCES>>
  BEGIN
       IF INSERTING AND :NEW.ID IS NULL THEN
           SELECT MEMBER_SEQ.NEXTVAL INTO :NEW.ID FROM SYS.DUAL;
           END IF;
  END COLUMN_SEQUENCES;
END;
/
ALTER TRIGGER "C##RABBITSUN2"."MEMBER_TRG" ENABLE;

 Oracle SQL

 CREATE TABLE `member` (
     `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
     `subject` VARCHAR(50) NULL DEFAULT NULL,
      PRIMARY KEY (`id`)
 )
 COLLATE='utf8_general_ci'
 ENGINE=InnoDB
 AUTO_INCREMENT=1;

 MySQL SQL

 

 

 


2. Oracle, MySQL - PDO 사용방법(소스코드)

 

<?php

/*
 * Subject: PDO
 * Created Date: 2019-12-10
 * Author by: 도도(Dodo) / rabbitsun2@gmail.com
 * Description:
 *
 * Reference:
 * 
 */

include 'MySQLDB.php';
include 'OracleDB.php';

$orcl = new OracleDB('127.0.0.1', 'c##rabbitsun2', '1234');
$orcl->connect();

// SELECT 문(OracleDB)
$query = "SELECT * FROM MEMBER";
$list = $orcl->select($query);

/*
foreach($list as $row){
   
    echo $row["ID"] . "/";
    echo $row["SUBJECT"] . "<br>";
   
}
*/

// INSERT 문(OracleDB)
//$subject = '연습';
//$result = $orcl->insert($subject);

$mysqlDB = new MySQLDB('127.0.0.1', 'rabbit2me', '1234', 'rabbit2me');
$mysqlDB->connect();

$list = $mysqlDB->select($query);

foreach($list as $row){
   echo $row["id"] . "/";
   echo $row["subject"] . "<br>";
}
 
$subject = '연습';
$result = $mysqlDB->insert($subject);

?>


[소스코드: index.php]

 

?>

class MySQLDB{
   
    private $hostName;
    private $userName;
    private $passwd;
    private $tns;
    private $dbh;
   
    public function __construct($hostName, $userName, $passwd, $dbname){
       
        $this->tns = "mysql:host=$hostName;dbname=$dbname";
       
        $this->hostName = $hostName;
        $this->userName = $userName;
        $this->passwd = $passwd;
       
       
    }
   
    public function __destruct(){
        unset($this->dbh);
    }
   
    public function connect(){
       
        $tns = $this->tns;
        $db_username = $this->userName;
        $db_password = $this->passwd;
       
        try{
            $this->dbh = new PDO($this->tns, $db_username, $db_password,
                array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
            //echo "참";
        }catch(PDOException $e){
            echo ($e->getMessage());
        }
       
    }
   
    public function select($query){
       
        $stmt = NULL;
        $dbh = $this->dbh;
       
        if ( $dbh != NULL ){
            $stmt = $dbh->prepare($query);
            $stmt->execute();
            $list = $stmt->fetchAll();
           
            return $list;
        }
       
        return NULL;
       
    }
   
    public function insert($subject){
       
        $stmt = NULL;
        $dbh = $this->dbh;
        $query = "INSERT INTO member(subject) VALUES(:subject)";
       
        if ( $dbh != NULL ){
            $stmt = $dbh->prepare($query);
            $stmt->bindParam(':subject', $subject);
            $stmt->execute();
           
            return true;
        }
       
        return false;
       
    }
   
}

?>


[소스코드: MySQLDB.php]

 

?>
class OracleDB{
   
    private $hostName;
    private $userName;
    private $passwd;
    private $tns;
    private $dbh;
   
    public function __construct($hostName, $userName, $passwd){
       
        $this->tns = "(DESCRIPTION =
            (ADDRESS_LIST =
              (ADDRESS = (PROTOCOL = TCP)(HOST = $hostName)(PORT = 1521))
            )
            (CONNECT_DATA =
              (SERVICE_NAME = xe)
            )
        )";
       
        $this->hostName = $hostName;
        $this->userName = $userName;
        $this->passwd = $passwd;
        $this->dbh = NULL;
       
    }
   
    public function __destruct(){
        unset($this->dbh);
    }
   
    public function connect(){
       
        $tns = $this->tns;
        $db_username = $this->userName;
        $db_password = $this->passwd;
       
        try{
            $this->dbh = new PDO("oci:dbname=". $tns . ";charset=UTF8", $db_username, $db_password);
            //echo "참";
        }catch(PDOException $e){
            echo ($e->getMessage());
        }
       
    }
   
    public function select($query){
       
        $stmt = NULL;
        $dbh = $this->dbh;
       
        if ( $dbh != NULL ){
            $stmt = $dbh->prepare($query);
            $stmt->execute();
            $list = $stmt->fetchAll();
           
            return $list;
        }
       
        return NULL;
       
    }
   
    public function insert($subject){
        $stmt = NULL;
        $dbh = $this->dbh;
        $query = "INSERT INTO MEMBER(SUBJECT) VALUES(:subject)";
       
        if ( $dbh != NULL ){
            $stmt = $dbh->prepare($query);
            $stmt->bindParam(':subject', $subject);
            $stmt->execute();
           
            return true;
        }
       
        return false;
       
    }
   
}

?>


[소스코드: OracleDB.php]

반응형
728x90
300x250
[PHP] xampp v3.2.4에서 Oracle-PDO, MySQLi 등 설정하기

 

xampp v3.2.4에서 Oracle-PDO, MySQLi 등 설정하는 방법에 대해 간단하게 소개하겠다.

아래의 그림을 따라하면 된다.

 


1. php.ini 환경설정 하기

 

XAMPP Control Panel v3.2.4은 C:\xampp에 있다.

xampp-control.exe를 더블클릭한다.

 

 

그림 1) xampp v3.2.4 설정하기의 예

 

 

그림 2) xampp v3.2.4 설정하기의 예

 

그림 2처럼 찾기 창을 띄우려면, Ctrl + F를 누른다.

oci를 입력한다.

 

 

그림 3) xampp v3.2.4 설정하기의 예

 

사용하고자 하는 ;extension을 extension으로 바꾼다.

 

 사용하지 않는 것

 사용하는 것

 ;extension

 extension

 

 

 

그림 4) xampp v3.2.4 서비스 시작

 

Apache의 Start를 누르면 그림 4처럼 바뀐다. Apache 글자배경이 녹색계열로 뜨면 정상적으로 서비스가 실행되었음을 알리는 것이다.

 


2. 셈플 소스코드(PHP-PDO)

 

PHP 셈플 코드이다.

 

 

 

그림 5) PHP-PDO-oci 셈플코드

 

<?php

$tns = " 
(DESCRIPTION =
    (ADDRESS_LIST =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
    )
    (CONNECT_DATA =
      (SERVICE_NAME = xe)
    )
  )
       ";
$db_username = "c##rabbitsun2";
$db_password = "1234";

try{

    $conn = new PDO("oci:dbname=".$tns,$db_username,$db_password);
    echo "참";

    }catch(PDOException $e){
    echo ($e->getMessage());
}
 
?>

 

 

그림 6) PHP-PDO-oci 셈플코드 (웹사이트에서 접속하기)

 

그림 6은 localhost/test.php에서 확인할 수 있다.

 


* 참고자료(Reference)

1. PHP: Oracle (PDO) - Manual, Last Modified, Accessed by 2019-12-10, https://www.php.net/manual/en/ref.pdo-oci.php

반응형
728x90
300x250
[PHP] Apache 2.4, PHP 7, Oracle 18c Express Edition 윈도우 환경에서 연동하기

 

PHP 7 그리고 Oracle 18c Express Edition을 연동하는 방법에 대해서 소개하겠다.

 

[작성환경]

MS윈도우 10 64bit (Microsoft Windows 10 64bit)

 


1. Oracle 내려받기

 

https://www.oracle.com/technetwork/database/database-technologies/express-edition/downloads/index.html

 

 

 

그림 1) Oracle 18c Express 내려받는 모습

 

 


2. Apache2.4에 PHP 7.3.12 연동하기

 

Apache24 - https://www.apachelounge.com/

PHP 7.3.12 - https://www.php.net/downloads.php

 

 

 

그림 2) Apache2.4에 연동하기 위한 모습(1단계)

 

 

 

 

그림 3) Apache2.4에 연동하기 위한 모습(2단계)

 

그림 3은 php.ini-production 파일을 복사 붙여넣기하여 php.ini으로 변경한 것이다.

 


3. Apache2.4의 conf\httpd.conf 설정하기


소스코드 285줄을 보면, DirectoryIndex가 있다.

index.php을 추가한다.

 

 수정 전

 수정 후

 <IfModule dir_module>

         DirectoryIndex index.html

 </IfModule>

 <IfModule dir_module>

         DirectoryIndex index.html index.php

 </IfModule>

 

 

 

그림 4) conf\httpd.conf 수정하기

 

 

그림 5) Apache 2.4 맨 하단에 php 모듈 적용시키기

 

그림 5처럼 맨 하단에 php 모듈을 적용시킨다.

 

# [추가하기]
PHPIniDir "C:/php7"
LoadModule php7_module "C:/php7/php7apache2_4.dll"
AddType application/x-httpd-php .html .php
AddHandler application/x-httpd-php .php

 

 


4. PHP 폴더명 변경하기

 

PHP 폴더명은 php7로 변경해준다.

 

 

그림 6) php7 폴더명 변경해주기

 


5. Apache 2.4의 htdocs 폴더 내에 phpinfo.php 생성하기

 

C:\Apache24\htdocs\ 내에 phpinfo.php을 만들어준다.

그리고 아래처럼 타이핑을 해준다.

 

 

그림 7) phpinfo.php 파일 만들기

 


6. PHP에 Oracle 연동하기

 

아래의 그림은 초기 php.ini의 모습이다.

 

 

그림 8) php.ini 초기 설정의 모습

 

수정할 내용은 ";extension=pdo_oci"를 "extension=pdo_oci" 이렇게 바꿀 것이다.

 

 

그림 9) php.ini 환경설정 변경의 예(1)

 

 변경 전

 변경 후

 ;extension=mbstring

 extension=mbstring

 ;extension=mysqli

 extension=mysqli

 ;extension=pdo_mysql

 extension=pdo_mysql

 ;extension=pdo_oci

 extension=pdo_oci

 

 

 

 

 

그림 10) php.ini 환경설정 변경의 예(2)

 


7. Oracle Instant Client Downloads

 

https://www.oracle.com/database/technologies/instant-client/downloads.html

 

 

그림 11) Instant Client - Oracle

 

 

그림 12) Instant Client - Oracle

 

 

그림 13) Instant Client - Oracle

 

그림 13처럼 C:\util\Instantclient.version으로 옮겨준다.

 


8. Instant Client를 위한 시스템 속성 변경해주기

 

Instant Client를 위한 시스템 속성 변경해준다.

내 PC에서 시스템 속성을 클릭한다.

 

 

그림 14) 시스템 속성 클릭하기

 

 

그림 15) 시스템 정보 클릭하기

 

 

그림 16) 고급 시스템 설정 클릭하기

 

 

그림 17) Instant Client - Oracle

 

"고급" 탭 클릭 후 "환경 변수(N)..."을 클릭한다.

 

그림 18) Instant Client - Oracle

 

시스템 변수(S)의 Path 변수를 클릭 후 "편집(I)..."을 클릭한다.

 

 

그림 19) Instant Client - Oracle

 

그리고 C:\util\instantclient_version을 찾아보기하여 등록한다.

 


8. PHP-PDO-OCI

 

https://www.php.net/manual/en/ref.pdo-oci.php

 

안 될 경우에는 https://www.apachefriends.org/index.html 에 접속하셔서 xampp로 진행하는 것도 하나의 방법이다.
개발이 목적이기 때문이다.
반응형
728x90
300x250
[MFC] 메시지 처리 - Timer(타이머) 만들기

 

Visual Studio 2019(C++.NET MFC 142)에서 Timer(타이머)를 작성해보도록 하겠다.

실시간 타이머는 말 그대로 일정+시간을 의미하는 타이머이다.

일상생활에서 컴퓨터의 "날짜 및 시간"을 보면 확인할 수 있다.

아래의 그림은 정적인 Timer이다.

 

 

이번 예제는 동적인 실시간 타이머를 구현하도록 하겠다.

 

[작성 환경]
Microsoft Visual Studio 2019
Microsoft Windows 10

 


1. 프로젝트 생성하기

 

프로젝트 생성하는 방법은 이전 예제에서도 다루고 있지만, SDI, MDI 등이 있을 수 있어서 표기하고 있다.

 

 

그림 1) 프로젝트 생성하기

 

 

그림 2) 프로젝트 생성하기

 

 

그림 3) 프로젝트 생성하기

 

 

그림 4) 프로젝트 생성하기

 

 

그림 5) 프로젝트 생성하기

 

 

그림 6) 프로젝트 생성하기

 


2. 변수 만들기, 클래스 마법사, 코드 입력하기

 

코드 작성 전략을 소개하면 크게, "변수 만들기"->"클래스 마법사"->"코드 입력하기" 순서로 진행해볼 수 있겠다.

 

 

그림 7) 프로젝트 생성 후 첫 화면

 

 

그림 8) 클래스 뷰에서 "CTimerDigitalView" 오른쪽 버튼 후 추가에서 변수 추가(B)... 클릭하기

 

그림 8처럼 따라서 진행하도록 한다.

 

 

그림 9) 변수 추가의 예(m_bTimerRun)

 

그림 9의 변수는 타이머의 실행 유무를 bool(부울)로 체크하는 함수이다.

 

 

그림 10) 코드 완성의 예

 

정상적으로 변수가 생성되었음을 알 수 있다. 그림 8처럼 그림 11을 다시 따라하도록 한다.

 

 

그림 11) 변수 추가의 예

 

 

그림 12) m_bTimerType 변수 추가 모습

 

그림 12는 m_bTimerType이라는 변수를 추가하고 있는 모습이다. m_bTimerType의 목표는 타이머 출력의 형식을 어떻게 할지 추후에 구현할 때 사용하게 될 것이다. 이 예제에서는 추후 고려에 대해서만 담고 있다.

 

 

그림 13) Timer_DigitalView.cpp 더블 클릭

 

그림 13은 CTimerDigitalView::CTimerDigitalView를 변형한 모습을 담고 있다.

 

// CTimerDigitalView 생성/소멸

CTimerDigitalView::CTimerDigitalView() noexcept
           :m_bTimerRun(false)
           , m_bTimerType(true)
{
           // TODO: 여기에 생성 코드를 추가합니다.

}

 

코드를 입력한다.

 


3. 생성자 만들기

 

Ctrl+Shift+X 단축키를 클릭해서 클래스 마법사를 실행한다.

메시지 탭을 클릭 후, "WM_Create"라고 입력한다.

그리고 "처리기 추가(A)"를 클릭한다.

OnCreate를 선택한 후, "코드 편집(E)"를 클릭한다.

 

 

그림 14) 클래스 마법사 실행하기

 

그림 15처럼 코드를 입력한다.

 

 

그림 15) OnCreate에 코드 작성하기

 

// CTimerDigitalView 메시지 처리기


int CTimerDigitalView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
        if (CView::OnCreate(lpCreateStruct) == -1)
              return -1;

 

        // TODO:  여기에 특수화된 작성 코드를 추가합니다.


        SetTimer(0, 1000, NULL);  // 타이머 설정
        m_bTimerRun = TRUE;    // 타이머 동작

        return 0;
}

 


4. 메시지 출력을 담을 변수 추가하기

 

다음은 메시지 출력을 담을 변수를 추가할 것이다.

CString 자료형으로 메시지 출력을 담을 것이다.

 

CTimerDigitalView를 오른쪽 버튼한 후, "추가", "변수 추가(B)..."를 클릭한다.

 

 

그림 16) 변수 추가의 모습

 

 

그림 17) m_strTimer 변수 추가 모습

 

변수를 추가한 후, 확인을 누른다.

Ctrl+Shift+X키를 눌러서 클래스 마법사를 호출한다.

 

 

그림 18) 클래스 마법사 호출한 모습

 

메시지 탭에서 "WM_TIMER"를 검색한다.

"처리기 추가"를 누른다.

"OnTimer"를 클릭 후 "코드 편집(E)"를 클릭한다.

 

 

그림 19) OnTimer()에 소스코드를 입력한 모습의 예(1)

 

 

그림 20) OnTimer()에 소스코드를 입력한 모습의 예(1)

 

void CTimerDigitalView::OnTimer(UINT_PTR nIDEvent)
{
         // TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
         int hour;
         CString str;
         CTime timer;
         timer = CTime::GetTickCount(); // Visual Studio 2017부터 GetCurrentTime() 삭제

 

        if (m_bTimerType) {
             m_strTimer.Format(_T("현재는 %d년 %d월 %d일 %d시 %d분 %d초"),
                   timer.GetYear(), timer.GetMonth(), timer.GetDay(),
                   timer.GetHour(), timer.GetMinute(), timer.GetSecond());


        }

        else {
                  hour = timer.GetHour();

 

                  if (hour >= 12) {
                        str = _T("PM");
   
                       if (hour >= 13) {
                              hour = hour - 12;
                       }

                 }
                 else {
                       str = _T("AM");
                 }

           

                 m_strTimer.Format(_T("지금은 %s %d %d %초"), str, hour,
                 timer.GetMinute(), timer.GetSecond());

       }

     

       Invalidate();

       CView::OnTimer(nIDEvent);
}

 

코드 입력을 마쳤으면, OnDraw를 클릭한다. 코드를 입력해준다.

 

 

그림 21) OnDraw() 함수 원형 내에 코드 입력해주기

 

// CTimerDigitalView 그리기

 

void CTimerDigitalView::OnDraw(CDC* pDC)
{
        CTimerDigitalDoc* pDoc = GetDocument();
        ASSERT_VALID(pDoc);

  

        if (!pDoc)
             return;

 

        // TODO: 여기에 원시 데이터에 대한 그리기 코드를 추가합니다.

 

        CRect rect;
        GetClientRect(&rect);

 

        // 윈도우의 중앙에 타이머를 출력
        pDC->DrawText(m_strTimer, rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER);

}

 

코드 입력을 마쳤다면, Ctrl+Shift+X를 누른다.

 


5. 소멸자 만들기

 

지금 작업은 실시간 타이머를 윈도우 프로그램이 종료할 때, 같이 종료될 수 있도록 지정해주는 기능을 구현하는 것이다.

 

메시지 탭에서 "WM_Destory"를 검색한다.

"처리기 추가(A)"를 클릭한다.

"OnDestory"를 클릭 후 "코드 편집(E)"을 클릭한다.

 

 

그림 22) 창 소멸에 관한 클래스 정의

 

 

 

그림 23) 코드 입력하기

 


6. 시연하기

 

시연하는 것이다.

Ctrl+F5를 눌러서 시연한다.

 

 

그림 25) 시연하기

 

[소스코드]

 

[첨부(Attachment)]

Timer_Digital.7z

 

 


7. 참고자료(Reference)

 

1. CTime::GetCurrentTime intellisense missing - Developer Community, Last Modified , Accessed by 2019-11-30, https://developercommunity.visualstudio.com/content/problem/100004/ctimegetcurrenttime-intellisense-missing.html

 

 

 

2. CTime 클래스 | Microsoft Docs, Last Modified, Accessed by 2019-11-30, https://docs.microsoft.com/ko-kr/cpp/atl-mfc-shared/reference/ctime-class?view=vs-2019#getcurrenttime

 

 

 

 

반응형

+ Recent posts