Mybatis框架详细介绍

一、Mybatis概述

1. 框架简介

目标
  • 了解什么是框架
  • 理解框架解决的问题
讲解
1.1 什么是框架

框架是整个或部分应用的可重用设计,是可定制化的应用骨架。它可以帮开发人员简化开发过程,提高开发效率。

  • 项目里有一部分代码:和业务无关,而又不得不写的代码==>框架
  • 项目里剩下的部分代码:实现业务功能需要的逻辑代码

简而言之,框架是一个应用系统的半成品,开发人员在框架的基础上,根据业务需求开发功能。即:别人搭台,你唱戏。

1.2 框架解决了什么问题

​ 框架主要是解决了技术整合问题,实现了项目和具体技术的解耦,提升项目的可维护性

​ 一个应用系统,必定要选用大量的技术来完成业务需求,实现功能。这就导致应用系统依赖于具体的技术,一旦技术发生了变化或者出现问题,会对应用系统造成直接的冲击,这是应该避免的。

​ 框架的出现,解决了这个问题:框架是技术的整合。如果使用了框架,在框架基础上进行开发,那么开发人员就可以直接调用框架的API来实现功能,而不需要关注框架的底层具体使用了哪些技术。这就相当于框架“屏蔽”了具体的技术,实现了应用系统功能和技术的解耦。

​ 框架一般处于低层应用平台(如JavaEE)和高层业务逻辑之间
在这里插入图片描述

1.3 有哪些常见的框架

​ 每个框架都是要解决一些具体的问题的,我们可以从JavaEE的三层架构,来说一下常见的框架有哪些。
在这里插入图片描述

Mybatis:
  • 框架职责:作用在dao层,负责数据库访问的框架。

  • 框架介绍:

    它原本是Apache的一个开源项目ibatis,后来迁移到了Google code,并改名为Mybatis;之后又迁移到了github上。

    它是一个优秀的Java轻量级dao层框架,对JDBC进行了封装,使开发人员只需要关注SQL语句,而不需要关注JDBC的API执行细节。

Hibernate:
  • 框架职责:作用在dao层,负责数据库访问的框架。

  • 框架介绍:

    Hibernate是一个完全面向对象的Dao层框架,封装程度非常高,开发人员可以完全以面向对象的方式操作数据库,甚至不需要编写SQL语句。

    但是,正因为Hibernate的封装程度过高,导致它的执行效率受到了影响,是重量级框架。目前在国内使用的越来越少了。

SpringMVC:
  • 框架职责:作用在web层,负责和客户端交互的框架。

  • 框架介绍:

    SpringMVC是Spring Framework的后续产品,受益于Spring框架的流行,并且因为SpringMVC使用简单、和Spring整合简单,导致SpringMVC框架在国内使用的也越来越多。

Struts1/Struts2:
  • 框架职责:作用在web层,负责和客户端交互的框架。

  • 框架介绍:

    Struts1是比较老的框架,目前已经基本不使用了。

    Struts2目前使用的也越来越少,逐步被SpringMVC代替

Spring:
  • 框架职责:不是作用在某一层,而是实现web层、Service层、Dao层之间解耦的框架,是三层之间的粘合剂
  • 框架介绍:Spring框架是为了解决应用开发的复杂性而创建的,任何Java应用都可以从Spring中受益。Spring是一个轻量级控制反转(IOC)和面向切面(AOP)的容器框架。

2. Mybatis简介

目标
  • 理解为什么要使用Mybatis
讲解

dao层常用的技术如下图所示:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-emit2jnS-1638773631190)(img/ORM思想和持久层框架-1605268232622.png)]

2.1 JDBC的问题

JDBC是操作数据库的最基本的规范,它的功能简单单一,在使用时需要开发人员处理很多问题:

  1. 硬编码问题
  2. 大量的重复代码
  3. 性能问题
  4. JavaBean和表数据的映射转换问题
2.2 ORM思想【面试】

