我們都知道在實際開發中我們很多都會面向接口編程,特別使我們的數據持久層的開發,通常都會在接口中定義好方法和一些規範。通過上一篇文章的學習,我們初步的理解了MyBatis的執行流程。但是卻存在一個問題,如果有一天我們的需求發生了改變,方法的名字改變了,或者是要新增某個方法或者刪除某個方法,那麼想象一下,我們是不是要去工程中找到所有用了這個配置文件的類裏面的方法,然後將他們的名字修改過來,這樣就會造成修改源代碼,在開發中如果需求改變就要修改源代碼的話,那肯定效率會很低的,於是在MyBatis中有一個專門解決這個問題的方法就是Mapper代理。它主要就是通過配置文件和接口關聯起來。這樣我們只要修改接口就可以了,而不需要修改所有代碼中的類。下面還是通過上一篇博文的案例,只是稍加修改。
user.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--對於面向接口編程 namespace必須是接口的名字(全路徑)
id必須是對應接口中方法的名字
resultType必須是參數返回值類型
parameterType必須是方法中參數的類型
-->
<mapper namespace="com.yxc.dao.UserDao">
<!--在這裏面配置各種sql語句-->
<!--添加用戶-->
<select id="addUser" parameterType="com.yxc.domain.User">
insert into user values(#{id},#{username},#{password})
</select>
<!--根據id刪除一個用戶-->
<select id="deleteUser" parameterType="int">
delete from user where id=#{id}
</select>
<!--更新數據-->
<select id="updateUser" parameterType="com.yxc.domain.User">
update user set username=#{username} where id=#{id}
</select>
<!--根據id查詢一條用戶信息-->
<select id="findUser" parameterType="int" resultType="com.yxc.domain.User">
select * from user where id=#{id}
</select>
<!--查詢所有用戶信息-->
<select id="findAllUser" resultType="com.yxc.domain.User">
select * from user
</select>
<!--根據用戶名和密碼查詢-->
<select id="getUser" resultType="com.yxc.domain.User">
select * from user where username=#{username} and password=#{password}
</select>
</mapper>
接口
package com.yxc.dao;
import com.yxc.domain.User;
import java.util.List;
/**
* 面向接口編程,擴展性更強
*/
public interface UserDao {
/**新增用戶方法*/
public void addUser(User user);
/**根據id刪除一個用戶*/
public void deleteUser(int id);
/**根據id查詢客戶*/
public User findUser(int id);
/**更新一個用戶*/
public void updateUser(User user);
/**查詢所有用戶*/
public List<User> findAllUser();
/**根據用戶名和密碼查詢用戶
* 通過這個方法瞭解一下怎麼傳遞多個參數
* */
public User getUser(@Param("username") String username,@Param("password") String password);
}
這是測試類
package com.yxc.test;
import com.yxc.dao.UserDao;
import com.yxc.domain.User;
import com.yxc.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
* 測試開發中面向接口編程怎麼使用Mybatis
*/
public class UserDaoTest {
@Test
/**新增一個用戶*/
public void testAddUser(){
//獲取一個sqlSession對象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//給定一個要添加的用戶對象
User user=new User();
user.setId(7);
user.setUsername("從心開始");
user.setPassword("123456");
UserDao mapper = sqlSession.getMapper(UserDao.class);
mapper.addUser(user);
//提交事務
sqlSession.commit();
//關閉資源
sqlSession.close();
}
@Test
/**根據id刪除一個用戶*/
public void deleteUser(){
//獲取sqlSession對象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
mapper.deleteUser(5);
//提交事務然後關閉資源
sqlSession.commit();
sqlSession.close();
}
@Test
/**跟新一個用戶信息*/
public void updateUser(){
//獲取sqlSession對象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
User user=new User();
user.setId(5);
user.setUsername("congxin");
UserDao mapper = sqlSession.getMapper(UserDao.class);
mapper.updateUser(user);
//提交事務然後關閉資源
sqlSession.commit();
sqlSession.close();
}
@Test
/**根據id查詢一個用戶信息*/
public void selectOneUser(){
//獲取sqlSession對象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//通過mapper代理來獲取接口對象,這樣如果配置文件中修改了內容以後,我們也不需要在源文件中修改代碼
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.findUser(2);
System.out.println(user);
//對於查詢語句來說不需要提交事務
sqlSession.close();
}
/**查詢所有用戶信息*/
@Test
public void selectAll(){
//獲取sqlSession對象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//查詢所有
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> allUser = mapper.findAllUser();
System.out.println(allUser);
//對於查詢語句來說不需要提交事務
sqlSession.close();
}
/**根據用戶名和密碼查詢*/
@Test
public void getUser(){
//獲取sqlSession對象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
User user = mapper.getUser("yxc", "1234");
System.out.println(user);
}
}
關於其它幾個類的代碼參考MyBatis從入門到不放棄(一)
其實如果掌握了上一篇的知識以後,再看這一篇文章是很容易的,在這裏多了一個接口,在接口中定義了各種方法以及方法的規範,然後在配置文件中有幾個屬性需要注意的:
<!--對於面向接口編程 namespace必須是接口的名字(全路徑)
id必須是對應接口中方法的名字
resultType必須是參數返回值類型
parameterType必須是方法中參數的類型
-->
最後改動的就是測試類中的調用方法的方式,不再輸入配置文件中的id名了,而是通過Mapper代理來幫我們匹配對應的方法,這樣,需求改變,測試類是不需要修改的。在這裏有一點需要注意的就是selectOne和selectList沒有出現,那是因爲mapper動態代理幫你封裝好了,它會根據你返回的類型來判斷調用哪一個方法,如果返回類型是一個實體對象,那麼就調用selectOne,如果返回類型是List集合,那麼就會調用selectList。
最後在這篇文章還涉及一個知識點就是傳遞多個參數怎麼辦?我們通過案例根據用戶名和密碼查詢用戶說明了這個問題,使用註解@Param註解綁定參數,MyBatis內部就會幫你將參數封裝成數組。然後對於參數都是實體類型的,我們可以直接傳遞實體對象
.