Java:Mybatis的使用

news2024/11/27 8:34:39

一、Mybatis的概述

MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发

MyBatis中文官网:https://mybatis.org/mybatis-3/zh/getting-started.html

二、Mybatis快速入门

1、创建user表,添加数据

create database mybatis;
use mybatis;

drop table if exists tb_user;

create table tb_user(
	id int primary key auto_increment,
	username varchar(20),
	password varchar(20),
	gender char(1),
	addr varchar(30)
);


INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '男', '北京');
INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津');
INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');

2、创建模块,导入坐标

<!--        pom.xml  -->
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>mybatis-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
<!--        mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>
<!--        mysql依赖-->
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>
<!--        junit测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>
        <!-- 添加slf4j日志api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.20</version>
        </dependency>
        <!-- 添加logback-classic依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- 添加logback-core依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>

    </dependencies>

</project>

3、编写 MyBatis 核心配置文件 – > 替换连接信息 解决硬编码问题

<!--   mybatis-config.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">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
<!--        数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis?userSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
<!--        加载sql映射文件-->
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>

4、编写 SQL 映射文件 --> 统一管理sql语句,解决硬编码问题

<!-- UserMapper.xml  -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
    namespace:名称空间
    id:唯一标识
    resultType:返回结果的类型
 -->
<mapper namespace="test">
    <select id="selectAll" resultType="com.itheima.pojo.User">
        select * from tb_user;
    </select>
</mapper>

在这里插入图片描述

5、编码

1.1 定义POJO类

package com.itheima.pojo;

// alt+鼠标左键,整列编辑
// int 基础类型,使用包装类。避免初始化值不统一的问题,包装类的初始化值都为null
public class User {
    private Integer id        ;
    private String username  ;
    private String password  ;
    private String gender    ;
    private String addr      ;

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", gender='" + gender + '\'' +
                ", addr='" + addr + '\'' +
                '}';
    }
}

1.2 加载核心配置文件,获取 SqlSessionFactory 对象

1.3 获取 SqlSession 对象,执行 SQL 语句

1.4 释放资源

package com.itheima;

import com.itheima.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * MyBatisDemo快速入门代码
 */
