MyBatis有参查询及动态查询

发布时间:2023年12月18日

上一篇博客中写了如何实现最简单的selectAll()查询所有的方法。下面继续说怎么实现有参查询和动态查询。

? 在说之前先说一下,数据库表中的字段名称和实体类中的属性名称不一样,则不能自动封装,就比如customer_id 和customerId。

? 解决办法:1、起别名:select customer_id as customerId.? ? 缺点:每次查询时都需要起一次别名。解决办法:用sql片段。

<!-- 一   sql片段-->
    <sql id="brand_column">
            id ,brand_name as brandName
        </sql>
    <!--    引用sql片段时 select<include refid="brand_column"/>导入 -->

sql片段缺点:不灵活。

? ? ? ? ? ? ? ? ? 2、resultMap:resultMap (1).定义<resultMap>标签;(2).在<select>标签中,使用resultMap属性代替resultType属性。

<resultMap id="brandResultMap" type="org.example.pojo.brand">
        <result column="customer_id" property="id"/>
<!--  id:完成主键字段的映射;result :完成一般字段的映射。
              column为表中的列名,property为实现类中的属性名-->
    </resultMap>

设置好resultMap后,就可以直接在<select>标签引用:

 <select id="selectAll" resultMap="brandResultMap">
        select *
        from sql_store.customers
    </select>

下面开始说带参查询:

? ? 1、根据id查询

? ? ? ? ? 先在接口方法中定义好接口

brand selectById(int id);

定义好方法后,selectById下面会有红波浪线报错,这是因为在Mapper.xml文件中找不到对应的方法,我们需要在Mapper.xml文件中声明对应的方法。我们不用手动跳转到xml文件界面然后手动输入方法,我们可以将光标停留在该方法中,然后按着 option键在按俩次回车就可以了。(我的是苹果电脑)

按一次回车后出现下面的选项,然后在按一次回车就可以自动在xml文件中生成对应的方法了。

生成对应的<select>标签后在补充完整就好了:

<select id="selectById" parameterType="int" resultMap="brandResultMap">
        select*
        from sql_store.customers
        where customer_id =#{id};
    </select>

参数占位符:1、#{}:会将其替换成?,为了防止sql注入。
2、${}:拼sql,会存在sql注入问题。
3、使用时机
参数传递的时候:#{}
表名或列名不固定的时候用${},灵活引用,但因为用${}就会存在sql注入,所以不常用。
参数类型:parameterType可以省略不写
特殊符号:就比如sql语句中where后跟的条件符号>号没问题,可<号就会报错
? ? ? ? ? ? ? ? ?1、转义字符:&lt;就是<号的意思。
? ? ? ? ? ? ? ? ? 2、CDATA区:<![CDATA[
? ? ? ? ? ? ? ? ? <
? ? ? ? ? ? ? ? ? ]]> ,把想用的符号写在中间。

?接下来是多条件查询

? ? ? ? ?1、散装查询,传入多个参数查询:

List<brand>selectByCondition(@Param("id")int id,@Param("city")String city,@Param("firstName")String first_name);

测试方法:

@Test
    public void selectByCondition() throws IOException {
        //接收参数
        int id=1;
        String city="a";
       String firstName="B";

        //手动处理参数
        city="%"+city+"%";
        firstName="%"+firstName+"%";


        //1.获取SqlSessionFactory。
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.获取sqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.获取Mapper接口的代理对象
        brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
        //4.执行方法
        List<brand> brands = brandMapper.selectByCondition(id, city, first_name);
        System.out.println(brands);

        //5.释放资源
        sqlSession.close();
    }

?

使用@Param(“sql参数占位符名称”)

? ? ? ?2、对象参数:对象属性名称要与参数占位符名称一致;?

List<brand>selectByCondition(brand brand);

将实体类作为参数传入。

测试方法:

@Test
    public void selectByCondition() throws IOException {
        //接收参数
        int id=1;
        String city="a";
       String firstName="B";

        //手动处理参数
        city="%"+city+"%";
        firstName="%"+firstName+"%";



        //封装对象
       brand brand=new brand();
       brand.setId(id);
       brand.setCity(city);
       brand.setFirstName(firstName);

        //1.获取SqlSessionFactory。
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.获取sqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.获取Mapper接口的代理对象
        brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
        //4.执行方法
        List<org.example.pojo.brand> brands = 
      brandMapper.selectByCondition(brand);
        System.out.println(brands);

        //5.释放资源
        sqlSession.close();
    }

