MyBatis——占位符,转义字符,多元素查询(模糊查询),动态sql(多条件中多查询,多条件中单查询)

本文围绕MyBatis展开,介绍了占位符${}和#{}的使用及区别,${}无法防止SQL注入,#{}可以。还提及转义字符及CDATA的用法,阐述多元素模糊查询的三种方法,以及动态SQL在多条件中多查询和单查询的应用及解决问题的办法。

占位符:${},#{}

${}:充当占位符时,无法防止sql注入,纯纯的外面给啥,他就往上放啥
#{}:充当…,可以防止sql注入

实体类:

package com.itjh.pojo;

public class Employee {
    String name;
    Integer age;
    String gander;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGander() {
        return gander;
    }

    public void setGander(String gander) {
        this.gander = gander;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gander='" + gander + '\'' +
                '}';
    }
}
  • ${}:

Mapper文件:占位符中写上你要查询的字段名

<mapper namespace="com.itjh.mapp.EmployeeMapper">
    <select id="selectone" resultMap="employee">
        select
        *
        from farther where age = ${age}
    </select>
</mapper>

Mapper接口:在括号中定义和Mapper文件中占位符内相同的参数int age

package com.itjh.mapp;

import com.itjh.pojo.Employee;
import java.util.List;

public interface EmployeeMapper {
    List<Employee> selectone(int age);
}

测试类:在调用selectone()中加入Mapper接口需要的参数:age(测试类中先定义一个有值的age)

import com.itjh.mapp.EmployeeMapper;
import com.itjh.pojo.Employee;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestEmployee {
    public static void main(String[] args) throws IOException {
        int age=29;
        String resource = "mybatis-emplyee.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession=sqlSessionFactory.openSession();
        EmployeeMapper employeeMapper=sqlSession.getMapper(EmployeeMapper.class);
        List<Employee> list=employeeMapper.selectone(age);
        System.out.println(list);
    }
}

结果中的sql语句:

 select * from farther where age = 29

这个就是用了${}占位符,他直接把29传进来了,无法防止sql注入

  • #{}:

将Mapper文件中的sql语句中的占位符写成#{}:

<mapper namespace="com.itjh.mapp.EmployeeMapper">
    <resultMap id="employee" type="com.itjh.pojo.Employee">
        <result property="iName" column="name"></result>
    </resultMap>
    <select id="selectone" resultMap="employee">
        select
        *
        from farther where age = #{age}
    </select>
</mapper>

结果:传入参数的位置变成了?,可以防止sql注入

简概:1、传递参数时:#{}
2、对表名、列名进行动态设置只可用${}

 select * from farther where age = ?
  • paremeterType:定义传参类型(图中 int 和 integer都可以)

<mapper namespace="com.itjh.mapp.EmployeeMapper">
    <resultMap id="employee" type="com.itjh.pojo.Employee">
        <result property="iName" column="name"></result>
    </resultMap>
    <select id="selectone" parameterType="integer" resultMap="employee">
        select
        *
        from farther where age = #{age}
    </select>
</mapper>

转义字符

  • 转移字符表:如:< 无法在mybatis的xml中进行正确释义,就需要别的字符来代替它,到运行的时候,便会自动转换为 <
    ![在这里插入图片描述]在这里插入图片描述

  • CDATA:<![CDATA[ 想要写的字符 ]]>:

<mapper namespace="com.itjh.mapp.EmployeeMapper">
    <resultMap id="employee" type="com.itjh.pojo.Employee">
        <result property="iName" column="name"></result>
    </resultMap>
    <select id="selectone" parameterType="integer" resultMap="employee">
        select
        *
        from farther where age
                               <![CDATA[  <  ]]>
                           #{age}
    </select>
</mapper>

多元素查询(利用模糊查询)

如下表,想要查询所有姓,性别为的人信息:只需要对性别和姓氏做手脚即可
在这里插入图片描述
Mapper配置文件:like #{参数(与Mapper接口中方法的参数保持一致)}

<mapper namespace="com.itjh.mapp.EmployeeMapper">
    <select id="selectmany" resultType="com.itjh.pojo.Employee">
        select
        *
        from farther where
        gander like#{gander}
        and name like#{name}
    </select>
</mapper>

三种方法:

Mapper配置文件不需要动,改Mapper接口和测试类即可

在这里插入图片描述

一些名称应当注意:

在这里插入图片描述

  • Mapper接口:@Param(“1”) 2 3

1:与Mapper配置文件里面模糊查询花括号中的参数一致
2:参数类型:int String …
3:与实体类中的属性一致

package com.itjh.mapp;

import com.itjh.pojo.Employee;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface EmployeeMapper {
      List<Employee> selectmany(@Param("gander")String gander,@Param("name")String name);
}

实体类:没啥特殊的

package com.itjh.pojo;

public class Employee {
    String name;
    Integer age;
    String gander;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGander() {
        return gander;
    }

    public void setGander(String gander) {
        this.gander = gander;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gander='" + gander + '\'' +
                '}';
    }
}

测试类:定义好需要的参数的值,调用Mapper接口方法时进行传参

import com.itjh.mapp.EmployeeMapper;
import com.itjh.pojo.Employee;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestEmployee {
    public static void main(String[] args) throws IOException {
        String gander="男";
        gander="%"+gander+"%";
        String name="张";
        name=name+"%";
        String resource = "mybatis-emplyee.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession=sqlSessionFactory.openSession();
        EmployeeMapper employeeMapper=sqlSession.getMapper(EmployeeMapper.class);
        List<Employee> list=employeeMapper.selectmany(gander,name);
        System.out.println(list);
    }
}
  • 实体法:

