文章出處

上一篇博文總結了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接口中所有方法的參數都只有一個!那如果我們要傳入兩個或多個參數該咋整?這沒辦法,想要傳多個參數還是死了這條心了吧,但是可以解決這個問題,就是對傳入的對象進行增強,讓傳進去的對象包含我們需要的參數即可。這算是個小弊端吧,但是不會影響我們開發。

 

 

本篇遺留了 

<mapper resource="sqlmap/User.xml" />
<mapper resource="mybatis/mapper/UserMapper.xml"/> 這2個必要的
<mapper class="mybatis.dao.UserMapper"/> 這個不確定要不要 一直報錯
<!-- <package name="mybatis.mapper"/> -->注意:此種方法要求mapper接口和mapper映射文件要名稱相同,且放到同一個目錄下;

一直報這個錯:org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): mybatis.dao.UserMapper.findUserByName

 

 

 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()