MyBatis有参查询及动态查询

上一篇博客中写了如何实现最简单的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>

 

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

  • 18
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis中,可以使用%符号实现模糊查询。然而,直接使用%可能会引发SQL注入的问题。为了同时解决模糊查询和SQL注入的问题,可以借助MySQL的函数和MyBatis的bind标签来实现。 首先,可以使用MySQL的CONCAT()函数将多个字符串连接成一个字符串。在MyBatis的映射文件中,可以使用该函数来实现模糊查询。例如,可以使用以下语句实现模糊查询: SELECT * FROM t_role WHERE role_name LIKE CONCAT('%',#{keyword},'%') OR id LIKE CONCAT('%',#{keyword},'%') OR role_type LIKE CONCAT('%',#{keyword},'%') 另外,还可以使用MyBatis的bind标签来定义一个变量,并将模糊查询的字符串赋值给该变量。然后,在查询语句中使用该变量来实现模糊查询。例如,可以使用以下语句实现模糊查询: <bind name="pattern" value="'%' + keyword + '%'" /> SELECT * FROM t_role WHERE role_name LIKE #{pattern} OR id LIKE #{pattern} OR role_type LIKE #{pattern} 需要注意的是,在使用bind标签时,要使用${...}来引用变量,而不是使用#{...}。这是因为#{...}会将传入的数作为字符串数处理,而${...}会将传入的数直接替换到SQL语句中。 综上所述,可以通过使用MySQL的函数和MyBatis的bind标签来实现MyBatis的入模糊查询。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SSM框架的学习与应用-Java EE企业级应用开发学习记录(第五天)MyBatis的注解开发](https://download.csdn.net/download/m0_53659738/88258800)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [MyBatis模糊查询的4种实现方式](https://blog.csdn.net/shadow_zed/article/details/107929621)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [MyBatis的模糊查询多种写法](https://blog.csdn.net/qq_45802158/article/details/127183382)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值