[java] output param

java는 call by value 이므로 인자를 통한 output을 언어 차원에서 지원하지 않는다.

output parameter를 지원하는 방법이 있다.

다음과 같은 방법으로 output parameter를 쓸 수 있다.


public void divide(int x, int y, int [] quotient) {
  quotient[0] = x / y;
  return;
}

모든 타입에 적용가능하며 사용하기 전에 배열 메모리 할당을 해 줘야 한다.

int outparm[] = new int[1];
quotient(25, 6, outparm);

[iBatis] iBatis 쉬운 예제

iBatis 쉬운 예제

iBATIS공식홈페이지입니다.( 개발자 가이드와 튜토리얼 메뉴얼도 있습니다.)
for Java를 클릭하면 자바용이 나옵니다.
http://ibatis.apache.org/

1. 원더걸스멤버 입력

CREATE TABLE `WONDERGIRLS`
(   `NUM` int(11) NOT NULL,   `NAME` varchar(10) NOT NULL,   `AGE` int(11) NOT NULL )
ENGINE=MyISAM DEFAULT CHARSET=euckr;

INSERT INTO `WONDERGIRLS` (`NUM`, `NAME`, `AGE`) VALUES
(1, '선예', 18), (2, '선미', 15), (3, '소희', 15), (4, '예은', 18), (5, '유빈', 99);

이클립스를 실행하고 JAVA PROJECT로 프로젝트를 하나 만듭시다. 그리고 패키지를 jyp라고 해서 만듭시다; iBATIS lib파일인 ibatis-2.3.0.677.jar과 OracleJDBC를 LIB으로 추가합시다. iBATIS를 사용하기 위한 설정파일을 구성해봅시다. jyp에다가 new해서 xml파일을 하나 만듭시다. 이름은 SqlMapConfig.xml 이라고 합시다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

<properties resource="./jyp/SqlMapConfig.properties" />

<settings
cacheModelsEnabled="true"
enhancementEnabled="true"
lazyLoadingEnabled="true"
maxRequests="32"
maxSessions="10"
maxTransactions="5"
useStatementNamespaces="false"
/>

<transactionManager type="JDBC" >
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}" />
<property name="JDBC.ConnectionURL" value="${url}" />
<property name="JDBC.Username" value="${username}" />
<property name="JDBC.Password" value="${password}" />
</dataSource>
</transactionManager>

<sqlMap resource="./jyp/WonderGirls.xml" />

</sqlMapConfig>

2. DB properties

2.1SqlMapConfig.properties(oracle)

driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:XE
username=MUDCHOBO
password=1234

2.2. SqlMapConfig.properties(MySQL)

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/testdbname
username=root
password=1234

3. MyAppSqlmapConfig 클래스

 package jyp;

import java.io.Reader;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;

public class MyAppSqlMapConfig {

private static final SqlMapClient sqlMap;

static {
try {
String resource = "./jyp/SqlMapConfig.xml";
Reader reader = Resources.getResourceAsReader(resource);
sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Error initializing class. Cause:" + e);
}
}

public static SqlMapClient getSqlMapInstance() {
return sqlMap;
}
}

4. WonderGirls 클래스

package jyp;

