MyBatis的使用(注解方式)

MyBatis的使用(注解方式)

1.MyBatis的日志开启方式

默认情况下执行接口的方法是不显示任何内容的,但是可以基于MyBatis开启日志输出

在配置文件中配置如下信息:

properties 复制代码
# 开启MyBatis的日志输出
mybatis.configuration.log-impl=org.apache.itbatis.logging.stdout.StudOutImpl

开启之后,可以在执行SQL语句的时候看到实际执行的语句内容以及参数的内容(实际影响数据库的行数)

2.MyBatis的SQL注入

预编译SQL就是SQL语句中不确定的地方提前用?进行占位的SQL语句

好处:减少数据库对SQL语句语法检查/优化/编译的次数,预编译SQL就相当于一个模板

而直接写好的SQL语句每次都会经过语法检查/优化/编译

在MyBatis中,SQL中获取参数的方式有两种

  • ${}:底层使用不是预编译SQL而是将参数拼接在SQL语句中

    java 复制代码
    //使用${}进行取值
    @Delete("DELETE FROM emp WHERE username = '${username}'") //DELETE FROM emp WHERE id = '10'
    public void deleteEmp2(@Param("username") String username);
    java 复制代码
    @Test
    public void testDeleteEmp2() {
        //SQL注入:传递数据导致SQL本身的语义发生改变攻击方式
        empMapper.deleteEmp2("' OR '1' = '1");
    }

    由于底层是拼接最终的SQL语句变成了DELETE FROM WHERE username=' OR '1' = '1',条件永远成立,所有的数据都被删除了,就存在SQL注入的问题

  • #{}:底层使用的是预编译SQL可以保证SQL语句的安全性

    java 复制代码
    //使用#{}进行取值
    @Delete("DELETE FROM emp WHERE username = #{username}") //DELETE FROM emp WHERE username = ?
    public void deleteEmp3(@Param("username") String username);

    由于预编译SQL已经先发送给MySQL进行编译,之后传递给的所有值都会被MySQL当作参数对待

总结:${}和#{}在MyBatis中取值的优缺点对比

1.底层的方式

  • #{}使用的是预编译语句,先将不确定的地方使用?占位,提前发送给MySQL进行编译
  • ${}底层直接进行内容的拼接,每次都会将拼接好的内容发给MySQL进行执行

2.效率的对比

  • 预编译SQL语句的性能更高,因为当模板被MySQL编译好之后就不需要再进行编译了,直接传递参数
  • ${}由于每次的内容都不一样,都需要进行编译的过程

3.灵活性的对比

  • ${}更加灵活,因为不仅仅可以拼接参数,SQL语句中的任何一个部分都可以拼接(表名/数据库名/字段)
  • #{}没有${}灵活,它只能够作为参数的占位符

开发中使用#{}!

3.MyBatis的添加操作

添加操作:要添加一条数据到数据库,基于已经完成ORM映射(表/类)直接声明该类作为方法的参数

可以基于#{}获取对象中成员变量内容组成的SQL语句

java 复制代码
@Insert("INSERT INTO emp VALUES (NULL,#{emp.username},#{emp.password},#{emp.name},#{emp.gender}," +
            "#{emp.image},#{emp.job},#{emp.entrydate},#{emp.deptId},#{emp.createTime},#{emp.updateTime})")
public void saveEmp(@Param("emp") Emp emp);

复杂对象:一个对象包含多个值(自定义类的对象),使用#{对象名.属性名}

@Param("emp") Emp emp,可以限制SQL语句中必须基于指定的名称进行获取

MyBatis添加操作(返回主键值)

如果需要在添加数据完成之后获取本次数据的主键,可以在添加的注解上使用@Options注解进行获取

java 复制代码
//开启主键返回(添加完成之后将生成的主键赋值给参数对象的id属性)
@Options(keyProperty = "id",useGeneratedKeys = true)
4.MyBatis更新操作

一般情况下可以将更新后的数据保存到一个与表进行映射的Java类中。参数对象里面必须带有id(id是定位要更新数据的唯一方式),创建时间不需要更新。