​ ORM:Object Relation Mapping,对象关系映射思想。指把Java对象和数据库的表的字段进行关联映射,从而达到操作Java对象,就相当于操作了数据库。查询了数据库,自动封装成JavaBean对象

  • 关系—>对象: 查询表数据,ORM框架自动帮我们把结果封装成JavaBean对象
  • 对象—>关系: 插入数据、修改数据等等,ORM框架自动帮我们把JavaBean对象转换成对应的SQL语句

常见的ORM框架:

  • Hibernate:是完全ORM框架,实现了双向映射。简单功能更简单,复杂功能更复杂
    • 关系—>对象:查询不用写SQL,也不用自己封装JavaBean
    • 对象—>关系:DML也不用写DQL
  • Mybatis:是半ORM框架,只实现了单向映射
    • 关系—>对象:查询不用自己封装JavaBean
    • 对象—>关系:没有实现,还需要我们自己编写SQL语句
2.3 Mybatis介绍

​ Mybatis是一个优秀的Java轻量级持久层框架。apache的ibatis,后来托管到google code,后来又迁移到github上。 Mybatis官网:http://www.mybatis.org/mybatis-3/zh/index.html

  • 它内部封装了JDBC,使开发人员只需要关心SQL语句,而不需要处理繁琐的JDBC步骤
  • 它采用了ORM思想(半ORM),解决了实体和数据库映射的问题。只要提供好sql语句,配置了映射,Mybatis会自动根据参数值动态生成SQL,执行SQL并把结果封装返回给我们。
  • 它支持XML和注解两种方式配置映射。
小结
  • ORM:对象-关系映射思想。表示一个JavaBean对象,要对应表里的一行数据。
    • 关系->对象的映射:从表里查询数据,由框架帮我们自动封装成JavaBean对象
    • 对象->关系的映射:把JavaBean里的数据存储到表里时,由框架帮我们自动把JavaBean的属性值,设置到表里对应的字段上
  • Hibernate是一个全ORM框架,实现了双向的自动映射。如果使用Hibernate,简单功能不需要写SQL。复杂功能需要再学习一套HQL语言
  • Mybatis是一个半ORM框架,只实现了"关系->对象"的自动映射。如果使用Mybatis框架,需要自己编写SQL

Mybatis

  • JDBC的基本使用:Statement

    //1. 注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    //2. 获取连接
    Connection conn = DriverManager.getConnection("jdbc:mysql:///day04","root","root");
    //3. 创建SQL执行平台
    Statement statement = conn.createStatement();
    //4. 执行SQL语句
    ResultSet resultSet = statement.executeQuery(String sql);
    int count = statement.executeUpdate(String sql);
    boolean isQuery = statement.execute(String sql);
    //5. 处理结果
    while(resultSet.next()){
        resultSet.getXxx(列序号);
        resultSet.getXxx(列名称);
    }
    //6. 释放资源
    resultSet.close();
    statement.close();
    connection.close();
    
  • SQL注入漏洞

    通过构造特殊的参数值,可以修改SQL语句的结构,绕过SQL的一些条件

    可以使用预编译对象解决SQL注入漏洞

  • JDBC的预编译对象:PreparedStatement

    可以解决SQL注入漏洞:更安全

    程序可读性更高

    同一SQL多次执行时,性能更强

    //1. 注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    //2. 获取连接
    Connection conn = DriverManager.getConnection("jdbc:mysql:///day04","root","root");
    //3. 创建SQL执行平台
    PreparedStatement statement = conn.prepareStatement("select * from user where id = ?");
    //4. 执行SQL语句
    statement.setInt(1, 1);
    ResultSet resultSet = statement.executeQuery();
    int count = statement.executeUpdate();
    boolean isQuery = statement.execute();
    //5. 处理结果
    while(resultSet.next()){
        resultSet.getXxx(列序号);
        resultSet.getXxx(列名称);
    }
    //6. 释放资源
    resultSet.close();
    statement.close();
    connection.close();
    
  • JDBC事务管理

    try{
        //1. 注册驱动
        //2. 获取连接
        //===开启事务===
        connection.setAutoCommit(false);
        //3. 创建SQL执行平台
        //4. 执行SQL语句
        //5. 处理结果
        //===提交事务===
        connection.commit();
    }catch(Exception e){
        //===回滚事务===
    }finally{
        //6. 释放资源
    }
    
  • 连接池

    • 为什么要使用连接池:连接可以复用,少量连接就可以支持海量的数据库操作;性能更强

    • JDBC规范规定了,所有连接池都必须实现的接口是:javax.sql.DataSource,获取连接的方法是getConnection()

    • druid连接池的使用

      1. 导入jar包:数据库驱动包,连接池的包
      2. 提供配置文件:xxx.properties,放到src下
      3. 编写代码使用连接池
      //1. 创建连接池对象
      DataSource ds = DruidDataSourceFactory.createDataSource(properties);
      //2. 从连接池里获取连接
      Connection connection = ds.getConnection();
      //   按照JDBC的步骤操作数据库
      //最后:释放资源:close()方法的作用是归还到连接池
      connection.close();
      

