美文网首页
五、使用MyBatis实现条件查询

五、使用MyBatis实现条件查询

作者: lifeline张 | 来源:发表于2018-08-25 09:37 被阅读0次

    一、本课目标

    • 掌握SQL映射文件的常用元素
    • 掌握使用select完成(单/多)条件查询
    image.png

    简介:
    1、mapper,是映射文件的根节点。里面只有一个属性namespace,即命名空间,通过namespace来区分不同的mapper来做到全局唯一。并且通过namespace还可以绑定相应的DAO接口来实现面向接口编程。

    二、mapper

    image.png

    有了Mapper。xml文件之后,就不用写Mapper接口的具体实现类了,mybatis会通过接口的完全限定名去找到对应的Mapper里面的sql语句去执行。也就是说namaspace的命名必须跟某个接口同名,此时接口中的方法与映射文件中sql语句id一一对应。

    namespace

    namespace的属性值cn.smbms.dao.user.UserMapper到底是java文件的名字还是xml文件的名字?
    因为我们之前的目录是以下这样的:

    image.png
    可以进行如下的测试:
    新建一个mapper包,将UserMapper.xml放进来:
    image.png
    同时修改改xml文件中的namespace属性值:
    image.png
    则对于单元测试的第一种方式来说:
    image.png
    只要将后面的字符串改为跟namespace的值相同就可以成功测试。
    而对于第二种使用接口的测试方式来说则会报错,这时如果将mapper包下面的UserMapper.xml文件的namespace属性值改为:
    cn.smbms.dao.user.UserMapper,则可以测试成功,说明当使用接口的时候,程序会去找namespace的值为接口的完全限定名的mapper标签。

    综上,在mybatis-config.xml文件中引入UserMapper.xml文件之后,当使用select的方式去执行操作的时候,只需要把namespace的值写进后面的字符串参数即可;当使用接口的方式的时候,程序会去找接口的完全限定名,只要当Mapper.xml中的namespace的值设置的跟接口的完全限定名即路径一致的时候才能执行。也就是上面的两句话,xml文件中的namespace的值必须跟某个接口的绝对路径相同,同时xml文件中的sql语句的id必须跟接口中的方法同名。
    所以,可以把namespace的值写为java文件的名字,这样不管使用什么方法,总不会有问题。
    习惯上都会把mapper、.xml文件跟你的mapper接口放在一个包下面,并且在MyBatis里面,我们的DAO接口一般不叫作UserDao,而叫做UserMapper

    三、select元素

    image.png

    3、1单参数查询

    在UserMapper.xml文件中增加查询:

       <!-- 根据用户名称查询用户列表(模糊查询) -->
        <select id="getUserListByUserName" parameterType="string" resultType="User">
            select * from smbms_user where userName like CONCAT('%',#{userName},'%')
        </select>
    

    分析:1、参数类型是string,这个地方对大小写不敏感。参数类型也可以是自己定义的实体类类型。
    2、sql语句中拿到参数的方法是#{参数名},这个参数名跟测试类中传进来的参数名必须一样。
    3、数据库字段名必须跟实体类字段名保持一致,这样才能把查询到的数据跟实体类对象一一匹配。
    在UserMapper.java中增加方法:

        public List<User> getUserListByUserName(String userName);
    

    3、构建测试类:

    @Test
        public void testGetUserListByUserName() {
            List<User> userList = null;
            SqlSession sqlSession = null;
            String userName = "赵";
            try {
                sqlSession = MyBatisUtil.createSqlSession();
                userList = sqlSession.getMapper(UserMapper.class).getUserListByUserName(userName);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                MyBatisUtil.closeSqlSession(sqlSession);
            }
            for (User user:userList) {
                logger.debug("testGetUserList userCode:" + user.getUserCode()
                        + "and userName" + user.getUserName());
            }
        }
    

    3.2多条件查询

    问题:按条件查询用户表,若多条件情况先如何处理?


    image.png

    分析:
    1、传入多个参数进行入参?
    2、封装成user对象进行入参?


    image.png

    使用实体类入参

    示例代码:
    改造UserMapper.xml文件:

        <!-- 查询用户列表 -->
        <select id="getUserList" parameterType="user" resultType="User">
            select * from smbms_user 
            where userName like CONCAT('%',#{userName},'%')
            and userRole=#{userRole}
        </select>
    

    改造接口:

    public List<User> getUserList(User user);
    

    改造测试类;

    @Test
        public void testGetUserList() {
            List<User> userList = null;
            SqlSession sqlSession = null;
            User user1 = new User();
            user1.setUserName("赵");
            user1.setUserRole(2);
            try {
                sqlSession = MyBatisUtil.createSqlSession();
            // 4、调用mapper文件来对数据进行操作,操作之前必须将mapper文件引入到mabatis-config.xml中
            //  userList = sqlSession.selectList("mmp.UserMapper.getUserList");
                userList = sqlSession.getMapper(UserMapper.class).getUserList(user1);
                
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                MyBatisUtil.closeSqlSession(sqlSession);
            }
            for (User user:userList) {
                logger.debug("testGetUserList userCode:" + user.getUserCode()
                        + "and userName" + user.getUserName());
            }
        }
    

    最终的运行结果正常。

    使用Map入参

    在UserMapper.xml文件中增加:

        <select id="getUserListByMap" parameterType="Map" resultType="User">
            select * from smbms_user 
            where userName like CONCAT('%',#{uName},'%')
            and userRole=#{uRole}
        </select>
    

    在接口中增加方法;

    public List<User> getUserListByMap(Map<String, String> userMap);
    

    实体类构建如下:

    @Test
        public void testGetUserListByMap() {
            List<User> userList = null;
            SqlSession sqlSession = null;
            Map<String, String> userMap = new HashMap<String, String>();
            userMap.put("uName", "赵");
            userMap.put("uRole", "2");
            try {
                sqlSession = MyBatisUtil.createSqlSession();
                userList = sqlSession.getMapper(UserMapper.class).getUserListByMap(userMap);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                MyBatisUtil.closeSqlSession(sqlSession);
            }
            for (User user:userList) {
                logger.debug("testGetUserList userCode:" + user.getUserCode()
                        + "and userName" + user.getUserName());
            }
        }
    

    单元测试正常。

    3.3小结

    image.png

    四、总结

    image.png

    所以mybatis的核心就是通过核心对象sqlSession的getMapper方法获得要找的sql语句的namespace+id,然后在核心配置文件引入的xml文件中去找namespace+id对应的sql语句然后执行并返回结果。如果不使用接口的话,则直接通过sqlSession的select等方法,把sql语句的namespace+id座位参数穿进去,然后mybatis会直接去找这个sql语句。

    相关文章

      网友评论

          本文标题:五、使用MyBatis实现条件查询

          本文链接:https://www.haomeiwen.com/subject/wqvwiftx.html