【Day 9】Mybatis CURD + XML 映射 + 动态 SQL

1 Mybatis 基础操作

下面进行:增删改查——C(create)U(update)R(retrieve)D(delete)

1.1 删除(删)

根据主键 id 进行删除

注意 占位符 #{ }

返回值是删除的记录条数

测试:

可以在日志中看到 mybatis 具体的语句

预编译 SQL 的优点:

  • 性能更高
  • 更安全(防止 SQL 注入)

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

        1 等于 1 是true,所以结果是 16,即查到了所有人,但是是大于 0 的,系统判断登录成功,可以进入系统

使用预编译 SQL:

就是使用 占位符 #{ }

Mybatis 占位符

1.2 插入(增)

在 Mapper 里面写 insert 接口方法

注意:

  • emp 的字段采用驼峰命名,而数据库的 emp 表,是用下划线命名(这样更直观)所以在填写 values 的时候,需要看清楚
  • id 不用填写,id 是自增(increment)
  • password 也不用填写,password 是默认'123456'

然后测试

如果需要拿到插入的员工的主键:

@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);

1.3 更新(改)

@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);

1.4 查询(查)

@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);

注:

  • 要正确地映射,使用注解@Parm
  • 而且 name 是 ${name}

另:由于 name 使用了 ${name},这不是预编译 SQL,会导致性能差,SQL 注入

解决办法:

使用 MySQL 自带的 concat 方法,进行字符串拼接

2 XML 映射文件

Mybatis 操作数据库有两种方法

  • 注解
  • XML 映射文件

 注意创建文件夹的名字

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>

2.1 MybatisX

IDEA 插件,用来简化 mybatis 

2.2 到底用注解还是 XML

3 动态 SQL(终于讲到这一点了)

        为什么说“终于讲到这一点了”,

        因为之前我就有个疑问,如果我只想查一下姓张的人,我不指定性别和入职日期,以前那个代码就查询不了:

@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 标签

  • <if>
  • <foreach>
  • <sql><include>

3.1 <if>

在 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(真的智能)

3.2 关于之前 update 的动态 SQL

之前的 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 更好

3.3 <foreach>

批量删除:

 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 是因为之前删除过)

3.4 <sql><include>

这两个标签解决代码复用

  • 41
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Spring Boot中,可以使用MyBatis框架来实现与关系数据库的关联映射。下面是一个简单的示例: 1. 首先,确保你的项目中已经引入了Spring Boot和MyBatis的依赖。 2. 创建一个实体类,表示数据库中的一张表。例如,创建一个名为User的实体类,包含id、name和age属性。 3. 创建一个Mapper接口,用于定义数据库操作的方法。例如,创建一个名为UserMapper的接口,包含查询用户信息的方法。 4. 在Mapper接口中使用注解@Select、@Insert、@Update等来定义SQL语句。 5. 创建一个Mapper.xml文件,用于编写SQL语句。在该文件中,使用<select>、<insert>、<update>等标签来定义SQL语句。 6. 在Spring Boot的配置文件中,配置MyBatis的相关信息,如数据库连接信息、Mapper接口的扫描路径等。 7. 在Service层中调用Mapper接口的方法,实现业务逻辑。 8. 在Controller层中处理请求,并调用Service层的方法。 下面是一个示例代码: ```java // User.java public class User { private Integer id; private String name; private Integer age; // 省略getter和setter方法 } // UserMapper.java @Mapper public interface UserMapper { @Select("SELECT * FROM user WHERE id = #{id}") User getUserById(Integer id); } // UserMapper.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.UserMapper"> <select id="getUserById" resultType="com.example.entity.User"> SELECT * FROM user WHERE id = #{id} </select> </mapper> // application.properties spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456 mybatis.mapper-locations=classpath:mapper/*.xml // UserService.java @Service public class UserService { @Autowired private UserMapper userMapper; public User getUserById(Integer id) { return userMapper.getUserById(id); } } // UserController.java @RestController public class UserController { @Autowired private UserService userService; @GetMapping("/user/{id}") public User getUserById(@PathVariable Integer id) { return userService.getUserById(id); } } ``` 以上示例演示了如何在Spring Boot中整合MyBatis,并实现了关联映射。你可以根据自己的需求,编写更多的Mapper接口和SQL语句来实现其他数据库操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值