반응형

checkbox 여러개의 값을 넘겨서 쿼리에 그 값들을 이용하려고 함.

1. HTML 

form submit시에 check된 value들만 전달됨.

<form name="f" method="get" action="/checkMenu">
<input type="checkbox" name="menu" value="hamburger">
<input type="checkbox" name="menu" value="pizza">
<input type="checkbox" name="menu" value="spagetti">
<input type="checkbox" name="menu" value="french fries">

<button type="submit">

 

2. VO

checkbox의 값들을 담을 변수는 배열로 만들어준다.

public class menuVO {
	private String[] menus;
}

 

3. Controller

request.getParameterValues로 받았다.

@RequestMapping
public ModelAndView checkMenu(HttpServletRequest request, HttpServletResponse response) throws Exception {
	String[] menus = request.getParameterValues("menus");
}

 

4. 쿼리파일 (xml)

iterate를 사용했다.

property = 변수명

<select id="getMenuInfo" parameterClass="menuVO" resultClass="orderVO">
	SELECT MENU_CODE, MENU_PRICE FROM MY_MENU_TABLE
	WHERE MENU_NAME IN
	<iterate property ="menus" open="(" close=")" conjunction=",">
	#menus[]#
	</iterate>
</select>
반응형
반응형

Spring boot 환경에서 postgreSql DB를 연동하여 정보를 가져오려고 한다.

 

MyBatis 사용을 위한 설정 

- MyBatis 설정 <configuration></configuration >  : mybatis-config.xml 에서 설정함.

- SqlSessionFactory : DatabaseConfig.java 에서 설정함

- SQL 맵핑 <mapper></mapper> : dataMapper.xml에 쿼리문을 작성함 


1. 라이브러리

build.gradle에 의존성 추가

implementation "org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.1"
implementation "org.mybatis:mybatis-spring:1.3.1"
implementation "org.mybatis:mybatis:3.4.5"

implementation "org.postgresql:postgresql:9.4.1209.jre6"

 

2. mybatis 설정 파일 추가

resources > mybatis 밑에 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>
    <settings>
        <setting name="jdbcTypeForNull" value="NULL" />
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>
</configuration>

jdbcTypeForNull : JDBC타입을 파라미터에 제공하지 않을때 null값을 처리한 JDBC타입을 명시한다. 일부 드라이버는 칼럼의 JDBC타입을 정의하도록 요구하지만 대부분은 NULL, VARCHAR 나 OTHER 처럼 일반적인 값을 사용해서 동작한다.

mapUnderscoreToCamelCase : 전통적인 데이터베이스 칼럼명 형태인 A_COLUMN을 CamelCase형태의 자바 프로퍼티명 형태인 aColumn으로 자동으로 매핑하도록 함

 

3.  jdbc datasource 설정

resources 밑에 application.yml 생성

내용

spring:
  profiles:
    active: local

---
# local development server
spring:
  profiles: local
  datasource:
    jdbc-url: jdbc:postgresql://localhost:5432/dbName
    driver-class-name: org.postgresql.Driver
    username: test
    password: test@!

 

4. DB 접속 및 sqlSession 설정

패키지 밑에 DataBaseConfig 생성

내용

package com.export.config;


import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

@Configuration
//////매퍼 xml 파일이 바라볼 패키지 설정
@MapperScan(value="com.export.mapper.*", sqlSessionFactoryRef = "sqlSessionFactory")
public class DataBaseConfig {

