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);
相关推荐
向阳121810 分钟前
mybatis 动态 SQL
数据库·sql·mybatis
新手小袁_J1 小时前
JDK11下载安装和配置超详细过程
java·spring cloud·jdk·maven·mybatis·jdk11
xlsw_10 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
cmdch201718 小时前
Mybatis加密解密查询操作(sql前),where要传入加密后的字段时遇到的问题
数据库·sql·mybatis
秋恬意21 小时前
什么是MyBatis
mybatis
CodeChampion21 小时前
60.基于SSM的个人网站的设计与实现(项目 + 论文)
java·vue.js·mysql·spring·elementui·node.js·mybatis
ZWZhangYu2 天前
【MyBatis源码分析】使用 Java 动态代理,实现一个简单的插件机制
java·python·mybatis
程序员大金2 天前
基于SSM+Vue的个性化旅游推荐系统
前端·vue.js·mysql·java-ee·tomcat·mybatis·旅游
奔跑草-2 天前
【服务器】MyBatis是如何在java中使用并进行分页的?
java·服务器·mybatis
秋恬意2 天前
接口绑定有几种实现方式
mybatis