MyBatis——增删改查

核心配置文件

MyBatis核心配置文件的顶层结构如下:

<environments> 元素

<typeAliases>元素

作用:

 

 

配置文件完成增删改查

准备环境

创建数据库表tb_brand
-- 删除tb_brand表
drop table if exists tb_brand;
-- 创建tb_brand表
create table tb_brand(
-- id主键
id int primary key auto_increment,
-- 品牌名称
brand_name varchar(20),
-- 企业名称
company_name varchar(20),
-- 排序字段
ordered int,
-- 描述信息
description varchar(100),
-- 状态:0:禁用 1:启用
status int
);
-- 添加数据
insert into tb_brand(brand_name,company_name, ordered, description,status)
values ('三只松鼠','三只松鼠股份有限公司',5,'好吃不上火',0),
('华为','华为技术有限公司',100,'华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界',1),
('小米','小米科技有限公司',50,'are you ok',1);

执行查询语句

实体类Brand
package com.mybatisDemo.pojo;

/**
 * @author hyk~
 */
public class Brand {
    //id 主键
    private Integer id;
    //品牌名称
    private String brandName;
    //企业名称
    private String companyName;
    //描述信息
    private String description;
    //状态: 0:禁用   1:启用
    private Integer status;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}
测试用例

安装MyBatisX插件

MybatisX是一款基于IDEA的快速开发插件,为效率而生
主要功能
XML和接口方法相互跳转
根据接口方法生成statement

安装完成后:自动创建

查询

(1)定义接口方法

(2)编写SQL映射文件

(3)执行测试方法

1.查询所有数据

运行结果出现异常,brandName和companyName查询为空值

原因:数据库表的字段名称 和 实体类的属性名称 不一样,则不能自动封装数据

解决方案1:

起别名:对不一样的列名起别名,让别名和实体类的属性名一样

*缺点:每次查询都要定义一次别名

解决方案2:

缺点:不灵活

解决方案3:

总结

实体类属性名和数据库表列名不一致,不能自动封装数据
1)起别名:在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样

*可以定义<sql>片段,提升复用性

2) resultMap:定义<resultMap>完成不一致的属性名和列名的映射

2.查看详情

定义接口方法

编写SQL映射文件

 参数占位符:

1. #{}:会将其替换为 ?,为了防止SQL注入

2. ${}: 拼接sql。会存在SQL注入问题

3. 使用时机: 

参数传递的时候: #{}

表名或者列名不固定的情况下: ${}

参数类型:parameterType 可以省略

特殊字符处理:

1.转义字符 例如:< 转义字符为 &lt;

2.CDATA区

 

编写测试方法

@Test
    public void testSelectById() throws IOException {
        //接收id参数
        int id = 1;

        //1.获取SqlSessionFactory
        String resource = "mybatis-config.xml"; //核心配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取SqlSession对象,执行SQL语句
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //获取BrandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        Brand brand = brandMapper.selectById(id);

        //打印
        System.out.println(brand);

        //释放资源
        sqlSession.close();
    }

运行


3.条件查询

多条件查询

参数接收

1.散装参数