public class MyBatisDemo {
    public static void main(String[] args) throws IOException {
//        1.加载mybatis的核心配置文件,获取 SqlSessionFactory 对象
//        在mybatis官网有代码案例
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//        2.获取 SqlSession 对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();

//        3.执行sql语句
//        参数是UserMapper.xml中 名称空间 的sql唯一标识(id):
//        List<User> users = sqlSession.selectList("test.selectAll");
        List<User> users = sqlSession.selectList("test.selectAll");

        System.out.println(users);

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

1.5 报错处理

(1)错误“ Java:不支持发行版本5”

解决方式1

直接Ctrl+shit+alt+s出现以下面版
在这里插入图片描述
因为我本地安装的jdk是14版本,所以这里显示的就是14版本,这里没有问题,然后向下找module模块,然后发现这里的langeage level居然是5.
在这里插入图片描述
修改到对应的版本,然后应用保存就可以关闭了。
在这里插入图片描述
然后去File里找Settings打开,在打开的页面中找到Build开头的那一串,接着找它下面Compiler下的java compiler,右侧还要修改成自己所使用的java版本
在这里插入图片描述

解决方式2

在 maven地址\conf\setting.xml中设置默认jdk版本…

代码:1.8是你自己的jdk版本号

  <profile>
      <id>development</id>
          <activation>
            <jdk>1.8</jdk>
            <activeByDefault>true</activeByDefault>
          </activation>
      <properties>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
            <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
      </properties>
 </profile>

将上述代码放到maven\conf\setting.xml中
在这里插入图片描述
重启idea
设置完成后,新建maven项目,不用修改设置即可编译成功.

6、Idea添加mysql连接

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.1 xml文件没有sql语法提示

在这里插入图片描述
在这里插入图片描述

1.2 仍没有解决的话

将光标随意移至一处SQL语句附近,按Alt+Enter,出现相关提示。
在这里插入图片描述
在这里插入图片描述

或者是:选择Language injection Settings,出现弹窗之后,在下图所指示位置,选择MySQL
在这里插入图片描述
在这里插入图片描述

三、Mapper 代理开发

  1. 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下
  2. 设置SQL映射文件的namespace属性为Mapper接口全限定名
  3. 在 Mapper 接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
  4. 编码
    • 通过 SqlSession 的 getMapper方法获取 Mapper接口的代理对象
    • 调用对应方法完成sql的执行

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

package com.itheima;

import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * MyBatisDemo代理开发
 */
public class MyBatisDemo2 {
    public static void main(String[] args) throws IOException {
//        1.加载mybatis的核心配置文件,获取 SqlSessionFactory 对象
//        在mybatis官网有代码案例
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//        2.获取 SqlSession 对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();

//        3.执行sql语句
//        参数是UserMapper.xml中 名称空间 的sql唯一标识(id):
//        List<User> users = sqlSession.selectList("test.selectAll");

//        3.获取对应的UserMapper接口的代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> users = userMapper.selectAll();

        System.out.println(users);

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

四、Mybatis核心配置文件说明

  • typeAliases:配置别名
  • environments:配置数据库的连接环境
  • mapper:加载sql映射文件
  • 注意:配置各个标签时,需要遵守前后顺序
<?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">
<configuration>

<!--    配置各个标签时,需要遵守前后顺序  -->

<!-- 配置别名,可以将name="com.itheima.pojo",省略不写,即在UserMapper.xml中,resultType=“user” -->
    <typeAliases>
        <package name="com.itheima.pojo"/>
    </typeAliases>

<!--
    environments:配置数据库的连接环境,可以配置多个environment,通过default控制连接哪个数据库
  -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
<!--        数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
<!--        test测试库   -->
        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--        数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
<!--        加载sql映射文件-->
        <mapper resource="com/itheima/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

五、Mybatis综合案例:增删改查

1、功能列表

  1. 查询
    • 查询所有数据
    • 查看详情
    • 条件查询
  2. 添加
  3. 修改
    • 修改全部字段
    • 修改动态字段
  4. 删除
    • 删除一个
    • 批量删除

2、准备环境

1.1 数据库表(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);


SELECT * FROM tb_brand;

1.2 实体类 Brand

com.itheima.pojo 包下创建 Brand 实体类。

public class Brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用  1:启用
    private Integer status;
    
    //省略 setter and getter。自己写时要补全这部分代码
}

1.3 编写测试用例

测试代码需要在 test/java 目录下创建包及测试用例。项目结构如下:
在这里插入图片描述

1.4 安装 MyBatisX 插件

  • MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

  • 主要功能

    • XML映射配置文件 和 接口方法 间相互跳转
    • 根据接口方法生成 statement
  • 安装方式

    点击 file ,选择 settings ,就能看到如下图所示界面
    在这里插入图片描述

  • 插件效果 在这里插入图片描述
    红色头绳的表示映射配置文件,蓝色头绳的表示mapper接口。
    在mapper接口点击红色头绳的小鸟图标会自动跳转到对应的映射配置文件,
    在映射配置文件中点击蓝色头绳的小鸟图标会自动跳转到对应的mapper接口。
    也可以在mapper接口中定义方法,自动生成映射配置文件中的 statement ,如图所示
    在这里插入图片描述

2.0 执行顺序

MyBatisTest.java:编写测试方法,进行调用接口。
BrandMapper.java:调用接口
BrandMapper.xml:编写sql语句

MyBatisTest.java --> BrandMapper.java --> BrandMapper.xml

3、查询所有数据

1.1 主要步骤

  1. 编写接口方法: Mapper接口
    • 参数:无
    • 结果:List<Brand>
  2. 编写 SQL语句: SQL映射文件:
  3. 执行方法,测试
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

1.2 问题处理:数据封装不全,有的为null

原因
数据库表的字段名称(带下划线),和 实体类的属性名称(驼峰) 不一样, 则不能自动封装数据。

(1)方案一:使用起别名+sql片段

  • 起别名:不用 *,用单独的字段,将字段起别名,别名跟实体类的属性名称保持一致
  • select id, brand_name as brandName, company_name as companyName, ordered, description, status from tb_brand;
  • 缺点:每次查询都要定义一次别名
  • 解决:用SQL片段的方式处理(但仍不灵活
<!-- BrandMapper.xml  -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
    namespace:名称空间
    id:唯一标识
    resultType:返回结果的类型
 -->
<mapper namespace="com.itheima.mapper.BrandMapper">

<!--
    数据库表的字段名称(带下划线),和 实体类的属性名称(驼峰)  不一样, 则不能自动封装数据
        * 起别名:不用*,用单独的字段,将字段起别名,别名跟实体类的属性名称保持一致
            * 缺点:每次查询都要定义一次别名
                * 解决:用SQL片段的方式处理(但仍不灵活)
-->


<!--    sql片段-->
	<sql id="brand_column">
        id, brand_name as brandName, company_name as companyName, ordered, description, status
    </sql>
    <select id="selectAll" resultType="com.itheima.pojo.Brand">
        select <include refid="brand_column"></include>
        from tb_brand;
    </select>

</mapper>

(2)方案二:resultMap方式

  1. 定义<resultMap>标签
  2. <select>标签中,使用 resultMap属性 替换 resultType属性
<!-- BrandMapper.xml  -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
    namespace:名称空间
    id:唯一标识
    resultType:返回结果的类型
 -->
<mapper namespace="com.itheima.mapper.BrandMapper">

<!--
    数据库表的字段名称(带下划线),和 实体类的属性名称(驼峰)  不一样, 则不能自动封装数据
        * resultMap:
            1. 定义<resultMap>标签
            2. 在<select>标签中,使用 resultMap属性 替换 resultType属性
-->
<!--
    id:唯一标识
    type:映射的类型,支持别名
-->
    <resultMap id="brandResultMap" type="com.itheima.pojo.Brand">
        <!--
                id:完成主键字段的映射
                    column:表的列名
                    property:实体类的属性名
                result:完成一般字段的映射
                    column:表的列名
                    property:实体类的属性名
            -->
        <result column="brand_name" property="brandName"/>
        <result column="company_name" property="companyName"/>
    </resultMap>
    <!--  在<select>标签中,使用 resultMap属性 替换 resultType属性  -->
        <select id="selectAll" resultMap="brandResultMap">
            select *
            from tb_brand;
        </select>
</mapper>

4、查询详情

1.1 主要步骤

  1. 编写接口方法: Mapper接口
    • 参数:id
    • 结果:Brand
  2. 编写 SQL语句: SQL映射文件:
  3. 执行方法,测试
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

1.2 注意事项

  1. 参数占位符:
    1)#{}:执行SQL时,会将#{}占位符替换为?,将来自动设置参数值
    2)${}:拼SQL。会存在SQL注入问题
    3)使用时机:
    * 参数传递,都使用#{}
    * 如果要对表名、列名进行动态设置,只能使用${}进行sql拼接。
  2. parameterType:
    • 用于设置参数类型,该参数可以省略
  3. SQL 语句中特殊字符处理:
    • 转义字符
    • <![CDATA[ 内容 ]]>: 输入CD会有提示

5、查询–多条件查询

1.1 主要步骤

