-
학원 day37~38. ibatis(2), XML기록 2022. 10. 30. 13:49
ibatis
- SQL Mapper framework
- SQL과 객체를 매핑시켜서 데이터베이스 엑세스 작업 수행하는 라이브러리다.
환경설정
- 라이브러리 (classPath에 등록)
- JDBC 드라이버 파일
ojdbc11.jar
- ibatis 라이브러리 파일
sqlmap-2.3.4.726.jar
- 환경설정 파일
resources/META-INF/ibatis/ibatis-config.xml
- 데이터베이스 연결 정보 설정
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="oracle.jdbc.OracleDriver" /> // jdbc종류
<property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@localhost:1521:xe" /> // 연결할 데이터베이스
<property name="JDBC.Username" value="hr" /> // 계정
<property name="JDBC.Password" value="zxcv1234" /> // 비밀번호
</dataSource>
</transactionManager>
- 매퍼파일(sql이 정의되어 있는 파일) 정보 등록 (테이블당 하나씩 생성)
<sqlMap resource="META-INF/ibatis/mappers/users.xml" />
<sqlMap resource="META-INF/ibatis/mappers/products.xml" />
<sqlMap resource="META-INF/ibatis/mappers/carts.xml" />
<sqlMap resource="META-INF/ibatis/mappers/reviews.xml" />
- 데이터베이스 엑세스 작업 준비
1. 테이블을 표현하는 VO 클래스 작성
public class User {
private String id;
private String password;
private String name;
private String email;
private String tel;
private String gender;
private String enabled;
private int point;
private Date createdDate;
private Date updatedDate;
}
2. 데이터베이스 엑세스 작업을 수행하는 DAO 클래스 작성
public class UserDao {
}
3. SQL과 객체를 매핑하는 매퍼파일을 작성
resources/META-INF/ibatis/mappers/users.xml 파일 추가
<sqlmap>
</sqlmap>
4. ibatis 환경 설정파일에 매퍼파일을 등록한다.
resources/META-INF/ibatis/ibatis-config.xml에 users.xml 파일 등록하기
<sqlMap resource="META-INF/ibatis/mappers/users.xml" />
- 데이터베이스 엑세스 작업 구현
1. 실행할 데이터베이스 엑세스 작업을 정의한다.
사용자아이디로 사용자 정보 조회하기
2. 실행할 SQL을 작성한다.
select *
from sample_users
where user_id = ?
3. 파라미터클래스(SQL 실행에 필요한 값을 표현하는 클래스)와 리절트클래스(SQL 실행결과를 저장하는 객체의 클래스)를 결정한다.
parameterClass="string" <--- SQL 실행에 필요한 값이 "사용자 아이디"
resultClass="com.sample.store.vo.User" <--- SQL을 실행하면 사용자정보(아이디, 비밀번호, 이름, 이메일 등 )가 조회된다. 그 정보를 모든 담을 수 있는 객체는 User 객체다.
4. 매퍼파일(resources/META-INF/ibatis/mappers/users.xml)에 SQL 구문 정의
<select id="getUserById" parameterClass="string" resultClass="com.sample.store.vo.User">
select user_id as id,
user_password as password,
user_name as name,
user_email as email,
...
from sample_users
where user_id = #value# // #value#에 들어갈 타입이 "string"이다.
</select>
5. DAO 클래스에 4번에 정의한 SQL 구문을 실행시키는 메소드를 정의
parameterClass="string" 이 메소드의 매개변수 타입이다.
resultClass="com.sample.store.vo.User"가 메소드의 반환타입이다.
* 단, SQL의 실행결과로 한 행이 조회되는지 여러 행이 조회되는 지에 따라서 반환타입이 달라진다.
* 한 행이 조회되는 경우 User가 메소드의 반환타입이다.
* 여러 행이 조회되는 경우 List<User>가 메소드의 반환타입니다.
public User getUserById(String userId) {
// Object SqlMapper.selectOne(String sqlId, Object param) : SELECT 구문을 실행한다. Object를 반환한다. (User가 될수도 있고, Product가 될 수도 있고 뭐가 올지를 모르니까 모든 객체의 반환타입을 Object로 작성해놓는다.)
// selectOne()메소드는 resultClass="com.sample.store.vo.User"에 정의된 객체를 Object로 클래스 형변환된 상태로 반환한다.
User user = (User) SqlMapper.selectOne("getUserById", userId);
return user;
}* Dao의 메소드는 매개변수가 1개 아니면 0개이다.
- 모든 사용자 정보를 조회하기 - SQL select * from sample_users order by user_id asc - parameter/result parameterClass : 정의할 필요없음 resultClass="com.sample.store.vo.User" <--- 사용자 정보(아이디, 비번, 이름, 이메일, 전화 ... 는 User객체에 저장할 수 있다.)가 여러 행 조회된다. - SQL 매핑 <select id="getAllUsers" resultClass="com.sample.store.vo.User"> select user_id as id, user_password as password, user_name as name, ... from sample_users order by user_id asc </select> - DAO클래스에 메소드 정의 public List<User> getAllUsers( ) { List<User> users = (List<User>) SqlMapper.selectList("getAllUser"); return users; } - 회원가입한 모든 사용자 수를 조회하기 - SQL select count(*) from sample_users - parameter/result parameterClass : 필요없음 resultClass="java.lang.Integer" 혹은 resultClass="int" <--- 사용자 숫자(정수)가 한 행 조회된다. - SQL 매핑 <select id="getUsersCount" resultClass="int"> select count(*) <!-- 값이 딱 하나만 조회되는 경우, 컬럼에 대한 별칭을 적을 필요없다. from sample_users resultClass의 타입을 해당 값의 타입에 맞게 string, int, long, double 중에서 하나를 적으면 된다. --> </select> - DAO클래스에 메소드 정의 public int getUsersCount( ) { int counts = (Integer) SqlMapper.selectOne("getUsersCount"); return counts; } - 회원정보 추가하기 - SQL insert into sample_users(user_id, user_password, user_name, user_email, user_tel, user_gender) values (?, ?, ?, ?, ?, ?) - parameter/result parameterClass="com.sample.store.vo.User" <--- 사용자 정보(아이디, 비번, 이름, 이메일, 전화 ... )를 전부 담아서 제공할 수 있는 객체는 User객체다. resultClass : INSERT 구문에서는 사용하지 않는다. - SQL 매핑 <insert id="insertUser" parameterClass="com.sample.store.vo.User"> insert into sample_users (user_id, user_password, user_name, user_email, user_tel, user_gender) values (#id#, #password#, #name#, #email#, #tel#, #gender#) <!-- User객체의 변수명과 매핑시킨다. --> </insert> - DAO클래스에 메소드 정의 public void insertUser(User user) { SqlMapper.insert("insertUser", user); // SQL 실행에 필요한 정보가 들어있는 User 객체를 ibatis에게 전달함 } - 회원정보 수정하기 - SQL update sample_users set user_password = ?, user_tel = ?, user_point = ?, user_enabled = ? user_updated = sysdate where user_id = ? - parameter/result parameterClass="com.sample.store.vo.User" resultClass : UPDATE 구문에서는 사용하지 않는다. - SQL 매핑 <update id="updateUser" parameterClass="com.sample.store.vo.User"> update sample_users set user_password = #password#, user_tel = #tel#, user_point = #point#, user_enabled = #enabled#, user_updated_date = sysdate where user_id = #id# </update> - DAO클래스에 메소드 정의 public void updateUser(User user) { SqlMapper.update("updateUser", user) } - 사용자이름으로 사용자 조회하기 - SQL select * from sample_users where user_name = ? // primary key, unique 제약조건이 지정된 컬럼 이외의 컬럼이 조건식에 사용되면 항상 여러 행이 조회될 수 있다. - parameter/result parameterClass="string" resultClass="com.sample.store.vo.User" <--- 사용자 정보(아이디, 비번, 이름, 이메일, 전화 ... 는 User객체에 저장할 수 있다.)가 여러 행 조회된다. - SQL 매핑 <select id="getUsersByName" parameterClass="string" resultClass="com.sample.store.vo.User"> select user_id as id, user_password as password, user_name as name, ... from sample_users where user_name = #value# </select> - DAO클래스에 메소드 정의 public List<User> getUsersByName(String name) { List<User> users = (List<User>)SqlMapper.selectList("getUsersByName", name); return users } - 데이터베이스 엑세스 작업 준비 - VO 클래스 정의 public class Product { private int no; private String name; private String maker; private int price; private double discountRate; private int stock; private String onSell; private Date createdDate; private Date updatedDate; } - 매퍼파일 정의 (resources/META-INF/ibatis/mappers/products.xml) <sqlmap> </sqlmap> - ibatis 환경설정 파일(resources/META-INF/ibatis/ibatis-config.xml)에 매퍼파일 등록 <sqlmap resource="META-INF/ibatis/mappers/products.xml" /> - DAO 클래스 정의 public class ProductDao { } - 상품번호로 상품 정보 조회하기 - SQL select * from sample_products where product_no = ? <-- product_no 컬럼은 Primary Key 제약조건이 정의된 컬럼, 한 행만 조회된다. - parameter/result parameterClass="int" resultClass="com.sample.store.vo.Product" - SQL 매핑 <select id="getProductByNo" parameterClass="int" resultClass="com.sample.store.vo.Product"> select product_no as no, product_name as name, product_maker as maker, ... from sample_products where product_no = #value# </select> - DAO클래스에 메소드 정의 public Product getProductByNo(int productNo) { Product product = (Product) SqlMapper.selectOne("getProductByNo", productNo); return product; } - 상품이름으로 상품정보 조회하기 - SQL select * from sample_products where product_name like '%' || ? || '%' <-- product_name 컬럼은 PK, UK 컬럼이 아니기 때문에 상품정보가 여러 행 조회될 수 있다. - parameter/result parameterClass="string" resultClass="com.sample.store.vo.Product" - SQL 매핑 <select id="getProductsByName" parameterClass="string" resultClass="com.sample.store.vo.Product"> select product_no as no, product_name as name, product_maker as maker, ... from sample_products where product_name like '%' || #value# || '%' </select> - DAO클래스에 메소드 정의 public List<Product> getProductsByName(String name) { // 메소드 이름은 id와 같을 필요 없지만 찾기 편하려고 같게 씀. List<Product> products = SqlMapper.selectList("getProductsByName", name); return products; } - 모든 상품정보 조회하기 - SQL select * from sample_products order by product_no desc - parameter/result parameterClass: 없음 resultClass="com.sample.store.vo.Product" (조회 조건이 없기 때문에 상품 정보가 여러 개 조회됨) - SQL 매핑 <select id="getAllProducts" resultClass="com.sample.store.vo.Product"> select product_no as no, product_name as name, product_maker as maker, ... from sample_products order by product_no desc </select> - DAO클레스에 메소드 정의 public List<Product> getAllProducts( ) { List<Product> products = (List<Product>) SqlMapper.selectList("getAllProducts"); return products; } - 새 상품정보 저장하기 - SQL insert into sample_products (product_no, product_name, product_maker, product_price, product_discount_rate, product_stock) values(sample_products_seq.nextval, ?, ?, ?, ?, ?) - parameter/result parameterClass="com.sample.store.vo.Product" resultClass : INSERT 구문에서는 사용하지 않는다. - SQL 매핑 <insert id="insertProduct" parameterClass="com.sample.store.vo.Product"> insert into sample_products (product_no, product_name, product_maker, product_price, product_discount_rate, product_stock) values (sample_products_seq.nextval, #name#, #maker#, #price#, #discountRate#, #stock#) </insert> - DAO클래스에 메소드 정의 public void insertProduct(Product product) { SqlMapper.insert("insertProduct", product); } - 최소가격, 최대가격 범위내의 상품정보 조회하기 - SQL select * from sample_products where product_price >= ? and product_price <= ? <-- product_price 컬럼은 PK, UK 컬럼이 아니기 때문에 상품정보가 여러 행 조회될 수 있다. order by product_price asc - parameter/result parameterClass="map" 혹은 parameterClass="java.util.Map" resultClass="com.sample.store.vo.Product" - SQL 매핑 <select id="getProductsByPrice" parameterClass="map" resultClass="com.sample.store.vo.Product"> select product_no as no, product_name as name, product_maker as maker, ... from sample_products where product_price >= #minPrice# and product_price <= #maxPrice# order by product_no desc </select> - DAO클래스에 메소드 정의 public List<Product> getProductsByPrice(Map<String, Object> param) { List<Product> products = (List<Product>) SqlMapper.selectList("getProductsByPrice", param); return products } * 가격으로 검색하기 사용 Map<String, Object> paramMap = new HashMap<>( ); paramMap.put("minPrice", 10000); paramMap.put("maxPrice", 50000); List<Product> products = productDao.getProductsByPrice(paramMap);
< products.xml >
<!-- 상품 가격(최소가격, 최대가격)으로 상품정보를 조회하는 SQL --> <select id="getProductsByPrice" parameterClass="map" resultClass="com.sample.store.vo.Product"> <![CDATA[ <!-- C DATA 섹션, 안에 내용을 순수 텍스트로 인식함. 따라서 안에 꺽쇠표시(<,>)가 있어도 오류 안난다. --> select product_no as no, product_name as name, product_maker as maker, product_price as price, nvl(product_discount_rate, 0) as discountRate, product_stock as stock, product_on_sell as onSell, product_created_date as createdDate, product_updated_date as updatedDate from sample_products where product_price >= #minPrice# and product_price <= #maxPrice# order by product_price asc ]]> </select>
★ 메소드의 실행 순서, 데이터의 흐름
사용자가 입력한 값이 메소드 실행에 필요한 값인 인자값으로 전달되면 메소드의 매개변수로 전달된다.
XML
- eXtensible Markup Language
- 확장 가능한 마크업 문서를 작성하는 표준이다.
* 확장 가능한 : 사용자가 임의의 태그, 문서작성 규칙을 자유롭게 정의해서 사용할 수 있다.
* 마크업 문서 : <태그> 혹은 <태그 속성명="속성값">을 이용해서 작성된 문서다.
XML 문서의 구조
선언부
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 문서 선언 -->
<!-- 도큐먼트 타입 선언 -->
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
바디부
<sqlmap> <!-- Root 엘리먼트(태그) -->
<!-- XML 컨텐츠 -->
</sqlmap>
HTML
- Hyper Text Markup Language
- 링크를 클릭하면 그 링크와 연결된 문서를 열어 볼 수 있는 마크업 문서를 작성하는 표준이다.
- 사용자가 임의로 태그를 생성해서 사용할 수 없다.
* 태그의 종류, 태그의 속성, 태그의 작성규칙이 정해져있다.
* 모든 브라우저는 HTML 표준에 맞게 작성된 HTML문서를 렌더링해서 표현한다.'기록' 카테고리의 다른 글
학원 day40. 웹, HTML, 태그, 속성 (0) 2022.11.01 학원 day39. 분석함수, 집합 연산, 계층형 쿼리 (0) 2022.10.31 학원 day36. ibatis (0) 2022.10.26 학원 day35. 무결성제약조건, 인덱스, 트랜잭션 (0) 2022.10.26 학원 day34. 시퀀스, 테이블, 뷰, 무결성 제약조건 (0) 2022.10.25