二、快速入门

需求描述

查询所有用户信息,获取用户集合List<User>

准备工作

1 统一开发环境
  1. 初始化数据库:执行数据库脚本《资料/mybatisdb.sql》
  2. 准备开发环境:jdk1.8, mysql5.7, idea2018
2 实现步骤
  1. 创建Java项目,准备JavaBean
  2. 编写Mybatis的代码,查询所有用户
  3. 编写测试代码

入门案例

1 创建Java项目,准备JavaBean
1) 创建java项目,导入jar包在这里插入图片描述
2) 创建JavaBean
  • 注意:JavaBean里的成员变量,尽量使用包装类,而不是基本数据类型。因为基本数据类型不支持null值
package com.demo.domain;

import java.util.Date;

/**
 * 一张表,要创建一个对应的实体类
 * 实体类里的属性,要和表里的字段一一对应
 * 实体类属性类型,建议使用包装类,而不是基本数据类型
 * 建议JavaBean的属性名 和 表的字段名保持一致
 *
 */
public class User {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    //get/set方法...
    //toString方法...
}
2 编写Mybatis的代码,查询所有用户
1) 创建dao接口(映射器)
  • 什么是映射器:dao层的接口,叫映射器。不需要实现类
  • 映射器的名称:XXXDaoXXXMapper
package com.demo.dao;

import com.demo.domain.User;

import java.util.List;

/**
 * 使用Mybatis操作数据库的步骤:
 *      1. 在dao包里创建一个接口。只要接口,不要实现类;在接口里定义方法
 *          这个接口叫“映射器”。XxxDao,XxxMapper
 *      2. 给每个接口创建一个xml配置文件:里边要给方法配置SQL语句
 *          名称:要和映射器接口名称相同
 *          位置:要和映射器接口放在一起
 *      3. 创建一个全局配置的xml文件:主要配置数据源
 *          名称:随意。习惯性命名为SqlMapConfig.xml。也可以任意命名mybatis.xml
 *          位置:建议放到src下
 */
public interface UserDao {

    /**
     * 查询所有用户,得到List<user>
     */
    List<User> queryAll();
}
2) 准备映射文件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">
<!--
mapper标签:表示是给一个映射器接口做配置的
namespace属性:写映射器接口的全限定类名,表示给哪个映射器接口配置的
-->
<mapper namespace="com.itheima.dao.UserDao">
    <!--
    给映射器接口里每个方法,都要有一个对应的配置===statement
     select标签:用于配置查询语句
     insert标签:用于配置插入语句
     update标签:用于配置修改语句
     delete标签:用于配置删除语句

        id属性:写方法名
        resultType属性:查询结果集里每一行,要封装成什么对象,写全限定类名
    -->
    <select id="queryAll" resultType="com.itheima.domain.User">
        select * from user
    </select>
</mapper>
3) 准备Mybatis的日志配置文件

Mybatis支持使用log4j输出执行日志信息,但是需要我们提供log4j的配置文件放在src下:log4j.properties

