【SSM】MyBatis 操作数据库(重点:Mybatis两种使用方式)

【大家好,我是爱干饭的猿,本文重点介绍ORM 框架和Mybatis的关系、通过注解 或者 通过XML配置文件的使用Mybatis,以及参数占位符 #{} 和 ${} 的区别, 什么是sql 注入。

后续会继续分享其他重要知识点总结,如果喜欢这篇文章,点个赞👍,关注一下吧】

上一篇文章:《【SSM】Spring AOP 统一问题处理(重点:Spring AOP 实现原理)》


🎁1.MyBatis 是什么?

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。

MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获 取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

简单来说 MyBatis 是更简单完成程序和数据库交互的工具,也就是更简单的操作和读取数据库工具。

🎁2. 什么是ORM框架?

ORM 把数据库映射为对象:

  • 数据库表(table)–> 类(class)
  • 记录(record,行数据)–> 对象(object)
  • 字段(field) –> 对象的属性(attribute)

一般的 ORM 框架,会将数据库模型的每张表都映射为一个 Java 类。 也就是说使用 MyBatis 可以像操作对象一样来操作数据库中的表,可以实现对象和数据库表之间的转换。

MyBatis 也是一个 ORM 框架,ORM(Object Relational Mapping),即对象关系映射。在面向对象编程语言中,将关系型数据库中的数据 与对象建立起映射关系,进而自动的完成数据与对象的互相转换:

  1. 将输入数据(即传入对象)+SQL 映射成原生 SQL

  2. 将结果集映射为返回对象,即输出对象

【SSM】MyBatis 操作数据库(重点:Mybatis两种使用方式)编辑

一些其他框架:

  • Hibernate框架:偏向简化SQL的模式
  • MyBatis框架:偏向ORM的模式
  • Spring 内部提供的JdbcTemplate:偏向简化SQL的模式
  • JPA :完全倒向了ORM的形式,建表的过程都被抽象,我们看到的只有类(我写了类,框架根据类建表)

🎁3. MyBatis 的使用

3.1 添加MyBatis框架支持

1. 新项目添加MyBatis框架

【SSM】MyBatis 操作数据库(重点:Mybatis两种使用方式)编辑

2. 旧项目添加MyBatis框架

a. 使用 EditStarters插件

【SSM】MyBatis 操作数据库(重点:Mybatis两种使用方式)编辑【SSM】MyBatis 操作数据库(重点:Mybatis两种使用方式)编辑

b. 手动添加

        <!-- 把 DataSource对象注册到Spring 中-->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jdbc</artifactId>
  </dependency>
  <!-- 添加 mybatis 框架 -->
  <dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>2.2.2</version>
  </dependency>
  <!-- 添加 MySQL 驱动 -->
  <dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <scope>runtime</scope>
  </dependency>

3.2 配置连接字符串和MyBatis

此步骤需要进行两项设置,数据库连接字符串设置和 MyBatis 的 XML 文件配置。

1. 配置连接字符串

如果是 application.yml 添加如下内容:

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/...?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

2. 配置 MyBatis 中的 XML 路径

通过XML配置文件的形式使用Mybatis 时需要配置,通过注解使用Mybatis时,不需要配置

