MyBatis 框架的搭建及使用(二)

简介: MyBatis 框架的搭建及使用

${} 和 #{} 有啥区别 ?


通过上面结果可以看到使用 ${} 时, MySQL 执行如下 :

6dbf4c812477348af18443ad0359373e_61a31189e3a740e0855e37f54484b293.png

而使用 #{} 替代, 则是这样 :

40f620640290eeed1ccb9faaaf192c4c_31ec982ff6c04b04b9b2612f0fd04ca5.png


${} 和 #{} 都是 MyBatis 中用来替换参数的.

${} 是直接替换, 而 #{} 是预执行.

#{} 规定了在 ? 里必须是一个参数, 不能是 SQL 命令或 SQL关键字, 而 ${} 里则可以是 SQL 命令或 SQL 语句.

这也就体现了 #{} 是安全的, ${} 是不安全的, 会有 SQL 注入问题.

使用 ${} 返回的参数, 一定得要能被穷举.


使用 ${} 会出现的问题


就拿用户登录来举例, 一般来说登录都是要通过用户名和密码的 :


@Mapper  
public interface UserMapper {
    //用户登录
    Userinfo login(@Param("username")String username, 
          @Param("password")String password);
}


<?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.example.demo.dao.UserMapper">
    <select id="login" resultType="com.example.demo.model.Userinfo">
        select * from userinfo where username=${username} and password=${password}
    </select>
</mapper>


@SpringBootTest  
class UserMapperTest {
    @Test
    void login() {
        Userinfo userinfo = userMapper.login("admin","admin");
        System.out.println(userinfo.toString());
    }
}

81b9c5c1c9de469ca3fca12f720af845.png


可以看到这个 SQL 语句明显有问题, 正常写法得加上单引号 ‘admin’, 使用 #{} 则没有这个问题.

这个问题也可以解决, 通过手动加单引号就行 :


<select id="login" resultType="com.example.demo.model.Userinfo">
        select * from userinfo where username='${username}' and password='${password}'
    </select>


这样明显更繁琐了, 而且不安全, 会有 SQL 注入风险 :


@Test
    void login() {
        Userinfo userinfo = userMapper.login("admin","' or 1='1");
        System.out.println(userinfo.toString());
    }


这里通过特殊语句, 来达到非法登录的目的 :

715e6570f92d5843d8950e7f3321dfbd_ad76d19f76b1456bb8894cde05aea992.png


可以看到, 我明明没有输入正确密码, 却可以获取到用户信息, 这就是 SQL注入.


like 查询


List<Userinfo> getLikeList(@Param("username") String username);


用 数据库函数 concat 进行拼接 :


