728x90

xml에서 설정

<?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.mybatis3.dao.mapper.StudentMapper">

         <resultMap id="studentResultMap" type="com.mybatis3.domain.Student">    

         <select id="findStudentByIdMap">

</mapper>

mapper의 namespace = "mapper의 위치"

 

<resultMap>

type: DB로 부터 받은 데이터 result를 바인딩할 java의 클래스 

<resultMap id="studentResultMap" type="com.mybatis3.domain.Student">

<id column="STUD_ID" property="studId"/>

<result column="NAME" property="name"/>

<result column="EMAIL" property="email"/>

<result column="DOB" property="dob"/>

</resultMap>

id = primaryKey

result = 나머지

column="데이터베이스의 컬럼명"

property="자바 클래스의 변수명" 

 

<resultMap id="studentWithAddressResultMap" type="com.mybatis3.domain.Student" autoMapping="true">

autoMapping = id, result를 직접 바인딩하지 않아도 column과 property를 비교하여 알아서 바인딩 해준다. 

다만, 하나의 클래스가 다른 클래스를 포함하고 있거나 컬렉션으로 갖는 경우 

id는 직접 기술해주어야하며, 

포함하고 있는 다른 클래스에 동일한 변수명을 가진 property가 있다면 또한 명시해주어야 한다. 

 

하나의 클래스가 다른 클래스를 포함하고 있는 경우 

<resultMap id="studentWithAddressResultMap" type="com.mybatis3.domain.Student" autoMapping="true">

<id column="STUD_ID" property="studId"/>

<association property="address" javaType="com.mybatis3.domain.Address" autoMapping="true">

<id column="ADDR_ID" property="addrId"/>

</association>

</resultMap>

<association> javaType="포함되는 클래스"

 

하나의 클래스가 다른 컬렉션을 포함하고 있는 경우

<resultMap id="studentWithCoursesResultMap" type="com.mybatis3.domain.Student" autoMapping="true">

<id column="STUD_ID" property="studId"/>

<result column="STUDENT_NAME" property="name"/>

<collection property="courseList" ofType="com.mybatis3.domain.Course" autoMapping="true">

<id column="COURSE_ID" property="courseId"/>

<result column="COURSE_NAME" property="name"/>

</collection>

</resultMap>

 

<collection> ofType="포함되는 컬렉션의 클래스"

동일한 프로퍼티를 가진 경우, <result>로 따로 맵핑해준다.

 

sql문도 작성 가능

<insert id="insertStudentBySequenceReturnPrimaryKey" parameterType="com.mybatis3.domain.Student">

<selectKey keyProperty="studId" order="BEFORE" resultType="int">select students_stud_id_seq.nextval from dual</selectKey>