	/////application.yml에 설정한 정보를 가져와 dataSource 빈 생성
    @Primary
    @Bean(name = "dataSource")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return DataSourceBuilder.create().build();
    }


    @Primary
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactoryBean(
            @Autowired @Qualifier("dataSource") DataSource dataSource,
            ApplicationContext applicationContext) throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource);
        factoryBean
                .setConfigLocation(applicationContext.getResource("classpath:mybatis/mybatis-config.xml"));
        factoryBean
                .setMapperLocations(applicationContext.getResources("classpath:mybatis/mapper/*.xml"));
        return factoryBean.getObject();
    }

    @Primary
    @Bean(name = "sqlSession")
    public SqlSessionTemplate sqlSession(
            @Autowired @Qualifier("sqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }

    @Primary
    @Bean(name = "transactionManager")
    public DataSourceTransactionManager transactionManager(
            @Autowired @Qualifier("dataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }


}

 

설정은 끝


매퍼 xml 파일 예시

resources > mybatis > mapper 밑에 매퍼 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.export.mapper.DataMapper">
    <select id="select11" parameterType="DataDto" resultType="Integer">
        SELECT COUNT(*)
        FROM ${tableName}
        WHERE ${dataTimeColumn} BETWEEN TO_TIMESTAMP(#{startTime},'YYYY-MM-DD') AND TO_TIMESTAMP(#{endTime},'YYYY-MM-DD')
</select>


</mapper>
반응형
반응형

Mapped Statements collection already contains value for...

머 대충 이런 에러가 났는데

쿼리 id가 중복되어서 그랬던거 같음

같은 id 를 가진 쿼리문 하나 지우니까 됨.

아래 내용은 아래 링크에서 가져온 것.

* 원인 

 1. mapper id 가 틀린 경우.

 2. Parameter와 bean의 field 명이 틀린 경우

 3. sql.xml 에서 정의된 namespace와 DAO에서 호출하는 namespace가 다를 경우

 4. mapper가 정의가 되어 있지 않거나 Spelling 이 틀린 경우

 5. mapper에 정의 된 namespace 명칭이 같은 Application 내에 중복 될 경우

아래 링크를 참고하였음

 

starlmh.tistory.com/entry/Mybatis-%EC%97%90%EB%9F%AC

 

Mybatis 에러

* 에러 문구 : Mapped Statements collection already contains value for ~ * 원인  1. mapper id 가 틀린 경우.  2. Parameter와 bean의 field 명이 틀린 경우  3. sql.xml 에서 정의된 namespace와 DAO에서..

starlmh.tistory.com

 

반응형
반응형

DB 컬럼명 <-> VO 변수명 DB 컬럼명이 AB_CD,VO 변수명이 abCd인 경우언더바와 camel case 자동매핑하기위해

mybatis-config.xml에 다음 내용 추가

<settings>

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

</settings>

 

반응형
반응형

 

<select id="selectByCareerYear" resultType="HashMap">
	select user_career_year || '년'
			,count(user_career_year) || '명'
				from(select 
					 trunc(months_between(sysdate,user_comp_enter)/12) user_career_year 
					 from user_info) 
				where not user_career_year is NULL 
				group by user_career_year 
				order by user_career_year desc
</select>

셀렉트 결과를... Developer에서 봤을때 처럼..

원하는 모양 : Hashmap으로 key="9년" , value="1명"

{COUNT(USER_CAREER_YEAR)||'명'=1명, USER_CAREER_YEAR||'년'=9년}

 

keySet() 으로 확인해보니 key는  [COUNT(USER_CAREER_YEAR)||'명', USER_CAREER_YEAR||'년'] 이고

values() 로 확인해보니 values는 [1명,9년] 

이렇게 뜨는데... 

그럼 쿼리문에서 이름을 바꾸자..

as로 alias를 명명했다

<select id="selectByCareerYear" resultType="HashMap">
	select user_career_year || '년' as year
			,count(user_career_year) || '명' as count
				from(select 
					trunc(months_between(sysdate,user_comp_enter)/12) user_career_year 
					from user_info) 
				where not user_career_year is NULL 
				group by user_career_year 
				order by user_career_year desc
</select>

keySet이 year과 count가 되었다. 

반응형
반응형

boardType 변수는 String[] 타입

String[] 타입을 map에 넣었다.

String[] boardType; //checkbox 선택지 가져올 배열 생성
boardType=request.getParameterValues("boardType"); //checkbox 선택지 가져오기
map.put("boardType", boardType);

 

이 map을 파라미터로 받아서 select 쿼리를 하려고 함 

   <select id="boardTypeList"  parameterType="hashmap" resultMap="boardVo">
   		select 
   			board_type
   			,board_num
   			,board_title
   			,board_comment
   			,total_cnt 
   		from (select 
				board_num
				,board_type
				,board_title
				,board_comment
				,row_number() over(order by board_num desc) as numrow
				,count(*) over() as total_cnt
			from board
			<if test="boardType!=null">
				where 
				<foreach collection="boardType" item="arr" separator="or">
					board_type= #{arr}
				</foreach>	
			</if>
				
			)
		where NUMROW BETWEEN (#{pageVo.pageNo}-1)*10 + 1 AND (#{pageVo.pageNo})*10

    </select>


<foreach collection = "boardType" item="arr" separator="or">

collection : 전달받은 인자. List or Array 형태만 가능
item : 전달받은 인자 값을 alias 명으로 대체
open : 구문이 시작될때 삽입할 문자열
close : 구문이 종료될때 삽입할 문자열
separator : 반복 되는 사이에 출력할 문자열
index : 반복되는 구문 번호이다. 0부터 순차적으로 증가

 

 

아래 블로그의 글을 참고하였음!

java119.tistory.com/85

 

[MyBatis] 동적 쿼리 foreach문 문법 총 정리

시작하기에 앞서 참고 자료 *ibatis iterate문 지원 태그 property : 파라미터명 prepend : 쿼리로 쓰일 문자 open : 구문이 시작될때 삽입할 문자열 close : 구문이 종료될때 삽입할 문자열 conjunction :..

java119.tistory.com

 

반응형
반응형

VO 객체 두 개를 한 쿼리로 어떻게 넘겨주나 찾다가 map을 이용하면 된다는 걸 알았음

컨트롤러에서 Hashmap 생성 및 put으로 Vo객체 put

 

Mybatis

map으로 썼던 경우도 있었는데 hashmap으로 쓰니 되더라. 무슨차이인지는 모르겠다.

parameterType="hashmap"

Vo 파라미터에 대한 접근은 #{Vo이름.파라미터이름}

반응형

+ Recent posts