注意:

  1. 如果没有log4j.properties,不影响Mybatis的功能,只是没有详细日志而已
  2. 如果需要日志的话,要把log4j.properties文件放到类路径(src)下。log4j.properties内容如下:
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE, LOGFILE        debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
4) 准备Mybatis的全局配置文件xml
  • 什么是全局配置文件:要使用Mybatis,必须提供的一个核心配置。只需要一个全局配置即可
  • 全局配置文件的要求:
    • 名称随意,我们这里叫SqlMapConfig.xml
    • 位置随意,我们这里为了方便读取,放到src
  • 全局配置文件里必须有的配置:
    • environments:用于配置数据库环境
    • mappers:用于配置所有的映射器
<?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>

    <!--配置数据源。default:默认要启用的数据库,写对应environment标签的id值-->
    <environments default="heima12">
        <!--一个environment标签,可以配置一个数据源-->
        <environment id="heima12">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis12?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
        <!--<environment id="abc">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///day04?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>-->
    </environments>

    <!--所有映射xml文件的位置-->
    <mappers>
        <!--写xml文件的路径。每个xml都要用一个mapper标签配置进来。-->
        <mapper resource="com/itheima/dao/UserDao.xml"/>
    </mappers>
</configuration>
3 编写测试代码
package com.demo;

import com.demo.dao.UserDao;
import com.demo.domain.User;
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.Test;

import java.io.InputStream;
import java.util.List;

/**
 * 测试UserDao的功能
 */
public class UserDaoTest {

    @Test
    public void testStart() throws Exception {
        //1. 加载配置文件
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

        //2. 得到一个SqlSession对象:
        //使用SqlSessionFactoryBuilder构造一个SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //使用SqlSessionFactory生产一个SqlSession对象
        SqlSession session = factory.openSession();

        //3. 获取UserDao代理对象;使用UserDao代理对象操作数据库
        UserDao userDao = session.getMapper(UserDao.class);
        List<User> userList = userDao.queryAll();
        userList.forEach(System.out::println);

        //4. 释放资源
        session.close();
        is.close();
    }
}
Mybatis使用步骤

准备工作:导入jar包,创建JavaBean

使用Mybatis的步骤:

  1. 先创建dao层的接口(映射器):只要接口,不要实现类。名称通常是:XxxDao, XxxMapper
  2. 给每个dao接口创建一个xml文件(映射配置文件,映射文件):给接口里的方法配置SQL语句
  3. 创建全局配置的xml文件:名称随意,位置建议放在src下。主要是配置数据源

三、单表CURD

目标

能够使用Mybatis实现单表的curd操作:

  • 查询全部用户,得到List<User>
  • 根据主键查询一个用户,得到User
  • 查询数量
  • 保存用户(新增用户)
  • 修改用户
  • 删除用户
  • 模糊查询

准备

  1. 实体类User:略

  2. 映射器接口UserDao:

    package com.itheima.dao;
    
    import com.itheima.domain.User;
    
    import java.util.List;
    
    /**
     * 如果你的Mybatis环境已经搭建环境,编写功能时,只需要:
     *      1. 在dao接口里写方法
     *      2. 在接口配置文件里写SQL语句
     *
     * 功能需求:
     * - 查询全部
     * - 根据主键查询一个用户,得到`User`
     * - 查询数量
     * - 保存用户(新增用户)
     * - 修改用户
     * - 删除用户
     * - 模糊查询
     * @author liuyp
     * @date 2021/09/05
     */
    public interface UserDao {
        List<User> queryAll();
    }
    
  3. 映射配置文件UserDao.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">
    <mapper namespace="com.itheima.dao.UserDao">
    
        <select id="queryAll" resultType="com.itheima.domain.User">
            select * from user
        </select>
        
    </mapper>
    
  4. 单元测试类

    在单元测试类中准备好@Before、@After的方法代码备用。

    后续要测试一个功能,就增加一个@Test方法即可。

    package com.demo;
    
    import com.demo.dao.UserDao;
    import com.demo.domain.User;
    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.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Date;
    import java.util.List;
    
    /**
     * Junit的注解:
     *  1. @Test:加在方法上,方法可以直接运行。要求方法必须是public, void, 无参
     *  2. @Before:加在方法上,这个方法会在每个Test方法执行之前,先执行一次
     *  3. @After:加在方法上,这个方法会在每个Test方法执行之后,再执行一次
     *
     * 增删改查功能测试
     */
    public class CurdTest {
        private UserDao userDao;
        private SqlSession session;
        private InputStream is;
    
        @Test
        public void testQueryAll(){
            List<User> userList = userDao.queryAll();
            for (User user : userList) {
                System.out.println(user);
            }
        }
    
    
        /**
         * ctrl + alt + f:把选中的变量,提取成Field(成员变量)
         * ctrl + alt + v:把选中的内容,提取成一个Variable(变量)
         * ctrl + alt + m:把选中的内容,提取成一个Method(方法)
         */
        @Before
        public void init() throws IOException {
            //1. 先加载全局配置文件
            is = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2. 再得到一个SqlSession对象。这个对象一定是随用随取,用完就关,一定要关
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
            session = factory.openSession();
            //3. 可以获取dao接口的代理对象
            userDao = session.getMapper(UserDao.class);
        }
    
        @After
        public void destroy() throws IOException {
            //4. 释放资源
            session.close();
            is.close();
        }
    }
    

