MyBatis的使用(注解方式)

MyBatis的使用(注解方式)

1.MyBatis的日志开启方式

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

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

# 开启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语句中

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

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

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

    //使用#{}进行取值
    @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语句

@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注解进行获取

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

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

@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如何处理伪表的结果

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

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

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

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

@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.基于手动指定伪表列与类的成员变量的映射关系完成封装

@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的驼峰映射(这种情况的使用前提是双方都遵守各自的开发规范)

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

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

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

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

    @Data
    @Builder
    public class EmpQuery {
        private String name; //员工姓名
        private Integer gender; //员工性别
        private LocalDate begin; //开始入职时间
        private LocalDate end; //结束入职时间
    }
    
    @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);
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值