[关闭]
@nextleaf 2018-07-18T18:59:06.000000Z 字数 3829 阅读 657

【3】Mapper代理方法开发dao

MyBatis


上一篇总结了mybatis使用 原始dao的方法存在的一些弊端,我们肯定不会去用它,那么mybatis中该如何开发dao呢?
使用mapper代理的方法来开发dao的步骤。

使用mapper代理的方法来开发dao时,程序员只需要干两件事即可:
1.需要编写mapper.xml映射文件
2.需要编写mapper接口(相当于dao接口)

从做的工作来看,使用mybatis中使用mapper代理来开发dao会很方便,完全不需要我们去写具体的实现类,只需要写出接口即可,但是接口不能直接拿来用啊,那么该如何产生它的实现类对象呢?这在下文会给出答案

1.UserMapper.xml

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,如下:
此处输入图片的描述

  1. <mapper namespace="com.mapper.UserMapper">
  2. <select id="findUserById" parameterType="int" resultType="com.vo.User">
  3. select * from user where id = #{id}
  4. </select>
  5. <select id="findUserByName" parameterType="java.lang.String" resultType="com.vo.User">
  6. select * from user where username like '%${value}%'
  7. </select>
  8. <insert id="insertUser" parameterType="mybatis.po.User">
  9. insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
  10. <!-- 将插入数据的主键返回,返回到user对象中 -->
  11. <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
  12. select last_insert_id()
  13. </selectKey>
  14. <!--
  15. <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
  16. select uuid()
  17. </selectKey>
  18. -->
  19. </insert>
  20. </mapper>

2.UserMapper.java(接口)

定义好了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

  1. import com.vo.User;
  2. import java.util.List;
  3. //mapper接口,相当于dao接口
  4. public interface UserMapper {
  5. //根据id查询用户信息
  6. public User findUserById(int id) throws Exception;
  7. //根据用户名模糊查询
  8. public List<User> findUserByName(String name) throws Exception;
  9. //添加用户信息
  10. public void insertUser(User user) throws Exception;
  11. //删除用户信息
  12. public void deleteUser(int id) throws Exception;
  13. //更新用户信息
  14. public void updateUser(User user) throws Exception;
  15. }

这里要注意一点就是findUserByName的方法,返回的是一个装有User的List,但是UserMapper.xml中对应的resultType类型是User,这里要注意,在前面的博文中也提到了,resultType指定的是单个返回结果的类型,也就是一条记录的类型,即User,但是这个findUserByName是返回很多User,所以返回值是List。mybatis会自动根据返回值类型去调用不同的方法,如下:

如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne来查询数据库
如果mapper方法返回一个集合对象,代理对象内部通过selectList来查询数据库

所以完全不用担心上面这个问题,mybatis已经帮我们解决好了。到这里还没完,还有一步就是别忘了在全局配置文件SqlMapConfig.xml中配置刚刚的UserMapper.xml,如下

  1. <mappers>
  2. <mapper resource="sqlmap/User.xml" />
  3. <mapper resource="mapper/UserMapper.xml" />
  4. </mappers>

3.测试程序

如何产生实现类的对象呢?我们在测试程序中来看:

  1. private SqlSessionFactory sqlSessionFactory;
  2. @Before //创建sqlSessionFactory
  3. public void setUp() throws Exception {
  4. String resource = "SqlMapConfig.xml"; //mybatis配置文件
  5. //得到配置文件的流
  6. InputStream inputStream = Resources.getResourceAsStream(resource);
  7. //创建会话工厂SqlSessionFactory,要传入mybaits的配置文件的流
  8. sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  9. }
  10. @Test
  11. public void testFindUserById() throws Exception {
  12. SqlSession sqlSession = sqlSessionFactory.openSession();
  13. //创建UserMapper对象,mybatis自动生成mapper代理对象
  14. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  15. User user = userMapper.findUserById(1);
  16. System.out.println(user);
  17. }
  18. @Test
  19. public void testFindUserByName() throws Exception {
  20. SqlSession sqlSession = sqlSessionFactory.openSession();
  21. //创建UserMapper对象,mybatis自动生成mapper代理对象
  22. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
  23. List<User> list = userMapper.findUserByName("倪升武");
  24. sqlSession.close();
  25. System.out.println(list);
  26. }
  27. }

原来这个sqlSession可以自动创建一个mapper接口的代理对象!我们只需要把刚刚写好的mapper接口类的字节码对象传给getMapper方法,即可得到一个该接口对应的代理对象,然后我们就可以使用这个代理对象来操作接口中具体的方法了。
到这里,使用mapper代理的方式开发dao就总结完了,但是有个小细节,由于mapper接口中方法的参数要根据映射文件中的parameterType来指定,而parameterType只有一个,所以mapper接口中所有方法的参数都只有一个!那如果我们要传入两个或多个参数该咋整?这没办法,想要传多个参数还是死了这条心了吧,但是可以解决这个问题,就是对传入的对象进行增强,让传进去的对象包含我们需要的参数即可。这算是个小弊端吧,但是不会影响我们开发

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注