赞
踩
下面进行:增删改查——C(create)U(update)R(retrieve)D(delete)
根据主键 id 进行删除
注意 占位符 #{ }
返回值是删除的记录条数
测试:
可以在日志中看到 mybatis 具体的语句
预编译 SQL 的优点:
SQL 注入:是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法
1 等于 1 是true,所以结果是 16,即查到了所有人,但是是大于 0 的,系统判断登录成功,可以进入系统
使用预编译 SQL:
就是使用 占位符 #{ }
Mybatis 占位符
在 Mapper 里面写 insert 接口方法
注意:
然后测试
如果需要拿到插入的员工的主键:
- @Insert("insert into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time)\n" +
- "values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, now());")
- public int insert(Emp emp);
- @Update("update emp set username=#{username}, name=#{name}, gender=#{gender}, image=#{image},job=#{job}," +
- "entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
- public void update(Emp emp);
- @Select("select * from emp where id=#{id}")
- public Emp select(Integer id);
但是注意看,后面三个是 null 值
在数据库中查询,就不是 null 值
是因为 Emp 类字段 和 数据库表属性 不一致
解决方案一:起别名
- @Select("select id, username, password, name, gender, image, job, entrydate, dept_id deptId," +
- " create_time createTime, update_time updateTime from emp where id=#{id}")
- public Emp select(Integer id);
解决方法二:手动封装
- // 解决方案二:通过 @Results,@Result 手动封装
- @Results({
- @Result(column = "dept_id",property = "deptId"),
- @Result(column = "create_time", property = "createTime"),
- @Result(column = "update_time",property = "updateTime")
- })
- @Select("select * from emp where id = #{id}")
- public Emp select(Integer id);
解决方法三:开启 mybatis 的驼峰命名自动映射开关
a_column => aColumn
开启之后,直接按原来的写:
- // 解决方案三:开启 mybatis 的驼峰命名自动映射开关
- @Select("select * from emp where id=#{id}")
- public Emp select(Integer id);
以上三种方法都会得到正确字段:
下面是条件查询:
输入张,性别,入职日期,结果根据更新日期降序
- @Select("select * from emp where name like '%${name}%' and gender = #{gender} and entrydate between #{begin} " +
- "and #{end} order by update_time desc")
- public List<Emp> selectByCondition(@Param("name") String name,
- @Param("gender") Short gender,
- @Param("begin") LocalDate begin,
- @Param("end") LocalDate end);
注:
另:由于 name 使用了 ${name},这不是预编译 SQL,会导致性能差,SQL 注入
解决办法:
使用 MySQL 自带的 concat 方法,进行字符串拼接
Mybatis 操作数据库有两种方法
注意创建文件夹的名字
XML 文件里面的配置
- <?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.example.mapper.EmpMapper">
-
- </mapper>
IDEA 插件,用来简化 mybatis
为什么说“终于讲到这一点了”,
因为之前我就有个疑问,如果我只想查一下姓张的人,我不指定性别和入职日期,以前那个代码就查询不了:
- @Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and entrydate between #{begin} " +
- "and #{end} order by update_time desc")
- public List<Emp> selectByCondition(@Param("name") String name,
- @Param("gender") Short gender,
- @Param("begin") LocalDate begin,
- @Param("end") LocalDate end);
动态 SQL:随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态 SQL
Mybatis 中有很多动态 SQL 标签
在 XML 里面去写
注意:and 要在新的一行里面写,之前我在行尾写,那样不行
- <mapper namespace="com.example.mapper.EmpMapper">
-
- <select id="selectByCondition" resultType="com.example.pojo.Emp">
- select *
- from emp
- where
- <if test="name!=null">
- name like concat('%',#{name},'%')
- </if>
- <if test="gender!=null">
- and gender = #{gender}
- </if>
- <if test="begin!=null">
- <if test="end!=null">
- and entrydate between #{begin} and #{end}
- </if>
- </if>
- order by update_time desc
- </select>
- </mapper>

这样就可以查到只姓张的人了
注意:判断入职日期,也可以在中间用 and,就不用像我那样两层 if:
- <if test="begin!=null and end!=null">
-
- </if>
但是对于只输入性别,其他三个字段都为 null,又报错
- @Test
- public void testSelectGender(){
- List<Emp> empList = empMapper.selectByCondition(null, (short) 1, null, null);
- empList.stream().forEach(System.out::println);
- }
因为 name 为 null,在 XML 里面跳过name,直接到 gender,where 直接以 and 开头了,
解决办法:把 where 改为 <where>
标签版的 where 可以自动去掉 and 或者 or,并且在条件都不成立的情况下去掉 where(真的智能)
之前的 update 存在问题
正常应该是传过来什么字段,就更新什么字段,没有就不变
但是现在是没有字段的情况下,直接设置为 null
解决:使用动态 SQL
就不用注解了,把之前代码注释掉
- // 这段代码有问题,现在不用了,在 XML 重写了
- // @Update("update emp set username=#{username}, name=#{name}, gender=#{gender}, image=#{image},job=#{job}," +
- // "entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
- public void update(Emp emp);
在 XML 里加
- <update id="update"> # 更新不需要返回什么东西,所以没有属性 resultType
- update emp
- set
- <if test="username!=null">username=#{username}</if>
- <if test="name!=null">,name=#{name}</if>
- <if test="gender!=null">,gender=#{gender}</if>
- <if test="image!=null">,image=#{image}</if>
- <if test="job!=null">,job = #{job},</if>
- <if test="entrydate!=null">,entrydate=#{entrydate}</if>
- <if test="deptId!=null">,dept_id=#{deptId}</if>
- <if test="createTime!=null">,create_time=#{createTime}</if>
- <if test="updateTime!=null">,update_time = now()</if>
- where id=#{id}
-
- </update>
这一次我们把第20个人,张测试,把他性别改成女,其他的字段不变:
还是像上次一样,set 也有标签版本的 <set>
用标签版本的 set 更好
批量删除:
MySQL 语句:
delete from emp where id in (18,19,20);
现在是 Mybatis:
EmpMapper 里面添加:
然后alt + 回车在 XML <mapper>里面写
- <!--
- 批量删除员工 delete from emp where id in(18,19,20)
- collection 遍历的集合
- item 遍历的元素
- separator 分隔符
- open 遍历开始前拼接的 SQL 片段
- close 遍历结束后拼接的 SQL 片段
- -->
- <delete id="deleteByIds">
- delete from emp where id in
- <foreach collection="list" item="id" separator="," open="(" close=")">
- #{id}
- </foreach>
- </delete>
测试(没有 17 是因为之前删除过)
这两个标签解决代码复用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。