insert into students(stud_id,name,email,dob) values(#{studId},#{name},#{email},#{dob})

</insert>

parameterType="insert시 필요한 파라메터의 타입"

<selectKey> insert시 sequence를 사용하여 pk를 초기화한다면 

insert후 insert한 데이터의 pk를 바로 반환 받기 위해 사용 

select students_stud_id_seq.nextval from dual

seq.nextval로 다음 seq 값을 미리 알아낸 후 

insert 할때는 seq.currval 값으로 insert 한다. 

파라메터를 넣을 땐 #{...property...} 표현식을 사용한다.

 

mybatis 사용

* 0. mybatis-config.xml --> InputStream

InputStream myBatisConfigInputStream = Resources.getResourceAsStream("mybatis-config.xml");

* 1. SqlSessionFactoryBuilder

SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();

* 2. SqlSessionFactory

SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(myBatisConfigInputStream);

* 3. SqlSession open (Connection) autocommit true

SqlSession sqlSession=sqlSessionFactory.openSession(true);

* 4. SqlSession사용(CRUD)

//List<Student> studentList=sqlSession.selectList("com.mybatis3.dao.mapper.StudentBasicMapper.findAllStudents");

Student student=sqlSession.selectOne(

"com.mybatis3.dao.mapper.StudentBasicMapper.findStudentById",1);

* 5. SqlSession close

sqlSession.close();

sqlSessionFactory.open(autocommit true?)

 

sqlSession 메소드

selectOne()  객체 한개 반환 받을 때 

selectList() 객체 컬렉션을 반환 받을 때

insert(), update(), delete()

 

sqlSession.method(namespace+sql태그 id, 파라메터)

 

 

 

 

 

interface 에서 설정

-인터페이스의 풀네임은 Mapper.xml의 namespace와 일치

-메소드 이름은 Mapper.xml의 id와 일치

-메소드 인자타입은 Mapper.xml의 parameterType과 일치

-메소드 리턴타입은 Mapper.xml의 resultType과 일치 

 

@Select("select stud_id as studid,name,email,dob from students where stud_id = #{studId}")

public Student findStudentById(@Param("studId")Integer studId);

어노테이션으로 sql문을 .xml 파일 대신 Mapper인터페이스에서 작성할 수 있다. 

 

 

Mapper interface 사용

* 0.mybatis-config-mapper-interface.xml --> InputStream

InputStream myBatisConfigInputStream = Resources.getResourceAsStream("mybatis-config-mapper-interface.xml");

* 1. SqlSessionFactoryBuilder

SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder();

* 2. SqlSessionFactory

SqlSessionFactory sqlSessionFactory=

sqlSessionFactoryBuilder.build(myBatisConfigInputStream);

* 3. SqlSession open (Connection ) autocommit true

SqlSession sqlSession=sqlSessionFactory.openSession(true);

* 4. StudentMapper[MapperInterface]생성

* org.apache.ibatis.binding.MapperProxy

StudentBasicMapper studentBasicMapper

=sqlSession.getMapper(StudentBasicMapper.class);

* 4. StudentMapper[MapperInterface]사용(CRUD)

Student student = studentBasicMapper.findStudentByNo(1);

* 5. SqlSession close

sqlSession.close();

sqlSession을 얻는것까진 동일 

 

인터페이스는 직접 사용하지 못하고 인터페이스를 상속받아 구현한 클래스를 사용해야 한다. 

Mapper는 인터페이스이므로 Mapper를 구현한 클래스를 가져와야하는데 

sqlSession의 getMapper가 이러한 일을 대신해준다. 

이를 Proxy라고 한다. 

Mapper mapper = sqlSession.getMapper(Mapper.class);

mapper.메소드를 이용해 인터페이스에서 만든 메소드를 사용할 수 있다. 

 

 

Dao에서 Mapper 사용하기 예제

public class AddressDao {

private SqlSessionFactory sqlSessionFactory;

private static final String NAMESPACE ="com.mybatis3.dao.mapper.AddressMapper.";

public AddressDao() {

try {

InputStream myBatisConfigInputStream = Resources.getResourceAsStream("mybatis-config.xml");

SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

this.sqlSessionFactory = sqlSessionFactoryBuilder.build(myBatisConfigInputStream);

} catch (Exception e) {

e.printStackTrace();

}

}

sqlSession이 아닌 factory를 필드로 갖고 매번 factory에서 sqlSession을 가져다 쓰고 반납한다. 

Dao 생성자에서 sqlSessionFactory를 생성해준다.

 

public Address findAddressByIdWithStudents(Integer addrId) {

SqlSession sqlSession= sqlSessionFactory.openSession(true);

Address address=sqlSession.selectOne(NAMESPACE+"findAddressByIdWithStudents",addrId);

sqlSession.close();

return address;

}

'Web' 카테고리의 다른 글

YAML Converter  (0) 2023.10.11
SPA(single page application) Handlebars 활용하기  (1) 2023.09.21
HTML5 Basic  (0) 2023.09.19
MyBatis Config  (0) 2023.09.19
AJAX Asynchronous Javascript And XML  (0) 2023.09.18
728x90

mybatis-config.xml 

<?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>태그 안에 setting할 속성 태그 입력

 

<properties resource="jdbc.properties" />

rss를 읽을 프로퍼티 파일 

jdbc에서 사용할 DataBase 설정값을 가진 properties 파일 

<settings> mapping, sql문 관련, 주요 기능에 관한 설정

<settings>

<!-- 카멜 케이스 VO 매핑 -->

<setting name="mapUnderscoreToCamelCase" value="true" />

<!-- 쿼리 결과 필드가 null인 경우, 누락이 되서 나오지 않게 설정 -->

<setting name="callSettersOnNulls" value="true" />

<!-- 쿼리에 보내는 파라미터가 null인 경우, 오류가 발생하는 것 방지 -->

<setting name="jdbcTypeForNull" value="NULL" />

</settings>

mapUnderscoreToCamelCase

자바의 domain에서는 카멜케이스를,

대소문자를 구분하지 않는 데이터베이스에서는 스네이크 케이스를 사용하면서 

바인딩할 때 스네이크 케이스를 카멜케이스로 변환하여 인식하고 바인딩 해줄지를 설정 

 

<typeAliases> 

<typeAliases>

<typeAlias alias="Student" type="com.mybatis3.domain.Student" />

</typeAliases>

도메인 타입을 기술할 때 패키지부터 풀네임을 기술해야한다.

alias를 설정하여 간단히 할 수 있다. 

 

<environments> 데이터베이스(<dataSource>), 트랜젝션(<transactionManager>) 설정

<environment>태그를 여러번 사용하여 다양한 설정 가능 

<environments default="development">

<environment id="development">

<transactionManager type="JDBC" />

<dataSource type="POOLED">

<property name="driver" value="${jdbc.driverClassName}" />

<property name="url" value="${jdbc.url}" />

<property name="username" value="${jdbc.username}" />

<property name="password" value="${jdbc.password}" />

</dataSource>

<!-- <dataSource type="POOLED">

<property name="driver" value="" />

<property name="url" value="" />

<property name="username" value="" />

<property name="password" value="" />

</dataSource>-->

</environment>

</environments>

<property>에 데이터베이스 설정 값 입력 

jdbc.properties 파일의 key값으로 value 값을 가져온다.

 

'Web' 카테고리의 다른 글

YAML Converter  (0) 2023.10.11
SPA(single page application) Handlebars 활용하기  (1) 2023.09.21
HTML5 Basic  (0) 2023.09.19
Mybatis Mapper  (0) 2023.09.19
AJAX Asynchronous Javascript And XML  (0) 2023.09.18
728x90

AJAX : 브라우저에서 제공하는 Web API인 XMLHttpRequest 객체를 기반으로한 비동기 방식 데이터 통신 
필요한 데이터만 전송받아 갱신이 필요한 부분만 갱신한다. 이러한 과정이 비동기 방식으로 진행되기 때문에 
서버에 요청을 보내고 받는 동안 Blocking 현상이 발생하지 않아 클라이언트는 자유롭게 페이지를 이용할 수 있다.
 

 


XMLHttpRequest 객체 
ㅁproperties
 - readyStatus  : http 요청의 상태를 정수로 반환 
       unsent : 0
       opened : 1
       headers_received : 2
       loading : 3
       done : 4
 - status : 요청에 대한 응답 상태를 정수로 ex) 200 
 - statusText : 요청에 대한 응답 상태를 문자열로 ex)"OK"
 - responseType : 응답 타입 ex) document, json
 - response : 응답의 바디
 - onreadystatechange 
 - onerror
 - onload
 - open() :  요청 초기화
 - send() : 요청 전송
 - abort() : 이미 전송한 요청 중단
 
 
