MyBatis2

lombok:

Lombok是一个使用的Java类库,能通过注解的形式自动生成 构造器、getter/setter、equals、hashcode、toString 等方法,并可以自动化生成日志变量,简化Java开发、提高效率

Lombok会在编译时,自动生成对应的java代码。我们使用lombok时,还需要安装一个lombok插件(idea自带)

注解:
  1. @Getter/@Setter:为所有属性提供get/set方法
  2. @ToString:会给类自动生成易阅读的toString方法
  3. @EqualsAndHashCode:根据类所拥有的非静态字段自动重写equals方法和hashCode方法
  4. @Data:提供了更综合的生成代码功能(@Getter+@Setter+@ToString+@EqualsAndHashCode)
  5. @NoArgsConstructor:为实体类生成无参的构造方法
  6. @AllArgsConstructor:为实体类生成除了static修饰的字段之外有各参数的构造器方法
引入依赖:
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

增删改查:

1、删除操作:
//根据ID删除数据
@Delete("delete from emp where id = #{id}") //#{}表示占位符
public void delect(Integer id);
//public int delect(Integer id);    //返回的是影响的行数 

如果mapper接口方法形参只有一个普通类型的参数,#{…}里面的属性名可以随便写,如:#{id} 、 #{value}

日志输出:

默认关闭,可以在application.properties中,打开mybatis的日志,并指定输出到控制台

#配置指定mybatis输出日志的位置,输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

---------------------------------------------
//预编译SQL
delete from emp where id = #{id}

==>  Preparing: delete from emp where id = ?
==> Parameters: 17(Integer)

<==    Updates: 1
---------------------------------------------

如果声明的sql语句使用 #{…} 占位符,那么最终 #{…} 会被 '?' 代替,生成预编译sql
数据库在执行语句时,会使用17替换掉 '?'
预编译sql优势:
  1. 性能更高

    sql语句发送给mysql数据库服务器之后,服务器会进行以下操作:

        1、SQL语法解析检查 2、优化SQL 3、编译SQL 4、执行SQL
        为了提高效率,在数据库中会将优化编译之后的sql缓存起来(1、2、3步),
        下次再执行sql语句时,会先检查缓存,如果缓存中有,就直接执行;
        如果没有,就需要再执行一遍流程,然后缓存起来
    
        1、非预编译:
        delect from emp where id =1;
        delect from emp where id =2;
        delect from emp where id =3;
        需要编译3次
    
        2、预编译:
        delect from emp where id = ?;
        1
        2
        3
        编译一次
    
  2. 更安全(防止sql注入)

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

        ' or '1' = '1
        -->
        select count(*) from emp where username = 'XXX' and password = '' or '1' = '1';
    
参数占位符:
  1. #{…}:

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

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

  2. ${…}:

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

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

        delete from emp where id = ${id}
    
        ==>  Preparing: delete from emp where id = 17
        ==> Parameters: 
        <==    Updates: 1
    
2、新增操作:
---------------------------------------------
//新增员工信息
@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:
---------------------------------------------
==>  Preparing: insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) values (?,?,?,?,?,?,?,?,?)
==> Parameters: Tom(String), 汤姆(String), 1(Short), 1.jpg(String), 1(Short), 2000-01-01(LocalDate), 1(Integer), 2023-04-20T11:32:41.049720(LocalDateTime), 2023-04-20T11:32:41.049720(LocalDateTime)
<==    Updates: 1
---------------------------------------------
主键返回:

描述:在数据添加成功后,需要获取插入数据库数据的主键

如:添加套餐数据时,还需要维护套餐菜品关系表数据

  • 1、先保存套餐信息,并获取套餐ID
  • 2、然后再保存套餐菜品关联信息(需要记录套餐ID、菜品ID)

实现:

        //会自动将生成的主键值,赋值给emp对象的id属性
        @Options(keyProperty = "id",useGeneratedKeys = true)
        /*
            useGeneratedKeys = true 表示要获取到返回回来的主键值
            keyProperty = "id" 表示返回回来的主键封装在emp对象的id属性
        */

        @Insert(……)
        public void insert(Emp emp);
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);    
---------------------------------------------
预编译SQL:
---------------------------------------------
==>  Preparing: update emp set username = ?,name = ?,gender = ?,image = ?, job = ?, entrydate = ?, dept_id = ?, update_time = ? where id = ?
==> Parameters: Tom1(String), 汤姆1(String), 1(Short), 1.jpg(String), 1(Short), 2000-01-01(LocalDate), 1(Integer), 2023-04-20T12:08:44.616295300(LocalDateTime), 18(Integer)
<==    Updates: 1   
--------------------------------------------- 
数据封装:

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

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