<select id="getLikeList" resultType="com.example.demo.model.Userinfo">
        select * from userinfo where
        username like concat('%',#{username},'%')
    </select>
@Test
    void getLikeList() {
        System.out.println(userMapper.getLikeList("管"));
    }

8bccacad09f147bdb3b0b3ca871561e4.png


删除操作


删除、修改、添加操作默认返回的是受影响的行数


@Mapper  
public interface UserMapper {
    //删除操作
    int delById(@Param("id") Integer id);
}


<!--这里返回类型可以省略-->
    <delete id="delById">
        delete from userinfo where id=#{id}
    </delete>


修改操作


@Mapper  
public interface UserMapper {
    //修改操作
    int update(Userinfo userinfo);
}


<update id="update">
        update userinfo set username=#{username} where id=#{id}
    </update>


@Test
    void update() {
        Userinfo userinfo = new Userinfo();
        userinfo.setId(1);
        userinfo.setUsername("管理员");
        int result = userMapper.update(userinfo);
        System.out.println("受影响的行数 : " + result);
    }

947db9d5cb8dd5fe9078d809466ce352_ee32b75120f049aebae92d18a40a012c.png

122c8d505d8992bd1fbc894457c39e57_3259cffce1c54ff0bc395240c12cb801.png


添加操作


  1. 拿到受影响的行数
//添加操作
    int add(Userinfo userinfo);
<insert id="add">
        insert into userinfo(username,password,photo)
        value(#{username},#{password},#{photo})
    </insert>


@Test
    void add() {
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("王三");
        userinfo.setPassword("123456");
        userinfo.setPhoto("/image/ddd.png");
        int result = userMapper.add(userinfo);
        System.out.println("受影响的行数 : " + result);
    }

849401e214254150aca618d65a8eb1cd.png


030b76dd553f413f9eb2c3bea194d8d5.png


  1. 拿到自增 id :


int insert(Userinfo userinfo);
<insert id="insert" useGeneratedKeys="true"
            keyColumn="id" keyProperty="id">
        insert into userinfo(username,password,photo)
        value(#{username},#{password},#{photo})
    </insert>


keyColum : 设置数据库自增主键字段名

keyProperty : 设置数据库自增 id 赋值的属性


@Test
    void insert() {
        Userinfo userinfo = new Userinfo();
        userinfo.setUsername("二哈");
        userinfo.setPassword("123456456");
        int result = userMapper.insert(userinfo);
        System.out.println("受影响的行数 : " + result + ", ID : " + userinfo.getId());
    }

4593aa20b9385a34db81606b11d77cd1_d492e7163dda42a586ffafd752ce6c7f.png


相关文章
|
5月前
|
Java 数据库连接 Maven
后端框架学习-----mybatis(使用mybatis框架遇到的问题)
这篇文章总结了在使用MyBatis框架时可能遇到的几个常见问题及其解决方法,包括配置文件注册、接口绑定、方法名匹配、返回类型匹配、Maven资源导出、时区设置和字符编码问题。
|
2月前
|
SQL Java 数据库连接
持久层框架MyBatisPlus
持久层框架MyBatisPlus
50 1
持久层框架MyBatisPlus
|
3月前
|
缓存 Cloud Native 安全
探索阿里巴巴新型ORM框架:超越MybatisPlus?
【10月更文挑战第9天】在Java开发领域,Mybatis及其增强工具MybatisPlus长期占据着ORM(对象关系映射)技术的主导地位。然而,随着技术的发展,阿里巴巴集团推出了一种新型ORM框架,旨在提供更高效、更简洁的开发体验。本文将对这一新型ORM框架进行探索,分析其特性,并与MybatisPlus进行比较。
86 0
|
5月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
5月前
|
Java 数据库连接 mybatis
mybatis框架图
文章介绍了MyBatis框架的起源、发展和其作为持久层框架的功能,提供了MyBatis的框架图以帮助理解其结构和组件。
mybatis框架图
|
5月前
|
安全 Java 数据库连接
后端框架的学习----mybatis框架(3、配置解析)
这篇文章详细介绍了MyBatis框架的核心配置文件解析,包括环境配置、属性配置、类型别名设置、映射器注册以及SqlSessionFactory和SqlSession的生命周期和作用域管理。
后端框架的学习----mybatis框架(3、配置解析)
|
5月前
|
Java 数据库连接 mybatis
后端框架的学习----mybatis框架(9、多对一处理和一对多处理)
这篇文章介绍了在MyBatis框架中如何处理多对一和一对多的关联查询,通过定义`<resultMap>`和使用`<association>`与`<collection>`元素来实现对象间的关联映射。
|
5月前
|
Java 数据库连接 测试技术
后端框架的学习----mybatis框架(8、lombok)
这篇文章介绍了如何在MyBatis框架中使用lombok库来简化Java实体类的编写,包括在IDEA中安装Lombok插件、在项目中导入lombok依赖以及在实体类上使用Lombok提供的注解。
|
5月前
|
Java 数据库连接 数据库
后端框架的学习----mybatis框架(6、日志)
这篇文章介绍了如何在MyBatis框架中使用日志功能,包括配置MyBatis的日志实现、使用log4j作为日志工具,以及如何通过配置文件控制日志级别和输出格式。
|
6月前
|
Java 数据库连接 Spring
搭建 spring boot + mybatis plus 项目框架并进行调试
搭建 spring boot + mybatis plus 项目框架并进行调试
110 4