ㅁ요청 보내기 
1. 생성 
const xhr = new XMLHttpRequest();

const  xhr=new XMLHttpRequest();

2. 요청속성설정 open( requestMethod, 서버측 Controller URL[, async 비동기 요청 여부 default true] );

method=(method)? method:'GET';

method=(method!='GET' &&method!='POST')?'GET':method;

params=(params)?params:null;

url=(method=='GET'&&params!=null)?url+'?'+params:url;

 


++requestMethod
 - get(모든, 특정 데이터 read) 페이로드 없음
 - post(데이터 create) 페이로드 있음
 - put(데이터 전체 update) 페이로드 있음
 - delete(데이터 delete) 페이로드 없음 

xhr.open('GET','user_view?id='+idStr);

++(open() 이후 필요시 HTTP 요청 헤더 설정 ex) post)  
text : text/plain; text/html; text/css; text/javascript
application : application/json; application/x-www-form-urlencode
multiple : multiple/formed-data 

//필요한 경우 HTTP 요청 헤더 설정

// 클라이언트가 서버로 전송할 데이터의 MIME 타입 지정 : json

xhr.setRequestHeader('content-type', 'application/json');

3. 응답이 도착했을 때 실행되는 콜백함수등록(이벤트프로퍼티에 함수 등록)

