上一篇文章总结了一些Dao开发的问题,所以我们这里开始讲一种mapper代理的方式去开发。
我先给出mapper代理开发的思路(mapper代理开发的规范):
我们用mapper代理开发时要写2个:
1.mapper.xml
2.mapper接口
我们写的mapper接口只要需要遵循一些开发规则,mybatis可以自动生成mapper接口实现类代理对象。(这句话很重要)
我们重点讲一下开发规则:
开发规范:
1、在mapper.xml中namespace等于mapper接口地址
2、mapper.java接口中的方法名和mapper.xml中statement的id一致
mapper.xml中是这样的:
mapper.java接口应该是这样的:

名字要一模一样的。
3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。

总结:
以上开发规范主要是对下边的代码进行统一生成:
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insertUser", user);
接下来将案例:
先给出案例的结构:
第一步:编写:sqlMapConfig.xml文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 和spring整合后 environments配置将废除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybaits?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="root" /> </dataSource> </environment> </environments> <!-- 把映射文件(sqlmap/user.xml)加载进sqlMapConfig.xml--> <mappers> <!-- 把mapper.xml加载进sqlMapConfig.xml--> <mapper resource="mapper/userMapper.xml"/> </mappers> </configuration>
第二步:编写mapper/userMapper.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"> <!-- nanmespace:命名空间。 作用就是对sql进行分类话管理,理解Sal分离 注意:使用mapper代理方式,namespace有特殊重要的作用 --> <mapper namespace="cn.itcast.mybatis.Dao.UserMapper"> <!-- 根据id获取用户信息 --> <!-- 在映射文件中配置很多sql语句 --> <!-- id:标识映射文件中的sql; 将sql语句封装到mappedStatement对象中,所以将id称为statement的id;parmenterType:指定输入的参数的类型,这里指定的int型 #{}表示一个占位符号; #{id}:其中的id表示接收输入的参数,参数名称就是id,如果输入参数就是简单类型,#{}中的参数名可以任意,可以value或其它名称 resultType:指定的sql输出结果的所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象; --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> select * from user where id = #{id} </select> </mapper>
第三步:UserMapper.java文件
package cn.itcast.mybatis.Dao; import cn.itcast.mybatis.po.User; public interface UserMapper { //这个名字(findUserById)和UserMapper.xml里面的id要一模一样 public User findUserById(int id); }
第四步:编写junit测试代码。编写Mybatis_mappertest.java
package cn.itcast.mybatis.first; import java.io.IOException; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import cn.itcast.mybatis.Dao.UserMapper; import cn.itcast.mybatis.po.User; public class Mybatis_mappertest { private SqlSessionFactory sqlSessionFactory; @Before public void setup() throws IOException { String resource="SqlMapConfig.xml"; InputStream inputStream= Resources.getResourceAsStream(resource); //主要是生成SqlsessionFactory。 this.sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testMaper() { SqlSession sqlSession=null; sqlSession=sqlSessionFactory.openSession(); //生成代理类 UserMapper userMapper=sqlSession.getMapper(UserMapper.class); User user=userMapper.findUserById(29); System.out.println(user.getUsername()); } }
运行结果:正常。
---------------------------------------------------------------------------------------------------------------------------------------------------------------
扩展一下,我们在查询时如果查询到很多条数据,时怎么写?
1.修改userMapper.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"> <!-- nanmespace:命名空间。 作用就是对sql进行分类话管理,理解Sal分离 注意:使用mapper代理方式,namespace有特殊重要的作用 --> <mapper namespace="cn.itcast.mybatis.Dao.UserMapper"> <!-- 根据id获取用户信息 --> <!-- 在映射文件中配置很多sql语句 --> <!-- id:标识映射文件中的sql; 将sql语句封装到mappedStatement对象中,所以将id称为statement的id;parmenterType:指定输入的参数的类型,这里指定的int型 #{}表示一个占位符号; #{id}:其中的id表示接收输入的参数,参数名称就是id,如果输入参数就是简单类型,#{}中的参数名可以任意,可以value或其它名称 resultType:指定的sql输出结果的所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象; --> <select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User"> select * from user where id = #{id} </select> <!--where username like '%${value}%' 这句话中必须写value不然就报错。因为规则上明确说过 ${}接收输入参数,类型可以是简单类型,pojo、hashmap。 如果接收简单类型,${}中只能写成value。 --> <select id="findUserByName" parameterType="String" resultType="cn.itcast.mybatis.po.User"> select * from user where username like '%${value}%' </select> </mapper>
2.修改UserMapper.java代码:
package cn.itcast.mybatis.Dao; import java.util.List; import cn.itcast.mybatis.po.User; public interface UserMapper { //这个名字(findUserById)和UserMapper.xml里面的id要一模一样 public User findUserById(int id); //注意这里写的是返回的List.这样代码内部就会调用selectList,但是在userMapper.xml中要写的是 //resultType="cn.itcast.mybatis.po.User" /* * * <select id="findUserByName" parameterType="String" resultType="cn.itcast.mybatis.po.User"> select * from user where username like '%${value}%' </select> * * */ public List<User> findUserByName(String name); }
-------------------------------------------------------------------------------------------------------------------------------------------------------------
最后对mapper开发方式做一个总结:
1. 代理对象内部调用selectOne或selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。
2.mapper接口方法参数只能有一个是否影响系统 开发
mapper接口方法参数只能有一个,系统是否不利于扩展维护。比如
这些方法中只有一个参数,因为:在userMapper.xml中只有一个resultType=“”但是:
系统 框架中,dao层的代码是被业务层公用的。
即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。
注意:持久层方法的参数可以包装类型、map。。。,service方法中建议不要使用包装类型(不利于业务层的可扩展)。