  1. 编写接口方法: Mapper接口
    • 参数:所有查询条件
    • 结果:List<Brand>
  2. 编写 SQL语句: SQL映射文件:
  3. 执行方法,测试
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

1.2 注意事项

  • 查询-多条件查询

    • 参数接收(三种方式)
      1. 散装参数:如果方法中有多个参数,就需要使用@Param("参数名称") 标记每一个参数,在映射配置文件中就需要使用 #{参数名称} 进行占位
      2. 对象参数:对象的属性名称 要和 参数占位符名称 一致
      3. map集合:只需要保证SQL中的参数名 和 map集合的键的名称对应上,即可设置成功
  • 其实都是一个方法。只是看要不要对散装的参数进行组装而已。

1.3 问题:查询条件必须全部输入才可以查询到结果,不灵活

解决方案:参考:<6、查询--多条件查询-动态条件>

6、查询–多条件查询-动态条件

1.1 动态条件

动态条件,其实就是动态SQL,
而动态SQL其实就是SQL语句中加入if判断等语句。

Mybatis对动态SQL有很强大的支撑:

if
choose (when, otherwise)
trim (where, set)
foreach

只需要修改BrandMapper.xml文件,其他都不用变
在这里插入图片描述

7、查询–单条件查询-动态条件

1.1 单条件查询-动态查询是什么

在这里插入图片描述
如上图所示,在查询时只能选择 品牌名称当前状态企业名称 这三个条件中的一个,但是用户到底选择哪儿一个,我们并不能确定。这种就属于单个条件的动态SQL语句。

这种需求需要使用到 choose(when,otherwise)标签 实现, 而 choose 标签类似于Java 中的switch语句。
在这里插入图片描述

8、添加

1.1 主要步骤