mybatis:
  mapper-locations: classpath:mapper/**.xml

3.3 通过注解使用Mybatis

定义Mapper 接口

@Repository // 消除报错
@Mapper   // Mapper 注解
public interface UserMapper {

}

1. 查询

    // 1. 查询
    // 1.1 通过uid 查询得到Map对象
    @Select("select uid, username, password from users where uid = #{uid}")
    Map<String, Object> select1(@Param("uid") int uid);

    // 1.2 通过uid 查询得到User类对象
    @Select("select uid, username, password from users where uid = #{uid}")
    UserDO select2(@Param("uid") int uid);
### 2. 插入
    // 2. 插入
    // 2.1 插入,返回插入成功的条数
    @Insert("insert into users (username, password) values (#{username}, #{password})")
    int insert1(UserDO userDO);

    // 2.2 由于用不到这个返回值,所以写成 void 更常见
    @Insert("insert into users (username, password) values (#{username}, #{password})")
    void insert2(UserDO userDO);

    // 2.3 插入后拿到自增id
    // 通过 @Options 注解,添加一些配置,得到自增主键,设置成 uid
    // keyProperty : 对象的属性名是 uid
    // keyColumn : 表的字段名的 uid
    @Insert("insert into users (username, password) values (#{username}, #{password})")
    @Options(useGeneratedKeys = true, keyProperty = "uid", keyColumn = "uid")
    void insert3(UserDO userDO);

3. 修改

    // 3. 修改
    @Update("update users set username = #{username}, password = #{password} where uid = #{uid}")
    int update(UserDO userDO);

4. 删除

    // 4. 删除
    @Delete("delete from users where uid = #{uid}")
    int delete(@Param("uid") int uid);

5. 总览(增删查改)

import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import java.util.Map;

@Repository // 消除报错
@Mapper   // Mapper 注解
public interface UserMapper {

    // 1. 查询
    // 1.1 通过uid 查询得到Map对象
    @Select("select uid, username, password from users where uid = #{uid}")
    Map<String, Object> select1(@Param("uid") int uid);

    // 1.2 通过uid 查询得到User类对象
    @Select("select uid, username, password from users where uid = #{uid}")
    UserDO select2(@Param("uid") int uid);

    // 2. 插入
    // 2.1 插入,返回插入成功的条数
    @Insert("insert into users (username, password) values (#{username}, #{password})")
    int insert1(UserDO userDO);

    // 2.2 由于用不到这个返回值,所以写成 void 更常见
    @Insert("insert into users (username, password) values (#{username}, #{password})")
    void insert2(UserDO userDO);

    // 2.3 插入后拿到自增id
    // 通过 @Options 注解,添加一些配置,得到自增主键,设置成 uid
    // keyProperty : 对象的属性名是 uid
    // keyColumn : 表的字段名的 uid
    @Insert("insert into users (username, password) values (#{username}, #{password})")
    @Options(useGeneratedKeys = true, keyProperty = "uid", keyColumn = "uid")
    void insert3(UserDO userDO);

    // 3. 修改
    @Update("update users set username = #{username}, password = #{password} where uid = #{uid}")
    int update(UserDO userDO);

    // 4. 删除
    @Delete("delete from users where uid = #{uid}")
    int delete(@Param("uid") int uid);
}

3.4 通过XML配置文件的形式使用Mybatis

先配置 MyBatis 中的 XML 路径,然后在mapper下 .xml 文件中写

【SSM】MyBatis 操作数据库(重点:Mybatis两种使用方式)编辑

定义Mapper 接口:

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;

@Repository
@Mapper
public interface UserMapper {
    // 1. 查询
    // 1.1 单个查询
    User selectOneByUid(@Param("uid") int uid);
    // 1.2 多个查询
    List<User> selectListByUidList(@Param("uidList") List<Integer> uidList);
    // 1.3 动态查询
    User selectByUser(@Param("user") User user);

    // 2. 插入
    // 2.1 单个插入
    int insertOneUser(@Param("user") User user);
    // 2.1 批量插入
    int insertBatch(@Param("userList") List<User> userList);

    // 3. 修改
    void update(int uid , String username);

    // 4. 删除
    void delete(int uid);
}

0. 关于resultMap

使用场景:

  • 字段名称和程序中的属性名不同的情况,可使用 resultMap 配置映射;
  • 一对一和一对多关系可以使用 resultMap 映射并查询数据。
    <!-- 返回字典映射-->
    <resultMap id="xxx" type="com.haomin.mybatis_xml.User">
        <id property="uid" javaType="Integer" column="uid" jdbcType="INTEGER" />
        <result property="username" javaType="String" column="username" jdbcType="VARCHAR" />
        <result property="password" column="password" />
    </resultMap>

【SSM】MyBatis 操作数据库(重点:Mybatis两种使用方式)编辑

1. 查询

    <!-- 1.1 单个查询 -->
    <select id="selectOneByUid" resultType="com.haomin.mybatis_xml.User" parameterType="int">
        select uid, username, password from users where uid = #{uid}
    </select>

    <!-- 1.2 多个查询 -->
    <select id="selectListByUidList" resultMap="xxx" parameterType="List">
        select uid, username, password from users where uid in (
            <foreach collection="uidList" item="id" separator=", ">
                #{id}
            </foreach>
        ) order by uid
    </select>

    <!-- 1.3 动态查询-->
    <select id="selectByUser" resultMap="xxx" parameterType="com.haomin.mybatis_xml.User">
        select uid, username, password from users where
        <if test="user.uid != null">
            uid = #{user.uid}
        </if>
        <if test="user.username != null">
            and username = #{user.username}
        </if>
        <if test="user.password != null">
            and password = #{user.password}
        </if>
    </select>

2. 插入

    <!-- 2.1 单个插入-->
    <insert id="insertOneUser" useGeneratedKeys="true" keyProperty="uid" keyColumn="uid">
        insert into users (username, password) values
        (#{user.username}, #{user.password})
    </insert>

    <!-- 2.2 批量插入-->
    <insert id="insertBatch" useGeneratedKeys="true" keyProperty="uid" keyColumn="uid">
        insert into users (username, password) values
        <foreach collection="userList" item="user" separator=", ">
            (#{user.username}, #{user.password})
        </foreach>
    </insert>

3. 修改

    <!-- 3. 修改-->
    <update id="update">
        update users set username = #{username} where uid = #{uid}
    </update>

4. 删除

    <!-- 4. 删除-->
    <delete id="delete">
        delete from users where uid = #{uid}
    </delete>

5. 总览(增删查改)

<?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.haomin.mybatis_xml.UserMapper">
    <!-- 返回字典映射-->
    <resultMap id="xxx" type="com.haomin.mybatis_xml.User">
        <id property="uid" javaType="Integer" column="uid" jdbcType="INTEGER" />
        <result property="username" javaType="String" column="username" jdbcType="VARCHAR" />
        <result property="password" column="password" />
    </resultMap>

    <!-- 1.1 单个查询 -->
    <select id="selectOneByUid" resultType="com.haomin.mybatis_xml.User" parameterType="int">
        select uid, username, password from users where uid = #{uid}
    </select>

    <!-- 1.2 多个查询 -->
    <select id="selectListByUidList" resultMap="xxx" parameterType="List">
        select uid, username, password from users where uid in (
            <foreach collection="uidList" item="id" separator=", ">
                #{id}
            </foreach>
        ) order by uid
    </select>

    <!-- 1.3 动态查询-->
    <select id="selectByUser" resultMap="xxx" parameterType="com.haomin.mybatis_xml.User">
        select uid, username, password from users where
        <if test="user.uid != null">
            uid = #{user.uid}
        </if>
        <if test="user.username != null">
            and username = #{user.username}
        </if>
        <if test="user.password != null">
            and password = #{user.password}
        </if>
    </select>

    <!-- 2.1 单个插入-->
    <insert id="insertOneUser" useGeneratedKeys="true" keyProperty="uid" keyColumn="uid">
        insert into users (username, password) values
        (#{user.username}, #{user.password})
    </insert>

    <!-- 2.2 批量插入-->
    <insert id="insertBatch" useGeneratedKeys="true" keyProperty="uid" keyColumn="uid">
        insert into users (username, password) values
        <foreach collection="userList" item="user" separator=", ">
            (#{user.username}, #{user.password})
        </foreach>
    </insert>

    <!-- 3. 修改-->
    <update id="update">
        update users set username = #{username} where uid = #{uid}
    </update>

    <!-- 4. 删除-->
    <delete id="delete">
        delete from users where uid = #{uid}
    </delete>
</mapper>

当然还有更多用法:可以参考 Mybatis 官方文档

3.5 参数占位符 #{} 和 ${} 和 sql 注入

  • #{}:预编译处理。

  • ${}:字符直接替换。

预编译处理是指:MyBatis 在处理#{}时,会将 SQL 中的 #{} 替换为?号,使用 PreparedStatement 的 set 方法来赋值,编译后会带上 ‘ ’。

直接替换:是 MyBatis 在处理 {} 替换成变量的值。

结论:

  • 用于查询的字段,尽量使用 #{} 预查询的方式,如果用${} 可能会出现sql注入问题。
  • 使用 ${sort} 可以实现排序查询或者分页,而使用 #{sort} 就不能实现排序查询了,因为当使用 #{sort} 查询时,如果传递的值为 String 则会加单引号,就会导致 sql 错误。 sql 注入代码例子:

执行:

select * from userinfo where username = '${name}' and password = '${pwd}'

当sql 为 : ‘ or 1=1  时

执行语句:

select * from users where username = ' or 1=1  and password = ' or 1=1;

当然,Mybatis 还有更多用法:可以参考



分享到此,感谢大家观看!!!

如果你喜欢这篇文章,请点赞加关注吧,或者如果你对文章有什么困惑,可以私信我。

🏓🏓🏓

原文始发于微信公众号(爱干饭的猿):【SSM】MyBatis 操作数据库(重点:Mybatis两种使用方式)

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/45797.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!