如果方法中有多个参数,需要使用@Param("SQL参数占位符名称”)

定义接口方法

 编写SQL映射文件

执行测试方法

@Test
    public void testSelectTerm() throws IOException {
        //接收多条件查询参数
        int status = 1;
        String brandName ="米";
        String companyName = "科技";

        //数据处理
        brandName = "%" + brandName+ "%";
        companyName = "%" + companyName+ "%";

        //1.获取SqlSessionFactory
        String resource = "mybatis-config.xml"; //核心配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取SqlSession对象,执行SQL语句
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //获取BrandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        List<Brand> brands = brandMapper.selectTerm(status, brandName, companyName);

        //打印
        System.out.println(brands);

        //释放资源
        sqlSession.close();
    }

运行结果

2.对象参数

定义接口方法

SQL映射文件无需变更

测试方法

其它代码无需更改,只需封装对象

并修改传参

运行未报错则成功

3.map集合参数

定义接口方法

SQL映射文件无需变更

测试方法

创建Map集合

修改传参

运行未报错则成功

总结

(1)散装参数: 需要使用@Param(“SQL中的参数占位符名称”)
(2)实体类封装参数:只需要保证sQL中的参数名和实体类属性名对应上,即可设置成功

(3)map集合:只需要保证SQL中的参数名和map集合的键的名称对应上,即可设置成功

4.多条件-动态条件查询

只需更改SQL映射文件

动态条件查询

if:条件判断

test:逻辑表达式

问题:

如果第一个条件为空,则会出现语法错误 :select * from tb_brand where and .... (第一个条件不需要逻辑运算符)

解决方案:

恒等式:where 1 = 1 没有特殊含义 只是为了语法正确

<where>标签 替换 where 关键字

5.单条件-动态条件查询

从多个条件中选择一个
choose(when,otherwise): 选择,类似于Java 中的 switch 语句

定义接口方法

编写SQL映射文件

编写测试文件

@Test
    public void selectTermSingle() throws IOException {
        //接收多条件查询参数
        int status = 1;
        String brandName ="米";
        String companyName = "";

        //数据处理
        brandName = "%" + brandName+ "%";
        companyName = "%" + companyName+ "%";

        //封装对象
        Brand brand = new Brand();
//        brand.setStatus(status);
//        brand.setBrandName(brandName);
//        brand.setCompanyName(companyName);

        //1.获取SqlSessionFactory
        String resource = "mybatis-config.xml"; //核心配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取SqlSession对象,执行SQL语句
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //获取BrandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

//        List<Brand> brands = brandMapper.selectTerm(brand);

        List<Brand> brands = brandMapper.selectTermSingle(brand);

        //打印
        System.out.println(brands);

        //释放资源
        sqlSession.close();
    }

可取消注释尝试各个方案

运行

添加

编写接口方法

编写SQL映射文件

测试方法

 @Test
    public void addData() throws IOException {
        //接收参数
        String brandName ="vivo";
        String companyName = "维沃通信有限公司";
        int ordered = 1000;
        String description = "点燃生活激情,vivo与你共创无限可能";
        int status = 0;

        //封装对象
        Brand brand1 = new Brand();
        brand1.setBrandName(brandName);
        brand1.setCompanyName(companyName);
        brand1.setOrdered(ordered);
        brand1.setDescription(description);
        brand1.setStatus(status);

        //1.获取SqlSessionFactory
        String resource = "mybatis-config.xml"; //核心配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取SqlSession对象,执行SQL语句
        //填入 true 表示自动提交事务
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //获取BrandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);


        boolean b = brandMapper.addData(brand1);

        //打印
        if (b == true)
            System.out.println("数据添加成功");

        if (b == false)
            System.out.println("数据添加失败");

        //手动提交事务 否则数据添加成功但无法查询到 数据库回滚
        //sqlSession.commit();

        //释放资源
        sqlSession.close();
    }

开启自动提交事务才能正常添加且查询到数据 

手动提交也可以

运行结果为数据添加成功

点开数据库执行查询语句发现已经有该条数据了

MyBatis事务
openSession():默认开启事务,进行增删改操作后需要使用

sqlSession.commit();手动提交事务

openSession(true): 可以设置为自动提交事务(关闭事务)

1.添加-主键返回

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

比如:添加订单和订单项
1.添加订单
2.添加订单项,订单项中需要设置所属订单的id

返回添加数据的主键

<insert useGeneratedKeys="true" keyProperty="id">

编写测试代码

运行

修改

1.修改全部字段

定义接口方法

编写SQL映射文件

执行测试方法

@Test
    public void updateData() throws IOException {
        //接收参数
        int id = 1;
        String brandName ="HONOR";
        String companyName = "荣耀手机有限公司";
        int ordered = 500;
        String description = "荣耀之路,始于创新,终于卓越。";
        int status = 1;

        //封装对象
        Brand brand1 = new Brand();
        brand1.setId(id);
        brand1.setBrandName(brandName);
        brand1.setCompanyName(companyName);
        brand1.setOrdered(ordered);
        brand1.setDescription(description);
        brand1.setStatus(status);

        //1.获取SqlSessionFactory
        String resource = "mybatis-config.xml"; //核心配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取SqlSession对象,执行SQL语句
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //获取BrandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);


        int i = brandMapper.updateData(brand1);


        //打印
        if (i != 0)
            System.out.println("数据修改成功,影响的行数为"+i+"行");
        if (i == 0)
            System.out.println("数据修改失败");
        
        //手动提交事务 否则数据添加成功但无法查询到 数据库回滚
        //sqlSession.commit();

        //释放资源
        sqlSession.close();
    }

将原先id为1的数据三只松鼠改成HONOR的数据

运行代码

显示数据修改成功并且影响行数为1行

查看数据库表显示已经修改完成了

2.修改动态字段

定义接口方法

编写SQL映射文件

执行测试方法

//修改动态数据
    @Test
    public void updateTrendsData() throws IOException {
        //接收参数
        int id = 1;
        String brandName ="HONOR-HUAWEI";
        String companyName = "华为荣耀手机有限公司";
        int ordered = 500;
        String description = "荣耀之路,始于创新,终于卓越。";
        int status = 1;

        //封装对象
        Brand brand1 = new Brand();
        brand1.setId(id);
        brand1.setBrandName(brandName);
        brand1.setCompanyName(companyName);
        brand1.setOrdered(ordered);
        brand1.setDescription(description);
        brand1.setStatus(status);

        //1.获取SqlSessionFactory
        String resource = "mybatis-config.xml"; //核心配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取SqlSession对象,执行SQL语句
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //获取BrandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);


        int i = brandMapper.updateTrendsData(brand1);


        //打印
        if (i != 0)
            System.out.println("数据修改成功,影响的行数为"+i+"行");
        if (i == 0)
            System.out.println("数据修改失败");

        //手动提交事务 否则数据添加成功但无法查询到 数据库回滚
        //sqlSession.commit();

        //释放资源
        sqlSession.close();
    }

主要是这一段代码

运行代码

由此可见已实现动态修改数据了

删除

1.删除一个

定义接口方法 根据id删除数据

编写SQL映射文件

执行测试方法

    //删除一条数据
    @Test
    public void deleteData() throws IOException {
        //接收参数
        int id = 5;

        //1.获取SqlSessionFactory
        String resource = "mybatis-config.xml"; //核心配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取SqlSession对象,执行SQL语句
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //获取BrandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        boolean b = brandMapper.deleteData(id);

        //打印
        if (b == true)
            System.out.println("数据删除成功");
        if (b == false)
            System.out.println("数据删除失败");

        //手动提交事务 否则数据添加成功但无法查询到 数据库回滚
        //sqlSession.commit();

        //释放资源
        sqlSession.close();
    }

删除id为5的数据

执行代码

提示数据删除成功,再次查看数据表

数据表中已无id为5的数据 表示删除成功了


2.批量删除

定义接口方法

编写SQL映射文件

MyBatis会将数组参数,封装成一个Map结合

*默认: array = 数组         collection="array"

*也可以使用 @Param("ids")注解改变Map集合的默认key的名称         collection="ids"

利用循环遍历ids数组中的数据 有几个id数据就会生成几个#{id}

separator="," 分隔符

open="("        开始的拼接

close=");"      结束时的拼接

查看数据表中数据

执行测试方法

    //批量删除数据
    @Test
    public void deleteDataByIds() throws IOException {
        //接收数组参数
        int [] ids = {4,5,6};

        //1.获取SqlSessionFactory
        String resource = "mybatis-config.xml"; //核心配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.获取SqlSession对象,执行SQL语句
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //获取BrandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);

        boolean b = brandMapper.deleteDataByIds(ids);

        //打印
        if (b == true)
            System.out.println("数据删除成功");
        if (b == false)
            System.out.println("数据删除失败");

        //手动提交事务 否则数据添加成功但无法查询到 数据库回滚
        //sqlSession.commit();

        //释放资源
        sqlSession.close();
    }

删除数组中包含的id数据

运行

查看数据表已经没有id为4,5,6的数据了

MyBatis参数传递

MyBatis 接口方法中可以接收各种各样的参数,MyBatis底层对于这些参数进行不同的封装处理方式

单个参数

1.POJO类型 直接使用,属性名 和 参数占位符 名称 一致

2.Map集合 直接使用,键名 和 参数占位符 名称 一致

3.Collection 封装为Map集合 可以使用@Param注解,替换Map集合中默认的arg键名

map.put("arg0",collection集合);

map.put("collection",collection集合);

4.List 封装为Map集合 可以使用@Param注解,替换Map集合中默认的arg键名
 

map.put("arg0",list集合);

map.put("collection",List集合);

map.put("List",List集合);

5.Array 封装为Map集合 可以使用@Param注解,替换Map集合中默认的arg键名
 

map.put("arg0",数组);

map.put("array”,数组);

6.其他类型 直接使用

7.多个参数:

封装为Map集合 可以使用@Param注解,替换Map集合中默认的arg键名

map.put("arg0",参数值1)

map.put("param1",参数值1)

map.put("param2",参数值2)

map.put("arg1",参数值2)

-------------@Param("username")

map.put("username",参数值1)

map.put("param1",参数值1)

map.put("param2",参数值2)

map.put("arg1",参数值2) 

MyBatis提供了 ParamNameResolver 类来进行参数封装

结论: 将来都使用@Param注解来修改Map集合中默认的键名

并使用修改后的名称来获取值,这样可读性更高

定义接口方法

编写SQL映射文件

执行 运行成功

注解开发

使用注解开发会比配置文件开发更加方便

格式:

@Select("select * from tb_user where id = #{id}")
User selectById(int id);

查询: @Select
添加: @Insert
修改: @Update
删除: @Delete

代码演示

定义接口方法并编写注解SQL语句

运行测试代码

总结:

注解完成简单功能
配置文件完成复杂功能 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

CtrlCV 攻城狮

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

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

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

打赏作者

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

抵扣说明:

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

余额充值