mybatis增删查改基础操作+mybatis日志输入+sql注入+xml配置与动态sql

删除操作

首先在我们进行最基础删除的操作的时候,我们要清楚我们执行操作的基础的表结构,表的内容,还需要有数据库表的实现类

准备工作

1.数据库的表结构以及内容

2.我们数据库表中对应的实体类

实体类创建好之后,类中需要一个标准的javabean,这里就不再放出来

3.准备操作该数据库的 mapper接口

加上mapper注解代表   该类为mybatis中的mapper接口,程序运行的时候会自动创建接口的实现类对象,并且交给spring的ioc容器管理,具体ioc可以看我上一篇文章

工程结构如下

删除操作

我们要在mybatis中实现 根据主键的删除操作

例如 删除id=2的数据

sql语句的写法为    delete from people where id=2

我们在mapper接口中的写法只需要加上对应的注解和 一个对应的方法

值得注意的是 一个mapper接口可以写入多个语句

@Delete("delete from people where id=2")
public  void delete();

然后在我们的测试包中的测试类中 定义如下方法 

执行之后,就能删除id为2的数据了,但是这种有一个弊端,就是你只能指定一行的删除情况,想删除其他的id 内容,就需要再编写删除方法,或者修改 delete注解中的sql语句内容,那么有没有方法能解决这种冗余的情况 ,我们可以使用占位符 #{}

改造后的sql语句如下  而在test方法中语句只需要加上想删除的对应id即可

#{}大括号中的命名是自己自由定义的,但是要与自己方法中的形参名称保持一致 ,但这是delete语句中 只有一个条件所执行的删除操作,如果delete语句中有两个条件成立才能执行删除的话怎么写呢

这是两个条件进行删除的时候的语句,但是当我运行 test方法进行测试的时候,报错了报了如下错误

就是我们在运行的时候,程序找不到sql语句idname与之对应的方法形参名字,那么 我们这时候就需要注解来进行绑定与之对应的形参值 

注意  当我们使用param注解之后,注解中的字符串 需要与sql语句中的对应,而 方法形参名 跟不跟sql语句中的 名字对应都可以

日志输入

再mybatis的运行当中,我们可以看到sql语句的执行,执行操作和执行结果,配置如下

打开之后,我们执行一下我们上面的delete测试方法  看一下控制台.

可以看到我们的执行记录,我们发现 #{}内容 被?代替,然后由 方法传过来的形参值 进行与sql语句?的匹配,然后 在匹配好之后,执行sql语句,updates代表表中更改了几条数据,因为我的数据是随便输入的,所以更改了0 

这种sql 进行?占位 并且与之匹配值的sql语句 我们称为预编译sql

预编译sql与sql注入

预编译sql有两个优势

1 .性能更高  

当我们根据三个不同的id值正常执行三次sql删除语句的话 ,就是 执行一次,删除一次  

但是 我们执行删除时,发现  只有删除的id值不同,其他语句都相同,性能较低   

预编译sql会将编译依次的sql语句缓存起来,后面再次执行这条语句的时候,不会再次编译。

2.更安全  可以防止sql注入

 sql注入:通过操作输入的数据修改事先定义好的sql语句,达到执行代码对服务器进行攻击的方式

由于没有对用户输入进行充分检查,而SQL又是拼接而成,在用户输入参数时,在参数中添加一些 SQL关键字,达到改变SQL运行结果的目的,也可以完成恶意攻击

 比如一个登录系统 

我们数据库中的账号对应的密码并不是这个密码,但是当我们 输入这串字符串当密码的时候,仍会登陆成功,那是因为 在底层中 sql语句的形式为

可以看到   拼接的为  password=‘ ‘or ’1‘=’1 ’  这样拼接 就会变成一句完好的sql语句,从而达到登录效果 这种是不安全的

所以我们都用#{}占位符 来进行sql占位,生成预编译sql,我们输入的内容在sql语句中都是用?来进行占位的,这样防止sql注入安全

在Mybatis中提供的参数占位符有两种

:${...} 、#{...}

#{...} 执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值 使用时机:参数传递,都使用#{…}

${...} 拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题 使用时机:如果对表名、列表进行动态设置时使用

增加操作

我们在插入的时候是根据一整行的信息进行插入的,这时候我们可以用我们之前建立的实体类 封装 好要插入的数据内容,然后调用mapper接口的方法 给sql语句返回一个封装好的实体类,mybatis会自动识别类中的名称与内容,进行插入操作