  1. 编写接口方法: Mapper接口
    • 参数:除了id之外的所有数据
    • 结果:void
  2. 编写 SQL语句: SQL映射文件:
  3. 执行方法,测试

(1) 编写接口方法

BrandMapper 接口中定义添加方法。

 /**
   * 添加
   */
void add(Brand brand);

(2) 编写SQL语句

BrandMapper.xml 映射配置文件中编写添加数据的 statement

<insert id="add">
    insert into tb_brand (brand_name, company_name, ordered, description, status)
    values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
</insert>

(3) 编写测试方法

test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法

@Test
public void testAdd() throws IOException {
    //接收参数
    int status = 1;
    String companyName = "波导手机";
    String brandName = "波导";
    String description = "手机中的战斗机";
    int ordered = 100;

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

    //1. 获取SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //2. 获取SqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //SqlSession sqlSession = sqlSessionFactory.openSession(true); //设置自动提交事务,这种情况不需要手动提交事务了
    //3. 获取Mapper接口的代理对象
    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    //4. 执行方法
    brandMapper.add(brand);
    //提交事务
    sqlSession.commit();
    //5. 释放资源
    sqlSession.close();
}

1.2 添加-主键返回

在数据添加成功后,有时候需要获取插入数据库数据的主键(主键是自增长的情况下)。

比如:添加订单和订单项,如下图就是京东上的订单

订单数据存储在订单表中,订单项存储在订单项表中。

明白了什么时候 主键返回 。接下来我们简单模拟一下,在添加完数据后打印id属性值,能打印出来说明已经获取到了。

我们将上面添加品牌数据的案例中映射配置文件里 statement 进行修改,如下

<insert id="add" useGeneratedKeys="true" keyProperty="id">
    insert into tb_brand (brand_name, company_name, ordered, description, status)
    values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});
</insert>

在 insert 标签上添加如下属性:

  • useGeneratedKeys:是够获取自动增长的主键值。true表示获取
  • keyProperty :指定将获取到的主键值封装到哪儿个属性里

9、修改–修改全部字段

1.1 主要步骤

  1. 编写接口方法: Mapper接口
    • 参数:所有数据
    • 结果:void
  2. 编写 SQL语句: SQL映射文件:
  3. 执行方法,测试

(1) 编写接口方法

BrandMapper 接口中定义修改方法。

 /**
  * 修改
  * 返回值也可以是void
  */
 int update(Brand brand);

上述方法参数 Brand 就是封装了需要修改的数据,而id肯定是有数据的,这也是和添加方法的区别。

(2) 编写SQL语句

BrandMapper.xml 映射配置文件中编写修改数据的 statement

<update id="update">
    update tb_brand
    set
        brand_name = #{brandName},
        company_name = #{companyName},
        ordered = #{ordered},
        description = #{description},
        status = #{status}
    where id = #{id};
</update>

(3) 编写测试方法

test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法

