1. 程式人生 > >【MyBatis學習04】mapper代理方法開發dao

【MyBatis學習04】mapper代理方法開發dao

  上一篇博文總結了mybatis使用 原始dao的方法存在的一些弊端,我們肯定不會去用它,那麼mybatis中該如何開發dao呢?如題所述,這篇博文主要來總結一下使用mapper代理的方法來開發dao的步驟。
  使用mapper代理的方法來開發dao時,程式設計師只需要幹兩件事即可:

  1. 需要編寫mapper.xml對映檔案
  2. 需要編寫mapper介面(相當於dao介面)

  從做的工作來看,使用mybatis中使用mapper代理來開發dao會很方便,完全不需要我們去寫具體的實現類,只需要寫出介面即可,但是介面不能直接拿來用啊,那麼我該如何產生它的實現類物件呢?這在下文會給出答案。
  所謂的mapper.xml對映檔案,內容其實是跟前面的User.xml檔案是一樣的,主要是跟定義一些跟User這個pojo之間的對映相關的東西,唯一不同的地方就在於namespace的賦值。在前面的User.xml檔案中,我們設定了namespace為”test”,然後在java方法呼叫的時候,我們會呼叫類似於sqlSession.insert("test.insertUser", user);

的方法,來定位需要執行的sql語句。但是在mapper.xml對映檔案中,namespace要設定為我們接下來寫的mapper介面的地址,即完全限定名。假設我們新建一個mapper包,在裡面新建一個UserMapper.xml,如下:

mapper.xml

  定義好了mapper.xml對映檔案後,接下來就要編寫mapper介面了,編寫mapper介面要遵循以下四個開發規範:

  1. 在mapper.xml中,使namespace等於mapper介面的地址(完全限定名)
  2. mapper.java介面中的方法名和mapper.xml中statement的id一致
  3. mapper.java介面中方法的輸入引數型別和mapper.xml中statement的parameterType指定的型別一致
  4. mapper.java介面中方法返回值型別和mapper.xml中statement的resultType指定的型別一致

  根據這四條開發規範,我們來完成mapper介面:UserMapper.java

//mapper介面,相當於dao介面
public interface UserMapper {

    //根據id查詢使用者資訊
    public User findUserById(int id) throws Exception;
    //根據使用者名稱模糊查詢
    public List<User> findUserByName(String name) throws
Exception; //新增使用者資訊 public void insertUser(User user) throws Exception; //刪除使用者資訊 public void deleteUser(int id) throws Exception; //更新使用者資訊 public void updateUser(User user) throws Exception; }

  這裡要注意一點就是findUserByName的方法,返回的是一個裝有User的List,但是UserMapper.xml中對應的resultType型別是User,這裡要注意,在前面的博文中也提到了,resultType指定的是單個返回結果的型別,也就是一條記錄的型別,即User,但是這個findUserByName是返回很多User,所以返回值是List<User>。mybatis會自動根據返回值型別去呼叫不同的方法,如下:

如果mapper方法返回單個pojo物件(非集合物件),代理物件內部通過selectOne來查詢資料庫
如果mapper方法返回一個非集合物件,代理物件內部通過selectList來查詢資料庫

  所以完全不用擔心上面這個問題,mybatis已經幫我們解決好了。到這裡還沒完,還有一步就是別忘了在全域性配置檔案SqlMapConfig.xml中配置剛剛的UserMapper.xml,如下:
配置
  到現在為止,使用mapper代理的方式開發dao步驟基本上就搞定了。下面就開始寫測試程式了。但是還遺留一個問題,就是文章開頭提到的:現在只有mapper介面啊,那麼你是如何產生實現類的物件呢?我們在測試程式中來看:

private SqlSessionFactory sqlSessionFactory;

    @Before //建立sqlSessionFactory
    public void setUp() throws Exception {
        String resource = "SqlMapConfig.xml"; //mybatis配置檔案 
        //得到配置檔案的流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        //建立會話工廠SqlSessionFactory,要傳入mybaits的配置檔案的流
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);      
    }

    @Test
    public void testFindUserById() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();
        //建立UserMapper物件,mybatis自動生成mapper代理物件
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findUserById(1);
        System.out.println(user);
    }

    @Test
    public void testFindUserByName() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();
        //建立UserMapper物件,mybatis自動生成mapper代理物件
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> list = userMapper.findUserByName("倪升武");
        sqlSession.close();
        System.out.println(list);
    }
}

  原來這個sqlSession可以自動建立一個mapper介面的代理物件!我們只需要把剛剛寫好的mapper介面類的位元組碼物件傳給getMapper方法,即可得到一個該介面對應的代理物件,然後我們就可以使用這個代理物件來操作介面中具體的方法了。
  到這裡,使用mapper代理的方式開發dao就總結完了,但是有個小細節,由於mapper介面中方法的引數要根據對映檔案中的parameterType來指定,而parameterType只有一個,所以mapper介面中所有方法的引數都只有一個!那如果我們要傳入兩個或多個引數該咋整?這沒辦法,想要傳多個引數還是死了這條心了吧,但是可以解決這個問題,就是對傳入的物件進行增強,讓傳進去的物件包含我們需要的引數即可。這算是個小弊端吧,但是不會影響我們開發。

文末福利:“程式設計師私房菜”,一個有溫度的公眾號~
程式設計師私房菜