Mapper接口文件修改一下:参数为一个实体对象

package com.itjh.mapp;

import com.itjh.pojo.Employee;
import java.util.List;

public interface EmployeeMapper {
      List<Employee> selectmany(Employee employee);
}

测试类:看代码上的注释,实体类的属性需要和接口的参数保持一致

import com.itjh.mapp.EmployeeMapper;
import com.itjh.pojo.Employee;
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 java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestEmployee {
    public static void main(String[] args) throws IOException {
    	//接收参数
        String gande="男";
        String name="张";
        //对数据加工一下,方便以后重用给上面两行代码传参就行,不用把模糊查询写死
        gande="%"+gande+"%"
        name=name+"%";
        //创建一个实体类对象,并且将上面的数据扔进去
        Employee employee=new Employee();
        employee.setName(name);
        employee.setGander(gande);

        String resource = "mybatis-emplyee.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession=sqlSessionFactory.openSession();
        EmployeeMapper employeeMapper=sqlSession.getMapper(EmployeeMapper.class);
		//接收上面已经搞好的实体类对象,返回一个集合
        List<Employee> list=employeeMapper.selectmany(employee);
        System.out.println(list);
    }
}
  • Map法:

Mapper接口文件修改一下:参数为一个Map集合

package com.itjh.mapp;

import com.itjh.pojo.Employee;
import java.util.List;

public interface EmployeeMapper {
      List<Employee> selectmany(Employee employee);
}

测试类:重点看注释

import com.itjh.mapp.EmployeeMapper;
import com.itjh.pojo.Employee;
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 java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TestEmployee {
    public static void main(String[] args) throws IOException {
    	//接收参数
        String gander="男";
        String name="张";
        //对数据加工一下,方便以后重用给上面两行代码传参就行,不用把模糊查询写死
        gander="%"+gander+"%"
        name=name+"%";
        //创造一个Map集合,用来将上面的数值扔进去,put()方法的`""`中的名称需要和
        //Mapper配置文件中的模糊查询中的参数一致
        Map map=new HashMap();
        map.put("gander",gander);
        map.put("name",name);

        String resource = "mybatis-emplyee.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession=sqlSessionFactory.openSession();
        EmployeeMapper employeeMapper=sqlSession.getMapper(EmployeeMapper.class);
        //将上面的map传进来
        List<Employee> list=employeeMapper.selectmany(map);
        System.out.println(list);
    }
}

结果的一部分:

15:35:56.462 [main] DEBUG com.itjh.mapp.EmployeeMapper.selectmany - ==>  Preparing: select * from farther where gander like? and name like?
15:35:56.500 [main] DEBUG com.itjh.mapp.EmployeeMapper.selectmany - ==> Parameters: %%(String),%(String)
15:35:56.558 [main] DEBUG com.itjh.mapp.EmployeeMapper.selectmany - <==      Total: 2
[Employee{name='张飞', age=29, gander='男'}, Employee{name='张益达', age=31, gander='男'}]

动态sql(多条件中多查询):

当Mapper配置文件写了相对应的全部字段的时候,如果你只想查询一部分条件下的东西,那么你的sql语句就会有问题,结果会报错,所以可以加入判断语句:没有传进参数的部分不会执行,if标签,其中test添加判断

<mapper namespace="com.itjh.mapp.EmployeeMapper">
    <select id="selectmany" resultType="com.itjh.pojo.Employee">
        select
        *
        from farther where
        <if test="gander!=null">
            gander like#{gander}
        </if>
        <if test="name!=null">
            and name like#{name}
        </if>
        <if test="age!=age">
            and age like#{age}
        </if>

    </select>
</mapper>

缺点:如果是第一个元素没有执行,那么第二个元素就是从and 开始,即sql语句中的where之后就是and,明显错了
解决办法:1、在where之后添加1=1即可
2、将sql语句中的where换成where标签:他会帮你写1=1并且把不必要的and去掉

<mapper namespace="com.itjh.mapp.EmployeeMapper">
    <select id="selectmany" resultType="com.itjh.pojo.Employee">
        select
        *
        from farther
        <where>
        <if test="gander!=null">
            gander like#{gander}
        </if>
        <if test="name!=null">
            and name like#{name}
        </if>
        <if test="age!=age">
            and age like#{age}
        </if>
        </where>
    </select>
</mapper>

动态sql(多条件中单查询):

前端页面上给你几个选项,你在其中选一个:用choose(when,otherwise),类似于java中的switch

<mapper namespace="com.itjh.mapp.EmployeeMapper">
    <select id="selectmany" resultType="com.itjh.pojo.Employee">
        select
        *
        from farther where
        <choose>
        <when test="gander!=null and gander!=''">
            gander like#{gander}
        </when>
        <when test="name!=null and name!=''">
            name like#{name}
        </when>
        <when test="age!=null and age!=''">
            age like#{age}
        </when>
        <otherwise>
            1=1
        </otherwise>
        </choose>
    </select>
</mapper>

其中otherwise标签可以用where标签替换:

<mapper namespace="com.itjh.mapp.EmployeeMapper">
    <select id="selectmany" resultType="com.itjh.pojo.Employee">
        select
        *
        from farther
     <where>
        <choose>
        <when test="gander!=null and gander!=''">
            gander like#{gander}
        </when>
        <when test="name!=null and name!=''">
            name like#{name}
        </when>
        <when test="age!=null and age!=''">
            age like#{age}
        </when>
        </choose>
      </where>
    </select>
</mapper>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值