@Test
    public void testUpdate() throws IOException {
//        接收参数,暂时写死
        int status = 1;
        String companyName = "111";
        String brandName = "111";
        String description = "2222";
        int ordered = 100;
        int id = 6;


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


//        1.加载mybatis的核心配置文件,获取 SqlSessionFactory 对象
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        2.获取 SqlSession 对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        SqlSession sqlSession = sqlSessionFactory.openSession(true);// 开启自动提交事务
//        3.获取对应的brandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//        4. 执行方法
        int count = brandMapper.update(brand);
        System.out.println(count);

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

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

10、修改–修改动态字段

(1) 编写SQL语句

set 标签可以用于动态包含需要更新的列,忽略其它不更新的列。

<update id="update">
    update tb_brand
    <set>
        <if test="brandName != null and brandName != ''">
            brand_name = #{brandName},
        </if>
        <if test="companyName != null and companyName != ''">
            company_name = #{companyName},
        </if>
        <if test="ordered != null">
            ordered = #{ordered},
        </if>
        <if test="description != null and description != ''">
            description = #{description},
        </if>
        <if test="status != null">
            status = #{status}
        </if>
    </set>
    where id = #{id};
</update>

(2) 编写测试方法

test/java 下的 com.itheima.mapper 包下的 MybatisTest类中 定义测试方法

@Test
public void testUpdate() throws IOException {
    //接收参数
    int status = 0;
    String companyName = "波导手机";
    String brandName = "波导";
    String description = "波导手机,手机中的战斗机";
    int ordered = 200;
    int id = 6;

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

    //1. 获取SqlSessionFactory
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    //2. 获取SqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //SqlSession sqlSession = sqlSessionFactory.openSession(true);
    //3. 获取Mapper接口的代理对象
    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    //4. 执行方法
    int count = brandMapper.update(brand);
    System.out.println(count);
    //提交事务
    sqlSession.commit();
    //5. 释放资源
    sqlSession.close();
}

11、删除–一行数据

(1) 编写测试方法

@Test
    public void testDeleteById() throws IOException {
//        接收参数,暂时写死
        int id = 6;

//        1.加载mybatis的核心配置文件,获取 SqlSessionFactory 对象
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        2.获取 SqlSession 对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        SqlSession sqlSession = sqlSessionFactory.openSession(true);// 开启自动提交事务
//        3.获取对应的brandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//        4. 执行方法
        brandMapper.deleteById(id);

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

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

(2) 编写接口方法

 /**
  * 删除一行数据
  */
 void deleteById(int id);

(3) 编写接口方法

<!--    删除一行数据 -->
 <delete id="deleteById">
     delete from tb_brand where id = #{id};
 </delete>

12、删除–批量删除

(1) 编写测试方法

@Test
    public void testDeleteByIds() throws IOException {
//        接收参数,暂时写死
        int[] ids = {5,7,8};

//        1.加载mybatis的核心配置文件,获取 SqlSessionFactory 对象
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        2.获取 SqlSession 对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        SqlSession sqlSession = sqlSessionFactory.openSession(true);// 开启自动提交事务
//        3.获取对应的brandMapper接口的代理对象
        BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//        4. 执行方法
        brandMapper.deleteByIds(ids);

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

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

(2) 编写接口方法

/**
 * 批量删除
 */
void deleteByIds(int[] ids);

(3) 编写接口方法

<!--    批量删除 -->
    <delete id="deleteByIds">
        delete from tb_brand where id
        in
        <foreach collection="array" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
        ;
    </delete>

编写SQL时需要遍历数组来拼接SQL语句。Mybatis 提供了 foreach 标签供我们使用

foreach 标签

用来迭代任何可迭代的对象(如数组,集合)。

  • collection 属性:
    • mybatis会将数组参数,封装为一个Map集合。
      • 默认:array = 数组
      • 使用@Param注解改变map集合的默认key的名称
  • item 属性:本次迭代获取到的元素。
  • separator 属性:集合项迭代之间的分隔符。foreach 标签不会错误地添加多余的分隔符。也就是最后一次迭代不会加分隔符。
  • open 属性:该属性值是在拼接SQL语句之前拼接的语句,只会拼接一次
  • close 属性:该属性值是在拼接SQL语句拼接后拼接的语句,只会拼接一次

@Param方式

(2) 编写接口方法

/**
 * 批量删除
 */
void deleteByIds(@Param("ids") int[] ids);

(3) 编写接口方法

<!--    collection属性的值,发生了改变 -->
<!--    批量删除 -->
    <delete id="deleteByIds">
        delete from tb_brand where id
        in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
        ;
    </delete>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/180695.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

英语语法大全

文章目录一、主语1、名词、代词和动词做主语2、主语从句做主语&#xff0c;谓语动词用单数3、主语从句练习二、谓语动词1、谓语动词种类2、主谓一致三、宾语1、单宾语2、双宾语3、复合宾语4、宾语从句四、定语1、定语从句2、定语从句的翻译五、状语1、分词做状语2、独立主格结构…

42.Isaac教程--超像素

超像素 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 超像素是一组外观相似的相连像素。 超像素分割将图像分成数百个不重叠的超像素&#xff08;而不是数千或数百万个单独的像素&#xff09;。通过使用超像素&#xff0c;您可以在更有意义的区…

ESP-C3入门2. Clion+IDF 开发环境搭建

ESP-C3入门2. ClionIDF 开发环境搭建一、准备工作二、Clion配置过程1. 使用idf.py命令创建一个范例工程2. 使用Clion打开项目&#xff0c;修改CMakeLists.txt3. 设置交叉编译工具链4. 设置CMake5. 对cmake一些路径进行修改。三、编译及烧录1. 编译2. 烧录3. 查看输出一、准备工…

审核中台业务数据进审升级之路

本文字数&#xff1a;3850字预计阅读时间&#xff1a;15 分钟目录1.背景1.1. 相关名词介绍1.2. 审核中台介绍1.3. 业务痛点介绍2. 规范化改造2.1 规范通讯协议2.2 规范处理流程3. 自动化改造3.1 业务接入检测器3.2 数据自动化流转3.3 源码示例4. 总结1.背景1.1 相关名词介绍1.1…

计算机图形学基础教程(Visual C++版)习题解答与编程实践(第2版)孔令德1-到第3章的直线扫描转换

1-到第3章的直线扫描转换&#xff08;没更新完&#xff09;习题1知识积累习题2知识点映射模式使用GDI对象习题3知识积累直线的中点Bresenham算法习题1 1.计算机图形学的定义是什么?说明计算机图形学、图像处理和模式识别之间的关系。 答&#xff1a; CG是计算机图形学的缩写。…

实验一、旅馆客户服务呼叫显示系统

实验一 旅馆客户服务呼叫显示系统 实验目的 综合应用数字电子技术知识&#xff0c;按照要求设计并完成一个小规模的数字电路系统。进行硬件线路的设计、仿真、焊接、调试与实现。使系统实现一种用于旅馆客户服务呼叫显示系统的实用电路。在呼叫过程中&#xff0c;当8位旅客有…

Spark Core ---- RDD持久化

RDD的数据是过程数据 RDD之间进行相互迭代计算&#xff08;Transformation的转换&#xff09;&#xff0c;当执行开启后&#xff0c;新RDD的生成&#xff0c;代表老RDD的消失 RDD的数据是过程数据&#xff0c;只在处理的过程中存在&#xff0c;一旦处理完成&#xff0c;就不见…

【数据结构和算法】实现带头双向循环链表(最复杂的链表)

前文&#xff0c;我们实现了认识了链表这一结构&#xff0c;并实现了无头单向非循环链表&#xff0c;接下来我们实现另一种常用的链表结构&#xff0c;带头双向循环链表。如有仍不了解单向链表的&#xff0c;请看这一篇文章(7条消息) 【数据结构和算法】认识线性表中的链表&…

Spring Boot之SpringSecurity学习

文章目录一 SpringSecurity简介二 实战演示0. 环境 介绍1. 新建一个初始的springboot项目2. 导入thymeleaf依赖3. 导入静态资源4. 编写controller跳转5. 认证和授权6. 权限控制和注销7. 记住登录8. 定制登录页面三 完整代码3.1 pom配置文件3.2 RouterController.java3.3 Securi…

那些面试官口中常常提到b树(MySQL索引底层数据结构)

各种常见树1.树的基本概念2.二叉树3.b树4.b树5.b树与b树的对比5.MySQL索引底层数据结构1.树的基本概念 树的特点&#xff1a;有一个树根&#xff0c;树根上又有很多枝干&#xff0c;枝干上又有很多树枝&#xff0c;树枝上又有很多叶子 树最为一种数据结构也有相似特点 树是一个…

【计算机网络(考研版)】第二站:物理层(一)

前言 如下图所示&#xff0c;这是我们之前所说的数据流动示意图 我们将按照从下向上的结构进行学习。这一讲学习第一层物理层。物理层关注在一条通信信道上传输原始比特&#xff0c;即无论面对什么样的传输介质(有线或者无线)都可以传输比特流&#xff0c;物理层的作用正是要尽…

Python3 函数

函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现单一&#xff0c;或相关联功能的代码段。 函数能提高应用的模块性&#xff0c;和代码的重复利用率。你已经知道Python提供了许多内建函数&#xff0c;比如print()。但你也可以自己创建函数&#xff0c;这被叫做用户…

Node require 正解

require 实现原理 流程概述 步骤1&#xff1a;尝试执行代码require("./1"). 开始调用方法require.步骤2&#xff1a;此时会得到filename&#xff0c;根据filename 会判断缓存中是否已经加载模块&#xff0c;如果加载完毕直接返回&#xff0c;反之继续执行步骤3&…

JavaScript 的数据类型

JavaScript 的数据类型 基本数据类型&#xff08;值类型&#xff09; Number&#xff08;包含小数、整数、负数、科学计数法&#xff09; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"…

【Linux】六、Linux 基础IO(四)|动态库和静态库

目录 十一、动态库和静态库 11.1 动态库和静态库定义 11.2 动静态库的基本原理 11.3 静态库的打包与使用 11.3.1 静态库的打包 11.3.2 静态库的使用 11.4 动态库的打包与使用 11.4.1 动态库的打包 11.4.2 动态库的使用 11.5 动态库的加载 十一、动态库和静态库 11.1…

CB2-2CARD的openSUSE安装NAS环境配置

CB2-2CARD的openSUSE安装&NAS环境配置1. 简介2. 规格3. 系统安装3.1 Linux/Unix稳定镜像3.2 基础功能更新&安装3.2.1 更新源3.2.2 升级系统3.2.3 基础功能安装3.3 OpenSUSE系统情况3.3.1 源操作命令3.3.2 源镜像4. 需求 & 配置4.1 MiniDLNAStep 1&#xff1a;安装M…

Day870.全局锁和表锁 -MySQL实战

全局锁和表锁 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于全局锁和表锁的内容。 数据库锁设计的初衷是处理并发问题。 作为多用户共享的资源&#xff0c;当出现并发访问的时候&#xff0c;数据库需要合理地控制资源的访问规则。锁就是用来实现这些访问规则的重…

数据结构 | C++ | 并查集原理讲解与模拟实现 | 并查集的相关习题

文章目录前言并查集原理并查集的模拟实现leetcode练习省份数量等式方程的可满足性前言 并查集通常会作为高阶数据结构的一个子结构使用&#xff0c;虽然原理不是很难&#xff0c;但其思想值得我们好好学习 并查集原理 并查集是一种树形结构&#xff0c;其保存了多个集合&…

【Maven】多环境配置与应用

目录 1. 多环境配置作用 问题导入 2. 多环境配置步骤 2.1 定义多环境 2.2 使用多环境&#xff08;构建过程&#xff09; 3. 跳过测试&#xff08;了解&#xff09; 问题导入 3.1 应用场景 3.2 跳过测试命令 3.3 细粒度控制跳过测试 1. 多环境配置作用 问题导入 多…

LeetCode 2331. 计算布尔二叉树的值

给你一棵 完整二叉树 的根&#xff0c;这棵树有以下特征&#xff1a; 叶子节点 要么值为 0 要么值为 1 &#xff0c;其中 0 表示 False &#xff0c;1 表示 True 。 非叶子节点 要么值为 2 要么值为 3 &#xff0c;其中 2 表示逻辑或 OR &#xff0c;3 表示逻辑与 AND 。 计算…