实现

3.1 根据主键查询一个用户
  1. 在映射器UserDao里加方法
/**
 * 根据主键查询一个用户
 * @param id 用户id
 * @return 得到`User`
 */
User findById(Integer id);
  1. 在映射文件UserDao.xml里加statement配置
<!--
select标签:用于配置查询语句
    id:方法名称
    parameterType:参数的类型,可省略不写
    resultType:查询结果集中,每一行数据要封装成什么对象,写全限定类名

SQL语句的写法:
    Mybatis里的SQL语句,如果有参数,不能写?,要写成  #{}
    SQL语句中#{}用于取参数值
    	如果只有一个参数并且是简单类型,SQL语句里要取参数值,写:#{随意写}
    	简单类型:8种基本数据类型及包装类, String
    -->
<select id="findById" resultType="com.itheima.domain.User">
    select * from user where id = #{abc}
</select>
  1. 功能测试:在测试类里加测试方法
@Test
public void testFindById(){
    User user = userDao.findById(41);
    System.out.println(user);
}
3.2 查询数量(聚合函数)
  1. 在映射器UserDao里加方法
    /**
     * 查询数量
     * @return user表里的总数量
     */
    int count();
  1. 在映射文件UserDao.xml里配置statement
<select id="count" resultType="int">
    select count(*) from user
</select>
  1. 功能测试,在单元测试类里加测试方法
@Test
public void testCount(){
    int count = userDao.count();
    System.out.println("user表的数据量:" + count);
}
3.3 保存/新增用户
  1. 在映射器UserDao里加方法
    /**
     * 保存用户(新增用户)
     * @param user 要保存的用户信息对象
     */
    void save(User user);
  1. 在映射文件UserDao.xml里配置statement
    <!--
	使用insert标签配置insert语句

    如果方法有查询参数,标签上要加parameterType,写参数的全限定类名。
        但是这个属性可以省略;如果省略了,Mybatis会自动推断参数类型

    如果参数是JavaBean,SQL语句里取参数值: #{JavaBean的属性名}

    如果要插入数据之后,得到最新的主键值,直接修改配置文件即可:
        在insert标签里增加子标签selectKey
        resultType:查询得到的主键值是什么类型的
        keyProperty:查询得到的主键值,要存储到JavaBean对象哪个属性上,写属性名
        order:要在insert之前查询主键值,还是在insert之后查询主键值
            MySql数据库,要求是AFTER
            Oracle数据库,要求是BEFORE
    -->