public class WonderGirls {

private int num;
private String name;
private int age;

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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

5. WonderGirls.xml
이제 가장 중요한 부분인 Wondergirls에 관련된 sqlMap을 작성해봅시다.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="WonderGirls">

<resultMap id="WondergirlsResult">
<result column="NUM" property="num" />
<result column="NAME" property="name" />
<result column="AGE" property="age" />
</resultMap>

<select id="getWondergirls" resultMap="WondergirlsResult">
SELECT NUM, NAME, AGE
FROM WONDERGIRLS
ORDER BY NUM
</select>

<select id="selectWondergirl" parameterClass="Integer"
resultClass="jyp.WonderGirls">
SELECT NUM, NAME, AGE
FROM WONDERGIRLS
WHERE NUM = #num#
</select>

<insert id="insertWondergirl" parameterClass="jyp.WonderGirls">
INSERT INTO
WONDERGIRLS (NUM, NAME, AGE)
VALUES (#num#, #name#, #age#)
</insert>

<update id="updateWondergirl" parameterClass="java.util.Map">
UPDATE WONDERGIRLS SET
NAME = #name#,
AGE = #age#
WHERE NUM = #num#
</update>

<delete id="deleteWondergirl" parameterClass="Integer">
DELETE FROM WONDERGIRLS
WHERE NUM = #num#
</delete>

</sqlMap>

sql문을 xml로 뺐습니다. 나중에 고칠 때 편할 듯 싶네요.  sql이 총 5가지가 있네요.  전체리스트가져오기, 멤버번호받아서 한명멤버정보 가져오기, 멤버추가하기, 멤버수정하기, 멤버삭제하기 select 해서 List를 가져올 때에는 원래 자동맵핑이 되서 알아서 가져오지만 그래도 명시적으로 맵핑을 해줘야돼요. 그래서 resultMap태그를 이용해서 명시해준뒤에 select를 선언해서 그 resultMap의 id를 resultMap속성값에 넣어주면 됩니다. insert할 때에도 WonderGirls클래스형으로 받아서 넣어주면 되구요. update할 때 좀 틀린게 parameterClass를 Map으로 선언합니다. 이름, 나이, 번호를 각각 객체로 받아서 Map에 저장한 것을 받아서 사용하는 것이죠. delete할 때에는 Integer클래스형으로 숫자하나 받아서 해당 멤버를 지우게 됩니다. 이번엔 DAO를 만들어봅시다. WonderGirlsDao 라는 이름의 클래스를 만들어봅시다.

6. WonderGirlsDao

package jyp;

import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import com.ibatis.sqlmap.client.SqlMapClient;

public class WonderGirlsDao {

@SuppressWarnings("unchecked")
public void viewMember(SqlMapClient sqlMap) throws SQLException {
List<WonderGirls> wonderGirlsList = (List<WonderGirls>) sqlMap
.queryForList("getWondergirls");
for (int i = 0; i < wonderGirlsList.size(); i++) {
WonderGirls wonderGirl = (WonderGirls) wonderGirlsList.get(i);
System.out.print("번호 : " + wonderGirl.getNum());
System.out.print("   이름 : " + wonderGirl.getName());
System.out.println("   나이 : " + wonderGirl.getAge());
}
}

public void insertMember(SqlMapClient sqlMap, WonderGirls wonderGirls)
throws SQLException {
sqlMap.insert("insertWondergirl", wonderGirls);
System.out.println("추가에 성공했습니다.");
}

public void modifyMember(SqlMapClient sqlMap, Map<String, Object> map)
throws SQLException {
sqlMap.update("updateWondergirl", map);
System.out.println("수정에 성공했습니다.");
}

public void deleteMember(SqlMapClient sqlMap, int num) throws IOException,
SQLException {
sqlMap.delete("deleteWondergirl", num);
System.out.println("삭제에 성공했습니다.");
}

public boolean validateMember(SqlMapClient sqlMap, int num) throws SQLException {
WonderGirls wonderGirls =
(WonderGirls) sqlMap.queryForObject("selectWondergirl", num);

if (wonderGirls == null) {
return false;
}
return true;
}
}

DAO를 보면 이상하게 간단합니다. 위에 xml에 다 쿼리를 선언해줬기때문에 그냥 파라메터만 넘겨주면 됩니다.  List보기는 sqlMap.queryForList(“getWondergirls”); getWondergirls는 위에 선언한 쿼리의 id입니다. insert할 때에는 객체를 받아서 넘겨주고, 수정할 때에는 Map을 넘겨주고, 삭제 할때에는 숫자를 넘겨주면 됩니다. 아 간단해요. 한줄이면 끝나요-_-;  예전에 Connection을 close()안해줬더니 서버가 다운되려고 한 경험이 있는데 이런일은 절대 없을 것 같군요. 이제 main함수를 작성해봅시다. 이름은 WonderGirlsApplication으로 해봅시다. public static void main(String[] args)에 체크해주시는 것 잊지 마시구요-_-;

7. WonderGirlsApplication.java

———————WonderGirlsApplication.java———————————–

package jyp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import com.ibatis.sqlmap.client.SqlMapClient;

public class WondergirlsApplication {

public static void main(String[] args) throws SQLException, IOException {

BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(System.in));
SqlMapClient sqlMap = MyAppSqlMapConfig.getSqlMapInstance();
WondergirlsDao wondergirlsDao = new WondergirlsDao();
WonderGirls wonderGirls = new WonderGirls();

Integer age, num;
String name;

while (true) {
try {
System.out.println("\n1.멤버출력\n2.멤버추가\n3.멤버수정\n4.멤버삭제\n5.종료");
System.out.print("--> ");
String temp = bufferedReader.readLine();
int MenuNum = Integer.parseInt(temp);
switch (MenuNum) {
case 1:
wondergirlsDao.viewMember(sqlMap);
break;

case 2:
wonderGirls = new WonderGirls();
System.out.print("번호을 입력하세요 : ");
wonderGirls.setNum(Integer.parseInt(bufferedReader.readLine()));
System.out.print("이름을 입력하세요 : ");
wonderGirls.setName(bufferedReader.readLine());
System.out.print("나이을 입력하세요 : ");
wonderGirls.setAge(Integer.parseInt(bufferedReader.readLine()));
wondergirlsDao.insertMember(sqlMap, wonderGirls);
break;

case 3:
Map<String, Object> map = new HashMap<String, Object>(3);

System.out.print("수정할 번호을 입력하세요 : ");
num = new Integer(Integer.parseInt(bufferedReader.readLine()));
if (!wondergirlsDao.validateMember(sqlMap, num)) {
System.out.println("없는 멤버번호입니다.");
break;
}
System.out.print("이름을 입력하세요 : ");
name = bufferedReader.readLine();
System.out.print("나이을 입력하세요 : ");
age = new Integer(Integer.parseInt(bufferedReader.readLine()));

map.put("num", num);
map.put("name", name);
map.put("age", age);
wondergirlsDao.modifyMember(sqlMap, map);
break;

case 4:
System.out.print("삭제할 멤버번호를 입력하세요 : ");
num = Integer.parseInt(bufferedReader.readLine());
if (!wondergirlsDao.validateMember(sqlMap, num)) {
System.out.println("없는 멤버번호입니다.");
break;
}
wondergirlsDao.deleteMember(sqlMap, num);
break;

case 5:
System.exit(0);

default:
System.out.println("1~5중에서 선택하세요!");
break;
}
} catch (NumberFormatException e) {
System.out.println("잘못 입력했습니다. 다시 입력하세요");
}
}
}
}

8. TEST

1번은 멤버 리스트를 가져오는군요.
1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –> 1 번호 : 1   이름 : 선예   나이 : 18 번호 : 2   이름 : 선미   나이 : 15 번호 : 3   이름 : 소희   나이 : 15 번호 : 4   이름 : 예은   나이 : 18 번호 : 5   이름 : 유빈   나이 : 5 1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –>

2번은 멤버를 추가하는데 추가해봅시다-_-;
1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –> 2 번호을 입력하세요 : 6 이름을 입력하세요 : 성종천 나이을 입력하세요 : 25 추가에 성공했습니다. 1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –> 1 번호 : 1   이름 : 선예   나이 : 18 번호 : 2   이름 : 선미   나이 : 15 번호 : 3   이름 : 소희   나이 : 15 번호 : 4   이름 : 예은   나이 : 18 번호 : 5   이름 : 유빈   나이 : 5 번호 : 6   이름 : 성종천   나이 : 25 1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –>
아 멤버가 추가되었어요 멤버를 수정해봅시다. 유빈양의 나이가 잘못 되었으니 수정해봅시다.
1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –> 3 수정할 번호을 입력하세요 : 5 이름을 입력하세요 : 유빈 나이을 입력하세요 : 20 수정에 성공했습니다. 1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –> 1 번호 : 1   이름 : 선예   나이 : 18 번호 : 2   이름 : 선미   나이 : 15 번호 : 3   이름 : 소희   나이 : 15 번호 : 4   이름 : 예은   나이 : 18 번호 : 5   이름 : 유빈   나이 : 20 번호 : 6   이름 : 성종천   나이 : 25 1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –>

아…. 유빈양이 제일 마지막에 들어왔는데 나이가 제일 많군요-_-; 그리고 이제 말도 안되는 성종천이라는 멤버를 지워봅시다-_-;
1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –> 4 삭제할 멤버번호를 입력하세요 : 6 삭제에 성공했습니다. 1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –> 1 번호 : 1   이름 : 선예   나이 : 18 번호 : 2   이름 : 선미   나이 : 15 번호 : 3   이름 : 소희   나이 : 15 번호 : 4   이름 : 예은   나이 : 18 번호 : 5   이름 : 유빈   나이 : 20 1.멤버출력 2.멤버추가 3.멤버수정 4.멤버삭제 5.종료 –>

출처: http://mudchobo.tomeii.com/tt/132