插入的代码

@Insert("insert into people(name,age,gender,phone)values (#{name},#{age},#{gender},#{phone})")
public  void insert(UserPeople userPeople);

 测试类中的代码

@Test
public void in(){
UserPeople up=new UserPeople();
up.setAge(10);
up.setGender(1);
up.setName("王五");
up.setPhone("111510506");}

在一般情况下,在我们插入完数据是不会返回主键的id值的,我们可以用一个options注解来得到返回的主键值 并在注解中指定属性useGeneratedKeys=true和 keyProperty="实体类属性名"

修改操作

修改操作与增加操作类似,也是可以指定一个修改的实体类的内容来进行修改

查询操作

查询操作正常的是select * 查询所有,但是当我们查询单个的时候,有时候会出现查询空值的情况比如下面这段查询代码

@Mapper

public interface EmpMapper {

@Select("select id, username,job, entrydate, dept_id, create_time, update_time from emp where id=#{id}")

public Emp getById(Integer id);}

而我们与之对应的实体类中 的内容为

 可以看到 红色部分字段对应的名称不同,原因是因为

实体类属性名和数据库表查询返回的字段名一致,mybatis会自动封装。

如果实体类属性名和数据库表查询返回的字段名不一致,不能自动封装。

无法自动封装解决方法

1. 起别名 2. 结果映射 3. 开启驼峰命名

1.@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}")

2.

column 为数据库表中字段名 peoperty为 实体类的属性名

@Results({@Result(column = "dept_id", property = "deptId"),

@Result(column = "create_time", property = "createTime"),

@Result(column = "update_time", property = "updateTime")})

@Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id=#{id}") 

3.如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射.

驼峰命名规则: abc_xyz => abcXyz

表中字段名:abc_xyz

类中属性名:abcXyz

sql注入的其他问题

当我们在进行模糊查询的时候,模糊查询进行的是字符串的拼接,这样会出现sql注入的问题,而且效率不高

如下一段 

@Select("select * from emp " + "where name like '%${name}%' " + "and gender = #{gender} " + "and entrydate between #{begin} and #{end} " + "order by update_time desc")

解决这种方法 可以用字符串拼接函数解决

concat('%',#{name},'%')

mybatisxml文件与动态sql

使用Mybatis的注解方式,主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建 议使用XML来配置映射语句,也就是将SQL语句写在XML配置文件中。

在Mybatis中使用XML映射文件方式开发,需要符合一定的规范:

1. XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下 (同包同名)

2. XML映射文件的namespace属性为Mapper接口全限定名一致

3. XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。

resultType属性,指的是查询返回的单条记录所封装的类型。

编写xml映射文件

xml映射文件中的dtd约束,直接从mybatis官网复制即

<?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">

<mappe namespace=" "></mapper>

 不同的sql语句操作写在与之对应的标签中去  查询语句就写在 select标签中去

动态sql
if,where

在这段查询语句中 ,如果我们只想用这句sql查询名字返回记录,但是其他查询字段为null,会发现这个查询结果是不正确的

但是我们会想  谁有病吗,我设置好查询之后偏偏传入空值,但是当我们面对这样的表单的时候就会出现以上情况

该查询就可以选择性传入参数,遇见这种我们不可能排列组合般的写很多句sql查询,所以这时候我们就要用到动态sql

SQL语句会随着用户的输入或外部条件的变化而变化,我们称为:动态SQL。

我们根据上面查询表单的情况写的动态sql语句应该是

这样写sql 只有在查询到姓名之后,后面两项即使不输入内容也可以查询出条件,但是当我们查询姓名的时候为空,后面两项继续查询,就会出现拼接问题

我们举个例子,我们不查询姓名,只查询gender  动态sql语句拼接为

select * from emp where and gender=#{}  order by update_time desc

 多了一个and,语句就会报错

那么怎么解决呢?就用where标签 包裹该判断的语句,where标签会自动判断是否去除 多余的and或者其他值

set

在使用动态sql的时候,需要把在mapper接口中的定义的方法的与之对应的 查询注解删除,只保留方法即可,其他在xml文件中书写

在进行update操作的时候,用if判断完之后,会出现 多余的逗号  比如后面就出现了多余的逗号,此种情况用set标签包裹即可

foreach

有下面的sql 语句

delete from emp where id in (1,2,3);

 用foreach遍历in中的内容批量删除

include

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三氧化真

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值