? ?3、map集合对象:

List<brand> selectByCondition(Map map);

?测试方法:

@Test
    public void selectByCondition() throws IOException {
        //接收参数
        int id=1;
        String city="a";
       String firstName="B";

        //手动处理参数
        city="%"+city+"%";
        firstName="%"+firstName+"%";

        Map map=new HashMap();
        map.put("customer_id",id);
        map.put("city",city);
        map.put("first_name",firstName);

        //1.获取SqlSessionFactory。
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.获取sqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.获取Mapper接口的代理对象
        brandMapper brandMapper = sqlSession.getMapper(brandMapper.class);
        //4.执行方法
        List<brand> brands = brandMapper.selectByCondition(map);
        System.out.println(brands);

        //5.释放资源
        sqlSession.close();
    }

Mapper.xml文件中这样写<select>标签,like是模糊查询,比如你city输入一个字母c,那么?数据库中city列中所有包含字母c的都会被查到。

<select id="selectByCondition" resultMap="brandResultMap">
        select *
        from sql_store.customers
        where customer_id=#{id}
        and city like #{city}
        and first_name like #{firstName}
    </select>

动态多条件查询:客户可能只传入1个参数,可能传入多个参数,而且我们是不知道传入多少个参数的。

? ?这时我们可以用if标签来判断:

<select id="selectByCondition" resultMap="brandResultMap">
        select *
        from sql_store.customers
        where 
        <if test="customer_id!=null">
            customer_id=#{id}
        </if>
         <if test="city!=null and city!=''">
         and city like #{city}
    </if>
        <if test="first_name!=null and first_name!=''">
         and first_name like #{firstName}
    </if>
    </select>

问题:如果第一个if不存在,那么查询的sql语句where条件中会多一个and,sql语句会报错。
解决:1、在第一个if前加上and,然后在最开头加上一个恒等式,比如1=1

<select id="selectByCondition" resultMap="brandResultMap">
        select *
        from sql_store.customers
        where 1=1 
            <if test="customer_id!=null">
                and customer_id=#{id}
            </if>
            <if test="city!=null and city!=''">
                and city like #{city}
            </if>
            <if test="firstName!=null and firstName!=''">
                and first_name like #{firstName}
            </if>
    </select>


2、mybatis提供了<where>标签来替换where关键字

<select id="selectByCondition" resultMap="brandResultMap">
        select *
        from sql_store.customers
        <where>
            <if test="customer_id!=null">
                and customer_id=#{id}
            </if>
            <if test="city!=null and city!=''">
                and city like #{city}
            </if>
            <if test="firstName!=null and firstName!=''">
                and first_name like #{firstName}
            </if>
        </where>
    </select>

以上就是动态的多条件查询。

接下来是动态的单条件查询,查询时客户可能一个条件也不选,这样sql语句中where后就什么也没有了,sql语句会报错。

? ? ? ? ? ? ?解决:1、<choose>标签中的otherwise标签? ? ?2、<where>标签与choose标签连用

? ? choose标签:choose标签就相当于switch,其中的when标签就相当于case,otherwise标签相当于default。

 <select id="selectByConditionSingle" resultMap="brandResultMap">
         select *
         from sql_store.customers
         where
         <choose>
             <when test="id!=null ">
                 customer_id= #{id}
             </when>
             <when test="city!=null and city!=''">
                 city like #{city}
             </when>
             <when test="firstName!=null and firstName!=''">
                 first_name like #{firstName}
             </when>
             <otherwise>
                 1=1
             </otherwise>
         </choose>
     </select>

? ?where与choose标签连用:这样写就不用写otherwise标签了。

 <select id="selectByConditionSingle" resultMap="brandResultMap">
        select *
        from sql_store.customers
        <where>
            <choose>
                <when test="id!=null ">
                    customer_id= #{id}
                </when>
                <when test="city!=null and city!=''">
                    city like #{city}
                </when>
                <when test="firstName!=null and firstName!=''">
                    first_name like #{firstName}
                </when>
            </choose>
        </where>
    </select>

?

以上就是关于查询的所有东东了。

文章来源:https://blog.csdn.net/hguhbh/article/details/135045093
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。