解决方案一:给字段起别名,让别名与实体类属性一致

解决方案二:通过 @Results,@Result 注解手动映射封装

    @Results({
        @Result(column = "dept_id",property = "deptId"),
        @Result(column = "create_time",property = "createTime"),
        @Result(column = "update_time",property = "updateTime")
    })
    @select(…)
    ……

解决方案三:开启mybatis的驼峰命名自动映射开关

application.properties文件中

    mybatis.configuration.map-underscore-to-camel-case=true
    //dept_id -->deptId
4、条件查询员工:

​ 1、根据输入的 员工姓名、员工性别、入职时间 搜索满足条件的员工信息

​ 2、其中 员工姓名,支持模糊匹配;性别 进行精准查询;入职时间 进行范围查询

​ 3、支持分页查询

​ 4、并对查询的结果,根据最后修改时间进行倒序排序

@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> list(String name, short gender, LocalDate begin,LocalDate end);
concat字符串拼接函数:
  1. ‘#{}’ 不能出现在引号之内的,因为 #{} 最终生成的是预编译的sql,最终要被 ? 替代,

而 ? 不能出现在引号之内,要把 # 换成 %

  1. ${} 不安全,会出现sql注入问题,此时,可以用 concat字符串拼接函数 解决

    select concat(‘hello’,’mysql’,’world’); –> hello mysql world
    –>
    select * from emp where name like concat(‘%’,#{name},’%’)

参数说明:
  1. 在springboot 2.X 版本中,#{}里的参数与形参对应起来就好

    @Select("… #{name} …")
    public …… (String name);
    
  2. 在springboot 1.X 版本或者单独使用mybatis时,需要每一个参数都加上 @Param 注解
    @Select("… #{name} …")
    public …… (@Param("name") String name,@Param("gender")Short gender …… )
    

在springboot 1.X 版本或者单独使用mybatis时,在对mapper接口编译的过程中,并不会保留方法的形参名称

    @Select("……")
    public List<Emp> list(String var1, short var2, LocalDate var3,LocalDate var4);

XML映射文件:

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

接口名:java.com.itheima.mapper.EmpMapper.class

映射文件名:resources.com.itheima.mapper.EmpMapper.xml

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

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

注意:

resources文件夹新建包时,不能用 ‘.’ 创建;要用 ‘/’

​ 如:不能”com.itheima.mapper”

​ 要用”com/itheima/mapper”

直接从mybatis官方复制约束:

@Mapper 
public interface EmpMapper{
    public List<Emp> list(String name, short gender, LocalDate begin,LocalDate end);
}

EmpMapper.xml:
//约束
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">

<mapper namespace="com.itheima.mapper.EmpMapper">
    //resultType 单条记录所封装的类型
    <select id="list" resultType="com.itheima.pojo.Emp">
        select * from emp where name like concat('%',#{name},'%') and gender = #{gender} 
        and entrydate between #{begin} and #{end} order by update_time desc
    </select>
</mapper>
XML映射文件 与 注解:

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

动态SQL:

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

<if>:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL
<where>:where元素只会在子元素有内容的情况下才插入where子句。而且会自动取出子句的开头的 AND 或 OR
<set>:动态地在行首插入set关键字,并会删除额外的逗号(用在update语句中)
<sql>:定义可重用的SQL片段
<include>:通过属性refid,指定包含的sql片段


select id,
username,
password,
name,
gender,
image,
job,
entrydate,
dept_id,
create_time,
update_time
from emp

<select id="list" resultType="com.itheima.pojo.Emp">
    <include refid="commonSelect"/>
等价于:
<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
    ……

<select id="list" resultType="com.itheima.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 and end != null">
            and entrydate between #{begin} and #{end}
        </if>
    </where>    
案例:

完善更新员工信息,如果更新时传递有值,则更新;如果更新时没有传递值,则不更新

<update id="update2">
    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>
创作不易!转载请注明作者及文章链接或作者博客链接——
- 作者:pidanxia
- 链接:https://pidanxia.ink
(链接可为:**文章链接**或者**作者博客链接**)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