2013年8月25日 星期日

MyBatis - 基本安裝 + 使用Select

  1. 於eclipse建立New Project【TestMyBatis】
  2. eclipse中的BuildPath加入mybatis-xxxx.jar(我安裝這時候為mybatis-3.2.2.jar)
  3. 建立res資料夾,這個資料夾會存放所有mybatis的config、mapper...等XML設定
  4. 於eclipse的Build Path加入res路徑(Add Folder->選擇res資料夾)

  5. 於res下加入jdbc.properties,這是讓我們設定jdbc資料庫連線的各種設定;這邊我們使用hsqldb,方便測試使用:
    jdbc.driver=org.hsqldb.jdbcDriver
    jdbc.url=jdbc:hsqldb:mem:my-project-test;shutdown=true
    jdbc.username=sa
    jdbc.password=
    
  6. 於res下加入mybatis-config.xml
    
      
      
        
          
          
            
            
            
            
          
        
      
      
        
      
    
    

    這是主要讓mybatis設定環境連線參數的設定檔
  7. 於res下加入UserMapper.xml
    
      < select id="getUserById" parametertype="String" resulttype="cmpnts.User">
         SELECT 
          userid as userid, 
          email as email , 
          password, 
          name as Name
         FROM USER 
         WHERE USERID = #{userId}
      </ select>
    
    

    (以上select開頭的tag空格請自行刪除,因為不用空格會被Blogger判定為HTML select)
    因為這篇只做SELECT因此以上設定檔只列出SELECT,可以看到SQL的語法直接寫在Mapper設定中就好了!非常的方便! 甚至若有邏輯上判斷的需求也可以直接寫在這,詳細請看這Dynamic SQL
  8. 建立package cmpnts,並加入User Class
    package cmpnts;
    
    public class User {
     private String userid;
     private String name;
     private String password;
     private String email;
    
     public String getUserId() {
      return userid;
     }
    
     public void setUserId(String userid) {
      this.userid = userid;
     }
    
     public String getName() {
      return name;
     }
    
     public void setName(String username) {
      this.name = username;
     }
    
     public String getPassword() {
      return password;
     }
    
     public void setPassword(String pwd) {
      this.password = pwd;
     }
     
     public String getEmaill(){
      return email;
     }
     
     @Override
     public String toString(){
      StringBuffer buf = new StringBuffer();
      buf.append("UserId:").append(this.getUserId());
      buf.append("\r\n\tname:").append(this.getName());
      buf.append("\r\n\tpassword:").append(this.getPassword());
      buf.append("\r\n\temail:").append(this.getEmaill());
      return buf.toString();
     }
    }
    
  9. 加入UserMapper Class

    package cmpnts;
    import java.util.List;
    
    public interface UserMapper{
     //public void insertUser(User user);
     public User getUserById(String userId);
     //public List getAllUsers();
     //public void updateUser(User user);
     //public void deleteUser(Integer userId);
    }
    

    這是我們的UserMapper Interface,由於這篇我們只會使用SELECT,因此實際上使用到的只有getUserById(String userId);


    到這邊準備工作都完成了,可以開始呼叫測試看結果了。
  10. 呼叫方式如下:
    public static void main(String[] args) {
      String resource = "mybatis-config.xml";
      InputStream inputStream;
      try {
         inputStream = Resources.getResourceAsStream(resource);
         SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
         .build(inputStream);
    
         createTableUser();
                    
         User user = UserDAO.getUserById(sqlSessionFactory,"Q011");
         System.out.println(user);
    
      } catch (Exception e) {
         e.printStackTrace();
      }
    }
    

    其中的createTableUser()我使用HSQLDB來建立Table,由於跟MyBatis並無關聯因此就不列出了, 習慣使用其他DataBase的直接依照一般習慣建立Table使用即可。(記得上面的jdbc.properties也要更改為自行使用的DataBase設定)
  11. UserDAO.java
    public static User getUserById(SqlSessionFactory sqlSessionFactory, String userid) {
       SqlSession sqlSession = sqlSessionFactory.openSession();
       try {
     UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
     return userMapper.getUserById(userid);
       } finally {
     sqlSession.close();
       }
    }
    

    • 首先我們傳入在main中建立的SqlSessionFactory
    • 使用SqlSessionFactory建立SqlSession 
    • 利用SqlSession獲得UserMapper的對應
    • 呼叫 getUserById(),取得我們要的結果User
    • 關於各種mybatis物件的life time請參考Getting started下面的Scope and Lifecycle
  12. 以下就是main呼叫後取得的User Println()結果
    UserId:Q011
     name:Q011anne
     password:annepwd123
     email:anne@mail.piwi.com.tw
    

以上看起來很神奇,其實說穿了就是使用Java Reflection的機制來做的(請見Java Reflection - 存取Field 資訊);
實際上測試了一下,他是直接對應field name;也就是說在User.java中的各種field name: userid、name、password、email都要能與在UserMapper.xml中寫下的SELECT Query相符(大小寫不限):
SELECT 
      userid as Userid, 
      email as Email , 
      password, 
      name as Name
     FROM USER 
     WHERE USERID = #{userId}

而與method name(getter、setter)沒有關聯。

2013/9/7補充:
   上述的SELECT語法,若沒有使用ResultMap一次傳回大量資料(請見此篇MyBatis - 使用resultMap、resultType自行定義回傳資料)則務必要使用如上述的 userid as userid 這種方式才有辦法對應的到,後面的 as userid,一定要使用回傳Java Type的field name,比如如果習慣field name使用_usierid、_eamil,就一定要寫成
SELECT 
      userid as _userid, 
      email as _email, 
      password as _password, 
      name as _name
     FROM USER 
     WHERE USERID = #{userId}
否則怎麼回傳都會是Null Data,倒是 #{userId}使用甚麼名稱都無所謂,使用 #{xx}也是可以的,應該是只要param順序對應到就可以

但是,如果像我Class field都習慣前面加上 _name、_userid這種方式,DB的field又不能修改成這樣,該怎麼辦呢? 這時候可以藉助好用的resultMap機制達到喔,請見此篇MyBatis - 使用resultMap、resultType自行定義回傳資料

沒有留言:

張貼留言