11. Mybatis 的增删查改【万字详解】

这篇具有很好参考价值的文章主要介绍了11. Mybatis 的增删查改【万字详解】。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1. 数据的查找 select

1.1 查询所有数据

1.2 通过 id 进行查找

2. 插入数据 insert

3. 修改数据 update

4. 删除数据 delete

5. $ 和 # 的区别

5.1 SQL 注入 用户登录

6. Spring Boot 打印 SQL 日志

7. order by 排序

8. like 查询

9. 通过页面返回数据

10. 总结


在上篇文章中我们介绍了 mybatis 的相关概念,通过 mybatis 对数据库中的数据进行查找,接下来我们将具体的介绍 Mybatis 的增删查改。

同时本篇文章还详细介绍了 $ 和 # 的区别(重点)。

1. 数据的查找 select

1.1 查询所有数据

通过 workbench,我们可以看到数据库中的现有数据:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

 接下来我们在 UserMapper.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.example.demo.mapper.UserMapper">
    <select id="queryAll" resultType="com.example.demo.model.User">
        select * from userinfo
    </select>
</mapper>

接下来在 UserMapper 类中添加查找方法: 

@Mapper
public interface UserMapper {
    List<User> queryAll();
}

在上述类的方法中右键,选择生成,选择测试,即可生成测试类。接下来,在 UserMapperTest 类中进行自测: 

@Slf4j
@SpringBootTest
class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    void queryAll() {
        List<User> users = userMapper.queryAll();
        log.info(users.toString());
    }
}

运行结果如下图所示,可以看到查找到了数据库中现有的所有数据: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

1.2 通过 id 进行查找

首先,我们在 UserMapper.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.example.demo.mapper.UserMapper">
    <select id="queryAll" resultType="com.example.demo.model.User">
        select * from userinfo
    </select>
    <select id="queryById" resultType="com.example.demo.model.User">
        select * from userinfo where id = ?
    </select>
</mapper>

接下来在 UserMapper 类中添加查找方法: 

@Mapper
public interface UserMapper {
    // 查询所有数据
    List<User> queryAll();
    // 通过 id 查询数据
    User queryById(@Param("uid") Integer id);
}

 在上述类的方法中右键,选择生成,选择测试,生成测试类:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

 可以看到生成的测试类中包含以下方法:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来,我们编写测试的代码:

@Slf4j
@SpringBootTest
class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    void queryAll() {
        List<User> users = userMapper.queryAll();
        log.info(users.toString());
    }

    @BeforeEach
    void setUp() {
        log.info("before...");
    }

    @AfterEach
    void tearDown() {
        log.info("after...");
    }

    @Test
    void queryById() {
        log.info("queryById...");
        User user = userMapper.queryById(1);
        log.info(user.toString());
    }
}

运行结果如下: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

需要注意的是,当我们只有一个参数时,可以不写注解;但是写了注解时,SQL 语句需要和注解中使用的参数保持一致

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

当只有一个参数时,不仅可以不写参数,参数的名称也可以不同,以下两条语句均可以成功执行:

User queryById(Integer id);
User queryById(Integer aaa);

2. 插入数据 insert

我们先来看一下数据库中都有哪些数据:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

可以看到 id 是自增的,createtime 和 updatetime 都是当前时间,因此我们在插入数据时不用添加。

接下来我们在 UserMapper.xml 文件中添加以下内容:

<insert id="insert">
        insert into userinfo (username,password,photo)values(#{username},#{password},#{photo})
</insert>

在 UserMapper 类中添加插入方法: 

@Mapper
public interface UserMapper {
    // 查询所有数据
    List<User> queryAll();
    // 通过 id 查询数据
    User queryById(@Param("uid") Integer id);
    // 插入数据
    Integer insert(User user);
}

在上述类的方法中右键,选择生成,选择测试,即可生成测试类,编写测试方法:

@Slf4j
@SpringBootTest
class UserMapperTest {
    @Autowired
    private UserMapper userMapper;
    @Test
    void queryAll() {
        List<User> users = userMapper.queryAll();
        log.info(users.toString());
    }

    @BeforeEach
    void setUp() {
        log.info("before...");
    }

    @AfterEach
    void tearDown() {
        log.info("after...");
    }

    @Test
    void queryById() {
        log.info("queryById...");
        User user = userMapper.queryById(1);
        log.info(user.toString());
    }

    @Test
    void insert() {
        User user = new User();
        user.setUsername("Danny");
        user.setPassword("123456");
        user.setPhoto("123");
        Integer result = userMapper.insert(user);
        log.info("insert result:"+ result);
    }
}

接下来,在 UserMapperTest 类中进行自测: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

 在 workbench 中可以看到数据插入成功:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis


还可以通过第二种方法插入数据:

Integer insert2(@Param(("userinfo")) User user);
 <insert id="insert2">
        insert into userinfo (username,password,photo)values(#{userinfo.username},#{userinfo.password},#{userinfo.photo})
 </insert>

 添加测试方法:

 @Test
    void insert2() {
        User user = new User();
        user.setUsername("Danny");
        user.setPassword("123456");
        user.setPhoto("123");
        Integer result = userMapper.insert2(user);
        log.info("insert result:"+ result);
    }

可以看到,同样能够运行成功:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

需要注意的是,如果使用了 @Param 注解,就必须使用 @Param 注解的命名

获取自增 id

在 UserMapper.xml 文件中添加以下内容:

<insert id="insert2" useGeneratedKeys="true" keyProperty="id">
        insert into userinfo (username,password,photo)values(#{userinfo.username},#{userinfo.password},#{userinfo.photo})
    </insert>

在 UserMapperTest 类中添加以下内容:

@Test
    void insert2() {
        User user = new User();
        user.setUsername("Danny");
        user.setPassword("123456");
        user.setPhoto("123");
        Integer result = userMapper.insert2(user);
        log.info("insert result:"+ result + ", 自增id:" + user.getId());
    }

此时可以看到自增 id 为:5. 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

3. 修改数据 update

在修改数据库的数据之前,我们先来看一下此时数据库中的数据:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来我们修改 id = 3 的这行数据:

在 UserMapper.xml 文件中添加以下内容:

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

在 UserMapper 类中添加修改方法:

@Mapper
public interface UserMapper {
    // 查询所有数据
    List<User> queryAll();
    // 通过 id 查询数据
    User queryById(@Param("uid") Integer id);
    // 插入数据
    Integer insert(User user);
    Integer insert2(@Param(("userinfo")) User user);
    // 修改数据
    void update(User user);
}

在上述类的方法中右键,选择生成,选择测试,即可生成测试类,编写测试方法:

 @Test
    void update() {
        User user = new User();
        user.setId(3);
        user.setUsername("Jenny");
        user.setPassword("root123456");
        userMapper.update(user);
    }

接下来,在 UserMapperTest 类中进行自测: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

运行成功后,可以看到数据库中 id =3 这一行的数据已经被修改了:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

4. 删除数据 delete

我们先来看一下此时数据库中的数据:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来我们删除 id = 4 的这行数据:

在 UserMapper.xml 文件中添加以下内容:

<delete id="delete">
        delete from userinfo where id = #{id}
    </delete>

在 UserMapper 类中添加修改方法: 

@Mapper
public interface UserMapper {
    // 查询所有数据
    List<User> queryAll();
    // 通过 id 查询数据
    User queryById(@Param("uid") Integer id);
    // 插入数据
    Integer insert(User user);
    Integer insert2(@Param(("userinfo")) User user);
    // 修改数据
    void update(User user);
    // 通过 id 删除数据
    void delete(Integer id);
}

在上述类的方法中右键,选择生成,选择测试,即可生成测试类,编写测试方法:

 @Test
    void delete() {
        userMapper.delete(4);
    }

接下来,在 UserMapperTest 类中进行自测: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

运行成功后,可以看到数据库中 id =4 这一行的数据已经被删除了:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

5. $ 和 # 的区别

我们将通过 id 查询的 xml 文件中的 # 改成 $:

 <select id="queryById" resultType="com.example.demo.model.User">
        select * from userinfo where id = ${uid}
    </select>

可以看到依然可以查询到数据: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来我们使用 # 通过名称来查询:

User queryByName(String name);
 <select id="queryByName" resultType="com.example.demo.model.User">
        select * from userinfo where username = #{username}
    </select>
@Test
    void queryByName() {
        log.info("queryByName...");
        User user = userMapper.queryByName("Jenny");
        log.info(user.toString());
    }

可以看到成功查询到数据: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来我们使用 $ 通过名称来查询:

修改 xml 文件:

<select id="queryByName" resultType="com.example.demo.model.User">
        select * from userinfo where username = ${username}
    </select>

运行代码后出现以下报错:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

是因为 $ 符号传递的参数是没有加引号,直接放在参数中的

那么,如果我们自行添加引号呢?

<select id="queryByName" resultType="com.example.demo.model.User">
        select * from userinfo where username = '${username}'
    </select>

此时我们可以看到成功运行了: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

综上,我们来看一下其中的本质原因:

  • #{} :预编译处理(占位)
  • ${}:字符直接替换(字符的内容直接当作 SQL 的一部分来运行,SQL 注入影响程序的安全

 当我们执行以下 SQL 语句时,会发现数据库中的所有数据都被查出来了:

SELECT * FROM userinfo where username = '' or 1 = '1'

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

5.1 SQL 注入 用户登录

我们先在数据库中保留以下信息:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

我们先来测试 # 正确查询:

<select id="queryByNameAndPassword" resultType="com.example.demo.model.User">
        select * from userinfo where username = #{username} and password = #{password}
    </select>
User queryByNameAndPassword(@Param("username") String username,@Param("password") String password);
 @Test
    void queryByNameAndPassword() {
        String username = "admin";
        String password = "admin";
        User user = userMapper.queryByNameAndPassword(username,password);
        log.info(user.toString());
    }

可以看到查询成功: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

再来测试 # 错误查询,直接修改测试方法:

@Test
    void queryByNameAndPassword() {
        String username = "admin";
        String password = "admin123";
        User user = userMapper.queryByNameAndPassword(username,password);
        log.info(user==null?null:user.toString());
    }

可以看到查询为空:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来测试 SQL 注入的情况:

@Test
    void queryByNameAndPassword() {
        String username = "admin";
        String password = "'or 1 ='1";
        User user = userMapper.queryByNameAndPassword(username,password);
        log.info(user==null?null:user.toString());
    }

可以看到使用错误的 password 显示为 null ,数据没有被查询出来:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis


接下来测试 $ 正确查询:

<select id="queryByNameAndPassword" resultType="com.example.demo.model.User">
        select * from userinfo where username = '${username}' and password = '${password}'
    </select>
@Test
    void queryByNameAndPassword() {
        String username = "admin";
        String password = "admin";
        User user = userMapper.queryByNameAndPassword(username,password);
        log.info(user==null?null:user.toString());
    }

可以看到成功查询到: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来我们输入错误的 password :

@Test
    void queryByNameAndPassword() {
        String username = "admin";
        String password = "admin123";
        User user = userMapper.queryByNameAndPassword(username,password);
        log.info(user==null?null:user.toString());
    }

可以看到没有查询到数据,显示为 null: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来我们来看 SQL 注入的情况:

@Test
    void queryByNameAndPassword() {
        String username = "admin";
        String password = "'or 1 ='1";
        User user = userMapper.queryByNameAndPassword(username,password);
        log.info(user==null?null:user.toString());
    }

 可以看到数据仍然被查询出来了:11. Mybatis 的增删查改【万字详解】,java ee,mybatis

那么 SQL 注入简单来说就是将本来不该被查询出来的数据,查询出来了。

6. Spring Boot 打印 SQL 日志

添加配置文件:

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

可以看到直接将对应的 SQL 语句打印在了控制台:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

以上就是 $ 打印的结果,是直接进行替换了。

接下来我们看一下 # 打印的结果:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

所以,# 就是进行预编译,采用占位的方式。

7. order by 排序

我们先来看一下此时数据库中的数据:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来我们根据 id 进行降序排列:

List<User> queryByOrder(String order);
<select id="queryByOrder" resultType="com.example.demo.model.User">
        select * from userinfo order by id #{order}
    </select>
@Test
    void queryByOrder() {
        List<User> users = userMapper.queryByOrder("desc");
        log.info(users.toString());
    }

我们可以看到运行之后的结果并没有像我们想象之中的那样降序排列,而是直接报错:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

那么上述这种情况下,就无法使用 # 必须使用 $ 符号才可以。

所以排序时只能使用 $。

修改 xml 文件:

 <select id="queryByOrder" resultType="com.example.demo.model.User">
        select * from userinfo order by id ${order}
    </select>

此时可以看到成功进行了降序排列:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

但是只要使用了 $ 就存在 SQL 注入的问题,该如何解决呢?

要从根源上解决以上问题就是不让用户输入 SQL 语句,用户只能点击,参数由后端进行拼接,后端在查询之前,对参数进行校验,只能传两个值:desc(降序) 和 asc(升序)。

8. like 查询

我们先来看一下 SQL 语句的 like 查询:

SELECT * FROM userinfo where username like "%m%";

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来我们使用 # 来查询: 

List<User> queryByLike(String name);
<select id="queryByLike" resultType="com.example.demo.model.User">
        SELECT * FROM userinfo where username like '%#{name}%';
    </select>
@Test
    void queryByLike() {
        List<User> users = userMapper.queryByLike("m");
        log.info(users.toString());
    }

可以看到无法正确查询: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

接下来我们改成 $ 进行查询:

 <select id="queryByLike" resultType="com.example.demo.model.User">
        SELECT * FROM userinfo where username like '%${name}%';
    </select>

此时,我们可以看到查询到了数据: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

但是使用了 $ 就存在 SQL 注入的问题,因此我们需要使用 MySQL 的一个内置函数。

SELECT * FROM userinfo where username like concat('%','m','%');

可以看到使用以上 SQL 语句也可以进行查询: 

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

因此,我们修改 xml 文件如下:

<select id="queryByLike" resultType="com.example.demo.model.User">
        SELECT * FROM userinfo where username like concat('%',#{name},'%');
    </select>

可以看到使用 concat 函数后可以查询成功:

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

9. 通过页面返回数据

11. Mybatis 的增删查改【万字详解】,java ee,mybatis

新建 UserController 类: 

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/selectAll")
    public List<User> selectAllUser(){
        return userService.selectAllUser();
    }
}

 新建 UserService 类:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;

    public List<User> selectAllUser() {
        return userMapper.queryAll();
    }
}

接下来我们运行启动类,即可在页面中看到查找的数据库信息: 

10. 总结

  1. $ 存在 SQL 注入问题,因为 # 是预编译而 $ 是字符替换;
  2. orde by 只能使用 $,通过后端控制参数的输入(只能为 desc 和 asc);
  3. # 直接用于 like 查询会报错,需要使用 MySQL 的内置函数 concat 进行字符连接

11. Mybatis 的增删查改【万字详解】,java ee,mybatis文章来源地址https://www.toymoban.com/news/detail-615558.html

到了这里,关于11. Mybatis 的增删查改【万字详解】的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包