<insert id="save" parameterType="com.itheima.domain.User">
    <selectKey resultType="int" keyProperty="id" order="AFTER">
        select last_insert_id()
    </selectKey>
    INSERT INTO USER (username, birthday, sex, address)
    VALUES (#{username}, #{birthday}, #{sex}, #{address})
</insert>
  1. 在测试类里加测试方法
@Test
public void testSave(){
    User user = new User();
    user.setUsername("4哥");
    user.setSex("男");
    user.setAddress("宿迁");
    user.setBirthday(new Date());

    int i = userDao.save(user);
    System.out.println("影响行数:" + i);

    //注意:使用Mybatis执行完DML操作之后,一定要提交事务
    session.commit();

    //要求:插入数据之后,可能够得到新数据的id值
    System.out.println("保存后:" + user);
}
  • 注意:
    • SQL语句里#{JavaBean的属性名}
    • 执行完DML语句,不要忘记提交事务
    • 如果插入数据时要获取最新的主键值,就在insert里增加子标签selectKey
3.4 修改用户
  1. 在映射器接口里加方法
/**
 * 修改用户
 * @param user 要修改的用户信息
 */
void edit(User user);
  1. 在映射文件里配置statement
<update id="edit" parameterType="com.itheima.domain.User">
    UPDATE USER SET
        username = #{username},
        birthday = #{birthday},
        sex = #{sex},
        address = #{address}
    WHERE id = #{id}
</update>
  1. 在测试类里添加测试方法
@Test
public void testEdit(){
    User user = userDao.findById(50);
    user.setSex("女");
    user.setUsername("2姐");

    userDao.edit(user);
    session.commit();
}
  • 注意事项:
    • 执行了DML语句,需要提交事务sqlSession.commit()
    • SQL语句里使用#{JavaBean的属性名}
3.5 删除用户
  1. 在映射器接口里加方法
    /**
     * 删除用户
     * @param id 要删除的用户id
     */
    void delete(Integer id);
  1. 在映射文件UserDao.xml里配置statement
<delete id="delete" parameterType="int">
    delete from user where id = #{abc}
</delete>
  1. 在测试类里增加测试方法
@Test
public void testDelete(){
    userDao.delete(50);
    session.commit();
}
  • 注意事项:
    • 执行完DML语句,需要提交事务sqlSession.commit()
    • SQL语句里: 只有一个参数并且是简单类型,#{随便写}
3.6 模糊查询
1 使用#{}方式进行模糊查询
  1. 在映射器UserDao里加方法
/**
     * CURD功能-模糊查询。
     * 使用#{}方式
     */
List<User> search(String username);
  1. 在映射文件UserDao.xml里配置statement

    利用了MySql的特殊拼接字符串的语法

    • select '%' '王' '%',得到的结果是'%王%'
    • select "%"'王'"%",得到的结果是'%王%'
<select id="search" parameterType="String" resultType="User">
    select * from user where username like "%"#{abc}"%"
</select>
  1. 在测试类里加测试方法
@Test
public void testSearch(){
    List<User> list = userDao.search("王");
    for (User user : list) {
        System.out.println(user);
    }
}
2 使用${}方式进行模糊查询
  1. 在映射器接口里加方法
/**
     * CURD功能-模糊查询
     * 使用${}方式
     */
List<User> search2(String username);
  1. 在映射文件UserDao.xml里配置statement
<select id="search2" parameterType="String" resultType="User">
    select * from user where username like '%${value}%'
</select>
  1. 在测试类里加测试方法
@Test
public void testSearch(){
    // List<User> list = userDao.search("王");
    List<User> list = userDao.search2("王");
    for (User user : list) {
        System.out.println(user);
    }
}
3 #{}${}的区别
  • #{}:本质是预编译方式执行SQL
    • 可以防止SQL注入漏洞
    • 如果只有一个参数,并且是简单类型,#{}里边可以随意写#{abc}
    • Mybatis会自动进行Java类型和JDBC类型的转换
  • ${}:本质是拼接SQL语句字符串
    • 不能防止SQL注入漏洞
    • 如果只有一个参数,并且是简单类型,${}只能写成value===>${value} (最新版本Mybatis里也可以随便写,但是仍然建议写成${value}
    • 不会进行Java类型和JDBC类型转换。Mybatis会把参数值toString()后,直接拼接到SQL语句里

有错误大家指正,共同进步,共同学习。

  • 15
    点赞
  • 107
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一切如你i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值