我们都知道在实际开发中我们很多都会面向接口编程,特别使我们的数据持久层的开发,通常都会在接口中定义好方法和一些规范。通过上一篇文章的学习,我们初步的理解了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内部就会帮你将参数封装成数组。然后对于参数都是实体类型的,我们可以直接传递实体对象
.