xhr.onload=function (){

if(xhr.readyState==4){

/*데이터 응답이 완전히 이루어졌을때*/

let jsonText=xhr.responseText;

let jsonObject= JSON.parse(jsonStr);

 

let spanE=document.getElementById('msg');

spanE.innerHTML=msgjsonObject.msg;

if(jsonObject.status==1){

spanE.style.color='green';

}else{

spanE.style.color='red';

}

}else{

/*응답이 오는 중*/

document.getElementById('msg').innerHTML='<img src="loading.gif" width="15px" height="15px" />';

}

console.log('응답');

}

;

4. 요청 전송

xhr.send();

send(요청바디)

send("param=value&param2=value2"...)

xhr.send((method=='POST')?params:null);

 

 

 

 

 

JSON

 

클라이언트와 서버간 통신에 사용되는 데이터 포맷

{

       "key" : value,

       "key" : "strValue"

       "arrayKey" : [

                                 value,

                                 value,

                                 "strValue"

                            ],

        "objectKey" : {

                                 "key" : value,

                                 "key" : value

                              }                           

}

 

JSON.stringify(obj);

obj를 json 타입의 문자열로 반환한다. 

 

JSON.parse(obj);

obj를 json 타입의 문자열을 객체 타입으로 반환한다.

 

 

 

응답받은 데이터 사용하기 예

{

"status": 1,

"msg": "성공",

"data": [{

"title": "타이틀1",

"company": "회사1",

"date": "2023-11-15"

},{

"title": "타이틀2",

"company": "회사2",

"date": "2023-11-16"

}]

}

JSON 

let responseJsonStr = xhr.responseText; //응답받은 JSON 포맷의 String 텍스트 데이터

let responseJsonObject = JSON.parse(responseJsonStr); /* JSON 문자열 -- JSON Object로 파싱*/

let newsJsonArray = responseJsonObject.data; //Array 데이터 

let htmlTemplate=`<ul>`;

for(let i=0; i<newsJsonArray.length;i++){

let title = newsJsonArray[i].title;

let company = newsJsonArray[i].company;

let date = newsJsonArray[i].date;

htmlTemplate+=`<li>${title}[${company}-${date}]</li>`;

}

htmlTemplate+=`</ul>`;

 

@RestController

RestController 맵핑 예시

@Operation(summary = "newsList", description = "news전체를 조회")

@GetMapping(value="/map/news", produces = "application/json;charset=UTF-8")

public Map<String, Object> newsTitlesMapJson() {

int status=1;

String msg = "";

Object data=new ArrayList<>();

 

data=getNewsList();

 

Map<String,Object> resultMap = new HashMap<String,Object>();

resultMap.put("status", status);

resultMap.put("msg", msg);

resultMap.put("data", data);

 

return resultMap;

}

Controller에 @RestController 어노테이션이 없다면 

method에 @ResponseBody 어노테이션을 붙여준다. 

 

@Operation() 어노테이션은 swagger의 어노테이션으로 swagger에서 확인할 수 있는 mapping 의 설명을 붙여줄 수 있다. 

 

컨트롤러에 일정한 형식을 부여하기 위해 

int status=1;

String msg = "";

Object data=new ArrayList<>();

 

data=getNewsList();

 

Map<String,Object> resultMap = new HashMap<String,Object>();

resultMap.put("status", status);

resultMap.put("msg", msg);

resultMap.put("data", data);

 

return resultMap;

 

형식을 유지해준다. 

data에는 리스트 형식으로 하고 리스트의 사이즈가 0 혹은 1 이어도 상관없다. 

 

프론트에서 데이터를 받을 때는 

xhr.responseText

{

"status":1,

"msg":"",

"data":[

        ]

}

로 받는다. 

let responseJsonObject = JSON.parse(xhr.responseText);

responseJsonObject.status==1

 

@GetMapping(value="/map/news/{no}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)

public Map<String, Object> newsTitleMapJson(@PathVariable(name="no")int no) {

RestAPI 를 적용한 Mapping 

인자를 쿼리스트링이 아닌 path 변수로 받는다. 

'Web' 카테고리의 다른 글

YAML Converter  (0) 2023.10.11
SPA(single page application) Handlebars 활용하기  (1) 2023.09.21
HTML5 Basic  (0) 2023.09.19
Mybatis Mapper  (0) 2023.09.19
MyBatis Config  (0) 2023.09.19

+ Recent posts