上一篇博文總結了mybatis使用 原始dao的方法存在的一些弊端,我們肯定不會去用它,那么mybatis中該如何開發dao呢?如題所述,這篇博文主要來總結一下使用mapper代理的方法來開發dao的步驟。
使用mapper代理的方法來開發dao時,程序員只需要干兩件事即可:
- 需要編寫mapper.xml映射文件
- 需要編寫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接口了,編寫mapper接口要遵循以下四個開發規范:
- 在mapper.xml中,使namespace等于mapper接口的地址(完全限定名)
- mapper.java接口中的方法名和mapper.xml中statement的id一致
- mapper.java接口中方法的輸入參數類型和mapper.xml中statement的parameterType指定的類型一致
- 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
文章列表