java 复制代码
@Update("UPDATE emp SET username = #{emp.username},password = #{emp.password},name = #{emp.name}" +
        ",gender = #{emp.gender},image = #{emp.image},job = #{emp.job},entrydate = #{emp.entrydate}" +
        ",dept_id = #{emp.deptId},update_time = #{emp.updateTime} WHERE id = #{emp.id}")
public void updateEmp(@Param("emp") Emp emp);
5.MyBatis查询单条数据

当执行增删改语句的时候返回值类型可以写void,但是查询的时候一定会产生一个伪表结果,声明返回值类型的目的就是告诉MyBatis如何处理伪表的结果

java 复制代码
@Select("SELECT * FROM emp WHERE id = #{id}")
public Emp selectEmpById(@Param("id") Integer id);

当MyBatis读取到返回值类型之后,会默认创建一个对象,按照表与类的映射关系完成对象成员变量的赋值

6.MyBatis解决表名/列名不一致问题

1.基于修改查询出伪表列的别名与类的成员变量名一致让MyBatis完成封装(起别名)

java 复制代码
@Select("SELECT id, username, password, name, gender, image, job, entrydate, dept_id AS deptId, create_time AS createTime, update_time AS updateTime FROM emp WHERE id = #{id}")
public Emp selectEmpById2(@Param("id") Integer id);

2.基于手动指定伪表列与类的成员变量的映射关系完成封装

java 复制代码
@Select("SELECT * FROM emp WHERE id = #{id}")
@Results({@Result(column = "dept_id", property = "deptId"), //伪表的dept_id列映射给deptId成员变量
          @Result(column = "create_time", property = "createTime"), //伪表的create_time列映射给createTime成员变量
          @Result(column = "update_time", property = "updateTime")}) //伪表的update_time列映射给updateTime成员变量
public Emp selectEmpById3(@Param("id") Integer id);

3.开启MyBatis的驼峰映射(这种情况的使用前提是双方都遵守各自的开发规范)

properties 复制代码
mybatis.configuration.map-underscore-to-camel=true
7.MyBatis查询多条数据操作
  • 查询多条数据的基础方式:没有条件

    由于要查询多条数据,要将返回值声明为List,泛型为封装为什么对象

    java 复制代码
    @Select("SELECT * FROM emp")
    public List<Emp> selectEmpList();
  • 查询多条数据的进阶方式:有条件

    有条件指的是要基于多个参数进行的查询,将多个参数封装为一个Java类(条件对象)

    java 复制代码
    @Data
    @Builder
    public class EmpQuery {
        private String name; //员工姓名
        private Integer gender; //员工性别
        private LocalDate begin; //开始入职时间
        private LocalDate end; //结束入职时间
    }
    java 复制代码
    @Select("SELECT * FROM emp WHERE name LIKE CONCAT('%',#{empQuery.name},'%') AND gender = #{empQuery.gender} AND entrydate >= #{empQuery.begin} AND entrydate <= #{empQuery.end}")
    public List<Emp> selectEmpListByCondition(@Param("empQuery") EmpQuery empQuery);
相关推荐
凌冰_17 分钟前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
Elaine2023912 小时前
零碎04 MybatisPlus自定义模版生成代码
java·spring·mybatis
一二小选手2 小时前
【MyBatis】全局配置文件—mybatis.xml 创建xml模板
xml·java·mybatis
刘大浪3 小时前
后端数据增删改查基于Springboot+mybatis mysql 时间根据当时时间自动填充,数据库连接查询不一致,mysql数据库连接不好用
数据库·spring boot·mybatis
蓝染-惣右介5 小时前
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
java·数据库·tomcat·mybatis
武子康6 小时前
Java-07 深入浅出 MyBatis - 一对多模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据库·sql·mybatis·springboot
一二小选手6 小时前
【Mybatis】@Param注解 resultMap手动映射
java·mybatis
郑祎亦9 小时前
Spring Boot 项目 myblog 整理
spring boot·后端·java-ee·maven·mybatis
jokerest1231 天前
web——sqliabs靶场——第十三关——报错注入+布尔盲注
mybatis