ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 학원 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문서를 렌더링해서 표현한다.

    댓글

Designed by Tistory.