8-1 Mybatis

Mybatis

Mybatis项目创建

1. 创建一个新的springboot工程,选择引入对应的起步依赖(mybatis、mysql驱动、lombok)

2. application.properties中引入数据库连接信息(复制过来即可)

3. 准备数据库表 emp,及对应的实体类 Emp (实体类属性采用驼峰命名模式)

4. 准备Mapper接口 EmpMapper

application.properties文件配置

#下面这些内容是为了让MyBatis映射
​
​
#指定Mybatis的Mapper文件
mybatis.mapper-locations=classpath:mappers/*xml
​
##指定Mybatis的实体目录
#自己修改
mybatis.type-aliases-package=com.itheima.Pojo.Emp  实体类地址
​
#开启驼峰命名自动映射,即从经典数据库列名 a_column 映射到经典 Java 属性名 aColumn。
mybatis.configuration.map-underscore-to-camel-case=true
​
#指定mybatis输出日志的位置, 输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
​
#驱动
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#连接路径
spring.datasource.url=jdbc:mysql://localhost:3306/tlias
#账号
spring.datasource.username=root
#密码
spring.datasource.password=1234

java语言编译为SQL语言的过程

语法检查>缓存> 编译SQL> 缓存>执行

预编译SQL

1.3.3.1 介绍

预编译的SQL,有两个优势:

  • 性能更高

  • 防止SQL注入

A. 性能更高: 预编译SQL,编译一次之后会将编译后的SQL语句缓存起来,后面再次执行这条insert语句时,SQL语句一样,不会再次编译。 只是输入的参数不同。

B. 防止SQL注入:将敏感字进行转义,安全。

参数占位符

在Mybatis中提供的参数占位符有两种:${...}, #{...}。

1). #{...}

执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值。

使用时机:参数传递,都使用#{…}

2). ${...}

拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题。

使用时机:如果对表名、列表进行动态设置时使用。

基础操作

增 insert into

删 delete

改 update

查 select

数据封装

我们看到查询返回的结果中大部分字段是有值的,但是deptId,createTime,updateTime这几个字段是没有值的,而数据库中是有对应的字段值的,这是为什么呢?(表和实体类名字对应不上

原因如下:

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

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

三种方法解决

起别名

@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 getById(Integer id);

手动结果映射

@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 getById(Integer id);

开启驼峰命名(推荐)

#开启驼峰命名自动映射,即从经典数据库列名 a_column 映射到经典 Java 属性名 aColumn。
mybatis.configuration.map-underscore-to-camel-case=true

参数名说明(@Param注解)

接口中的方法怎么设定参数名,好让SQL语句中能够识别

在springBoot的2.x版本之后,springBoot的父工程对compiler编译插件进行了默认的参数 parameters 配置,使得在编译时,会在字节码文件中保留原方法形参的名称,所以#{…}里面可以直接通过形参名获取对应的值。

在springBoot的1.x版本中,所有接口方法形参编译后的为var1、var2 …,此时如果有多个参数,就需要通过@Param注解来指定SQL语句中的参数名

@Select("select * from emp " +
            "where name like concat('%',#{name},'%') and gender=#{gender} and entrydate between #{begin} and #{end};")
            
    List<Emp> list3(@Param("name") String name, @Param("gender") Short gender, @Param("begin") LocalDate begin, @Param("end") LocalDate end);

主键返回(@Options(keyProperty = "id", useGeneratedKeys = true))

@Options(keyProperty = "id", useGeneratedKeys = true)
​
@Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) " +
"values(#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
public void insert(Emp emp);

动态SQL

XML映射文件

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

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

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

<?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=" 接口全限定名 "> 接口地址
​
  <select id="接口方法名" resultType=" 返回值类型 "> 绑定方法名 返回值地址到POJO的类中
    <!-- sql语句 -->
​
  </select>
​
</mapper>

if

用于判断条件是否成立,使用test属性进行条件判断,如果条件为true,则拼接SQL

<select id="list" resultType="com.itheima.pojo.Emp">
    select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
    where
    <if test="name != null">
        name like concat('%',#{name},'%')
    </if>
    <if test="gender != null">
        and gender = #{gender}
    </if>
    <if test="begin != null and end != null">
        and entrydate between #{begin} and #{end}
    </if>
    order by update_time desc
</select>

where 标签

<where> (去and 或 or)如果不去除会出现SQL语句语法错误

where 元素只会在子元素有内容的情况下才插入where子句。而且会自动去除子句的开头的AND 或OR。

Set标签

<set>(去逗号) 如果不去除会出现SQL语句语法错误

动态地在行首插入 SET 关键字,并会删掉额外的逗号。(用在update语句中)

<update id="update">
    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="updateTime != null">
            update_time=#{updateTime}
        </if>
    </set>
    where id=#{id}
</update>

foreach标签

<foreach>(批量处理数据 例如删除)

foreach属性介绍:

collection:集合名称

item:集合遍历出来的元素/项

separator:每一次遍历使用的分隔符

open:遍历开始前拼接的片段

close:遍历结束后拼接的片段

SQL语句
delete from emp where id in (1,2,3);
//批量删除
public void deleteByIds(List<Integer> ids);
​
XML映射文件
<delete id="deleteByIds">
    delete from emp where id in
    <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
    </foreach>
</delete>

SQL标签

<sql>用于减少重复代码块 生成一个可重用的代码块片段

include标签

<include> 通过属性refid,指定包含的sql片段。

<sql id="commonSelect">
    select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
 </sql>
 
 <select id="list" resultType="com.itheima.pojo.Emp">
    <include refid="commonSelect"/>
    <where>
        <if test="name != null">
            name like concat('%',#{name},'%')
        </if>
        <if test="gender != null">
            and gender = #{gender}
        </if>
        <if test="begin != null and end != null">
            and entrydate between #{begin} and #{end}
        </if>
    </where>
    order by update_time desc
</select>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值