MyBatis 快速入门

MyBatis 快速入门

  • 前言
  • 什么是 MyBatis
    • 简介
    • 核心特性
    • 使用示例
      • 配置文件
      • Mapper 接口
      • SQL 映射文件
      • 使用 MyBatis
  • = = = = = = = = 如果大家对以上的导读很懵怎么办!没关系 往下阅读! = = = = = = = = =
  • 1. MyBatis 介绍
    • 1.1. 什么是MyBatis
    • 1.2. 持久层
    • 1.3. 框架
    • 1.4. JDBC 弊端
    • 1.5. MyBatis 简化
  • 2. MyBatis 快速入门
    • 2.1. 查询user表中所有数据
    • 2.2. 解决 SQL 映射文件的警告提示
  • 3. Mapper 代理开发
    • 3.1. 目的
    • 3.2. 使用 Mapper 代理方式完成入门案例
  • 4. MyBatis 核心配置文件
    • 4.1. 类型别名(typeAliasess)
    • 4.2. 数据库配置连接环境信息
  • 5. 配置文件完成增删改查
    • 5.1. 准备环境
      • 5.1.1. 数据库表 tb_brand
      • 5.1.2. 实体类 Brand
      • 5.1.3. 测试用例
      • 5.1.4. 安装MyBatiisX 插件
    • 5.2. 查询
      • 5.2.1. 查询所有数据
      • 5.2.2. 查看详情
      • 5.2.3. 条件查询
        • 1.多条件查询
        • 2.多条件-动态条件查询
        • 3.单条件-动态条件查询
    • 5.3. 添加
      • 5.3.1. 主键返回
    • 5.4. 修改
      • 5.4.1. 修改全部字段
      • 5.4.2. 修改动态字段
    • 5.5. 删除
      • 5.5.1. 删除一个
      • 5.5.2. 批量删除
  • 6. 参数传递
    • 6.1. 单个参数
    • 6.2. 多个参数
  • 7. 注解完成增删改查

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

前言

跟着B站学:黑马mybatis教程全套视频教程,2天Mybatis框架从入门到精通

什么是 MyBatis

简介

MyBatis 是一种开源的持久层框架,它简化了数据库交互的过程,使得与数据库的交互更加灵活和高效。MyBatis 通过将 SQL 语句与 Java 代码进行分离,提供了一种直观的、面向对象的数据库访问方式。

核心特性

  1. 简化数据库访问:MyBatis 使用简单的 XML 或注解配置,将 SQL 语句和 Java 对象映射关系定义在配置文件中,从而实现了数据操作的解耦。

  2. 灵活的 SQL 编写:MyBatis 支持使用原生的 SQL 语句,可以根据需求编写复杂的查询语句,同时也提供了动态 SQL 的功能,使得在运行时动态生成 SQL 语句成为可能。

  3. 对象关系映射(ORM):通过配置文件或注解,MyBatis 能够将数据库中的记录映射到 Java 对象上,实现了对象和数据库表之间的简单映射,减少了手动处理数据转换的工作。

  4. 缓存机制:MyBatis 提供了一级缓存和二级缓存的支持,可以提高查询性能,避免不必要的数据库交互。

  5. 插件机制:MyBatis 允许用户编写插件,扩展框架的功能,例如自定义拦截器来实现日志记录、性能监控等功能。

使用示例

配置文件

<!-- mybatis-config.xml -->
<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://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="password"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/example/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

Mapper 接口

// UserMapper.java
public interface UserMapper {
    User getUserById(int id);
    List<User> getAllUsers();
    void insertUser(User user);
    void updateUser(User user);
    void deleteUser(int id);
}

SQL 映射文件

<!-- UserMapper.xml -->
<mapper namespace="com.example.mapper.UserMapper">
    <select id="getUserById" resultType="User" parameterType="int">
        SELECT * FROM users WHERE id = #{id}
    </select>

    <select id="getAllUsers" resultType="User">
        SELECT * FROM users
    </select>

    <insert id="insertUser" parameterType="User">
        INSERT INTO users (id, username, email) VALUES (#{id}, #{username}, #{email})
    </insert>

    <update id="updateUser" parameterType="User">
        UPDATE users SET username=#{username}, email=#{email} WHERE id=#{id}
    </update>

    <delete id="deleteUser" parameterType="int">
        DELETE FROM users WHERE id=#{id}
    </delete>
</mapper>

使用 MyBatis

// 使用 MyBatis 进行数据库操作
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();

UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

// 查询用户
User user = userMapper.getUserById(1);
System.out.println(user);

// 查询所有用户
List<User> userList = userMapper.getAllUsers();
System.out.println(userList);

// 插入用户
User newUser = new User(4, "NewUser", "newuser@example.com");
userMapper.insertUser(newUser);
sqlSession.commit();

// 更新用户
User updatedUser = new User(4, "UpdatedUser", "updateduser@example.com");
userMapper.updateUser(updatedUser);
sqlSession.commit();

// 删除用户
userMapper.deleteUser(4);
sqlSession.commit();

// 关闭会话
sqlSession.close();

以上示例演示了 MyBatis 的基本用法,通过配置文件定义数据源、Mapper 接口定义数据操作,以及 SQL 映射文件将 SQL 语句与 Java 方法进行映射。MyBatis 的灵活性和简洁性使得它成为许多 Java 项目中首选的持久层框架之一。

= = = = = = = = 如果大家对以上的导读很懵怎么办!没关系 往下阅读! = = = = = = = = =

1. MyBatis 介绍

1.1. 什么是MyBatis

  • MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发
  • MyBatis 本是 Apache 的一个开源项目 iBatis,2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis。2013 年 11 月迁移到 Github
  • 官网:点击前往

1.2. 持久层

  • 负责将数据到保存到数据库的那一层代码
  • JavaEE三层架构:表现层、业务层、持久层

1.3. 框架

  • 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
  • 在框架的基础之上构建软件编写更加高效、规范、通用、可扩展

1.4. JDBC 弊端

在这里插入图片描述

1.5. MyBatis 简化

在这里插入图片描述

注册驱动——写到配置文件中
在这里插入图片描述
SQL硬编码——写到配置文件中
在这里插入图片描述

操作繁琐
在这里插入图片描述

MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作

来看看对持久层框架优化!

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

2. MyBatis 快速入门

2.1. 查询user表中所有数据

  1. 创建user表,添加数据
  2. 创建模块, 导入坐标
  3. 编写MyBatis核心配置文件→替换连接信息解决硬编码问题
  4. 编写SQL映射文件→统一管理sq|语句,解决硬编码问题
  5. 编码
    1. 定义POJO类
    2. 加载核心配置文件,获取SqlSessionFactory 对象
    3. 获取SqlSession对象,执行SQL语句
    4. 释放资源

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

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)创建模块,导入坐标

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
模块创建结束

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

<?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>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <!--mybatis 依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>

        <!--mysql 驱动-->
        <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>

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--    console表示当前日志信息是可以输出到控制台的-->
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%level]  %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern>
        </encoder>
    </appender>
    <logger name="com.Carter_x" level="DEBUG" additivity="false">
        <appender-ref ref="Console"/>
    </logger>
</configuration>

从XML中构建SqlSessionFactory
每个基纡MyBatis的应用都是以一个Sq|SessionFactory的实例为核心的。SqlSessionFactory 的实例可以通过Sq|SessionFactoryBuilder获得。而SqlSessionFactoryBuilder则可以从XML配置文件或一个预先配置的Configuration实例来构建出SqlISessionFactory实例。

从XML文件中构建SqlSessionFactory的实例非常简单,建议使用类路径下的资源文件进行配置。但也可以使用任意的输入流 (InputStream) 实例,比如用文件路径字符串或fle:// URL构造的输入流。MyBatis 包含一个名叫 Resources的工具类,它包含一实用方法,使得从类路径或其它位置加载资源文件更加容易。

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

3)编写 MyBatis 核心

XML 配置文件中包含了对 MyBatis 系统的核心设置,包括获取数据库连接实例的数据源(DataSource)以及决定事务作用域和控制方式的事务管理器(TransactionManager)。后面会再探讨 XML 配置文件的详细内容,这里先给出一个简单的示例:

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

    <typeAliases>
        <package name="com.itheima.pojo"/>
    </typeAliases>
    
    <!--
    environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment
    -->
    <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?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>

        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="1234"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--加载sql映射文件-->
       <!-- <mapper resource="com/itheima/mapper/UserMapper.xml"/>-->

        <!--Mapper代理方式-->
        <package name="com.itheima.mapper"/>
    </mappers>
</configuration>

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

探究已映射的 SQL 语句
现在你可能很想知道 SqlSession 和 Mapper 到底具体执行了些什么操作,但 SQL 语句映射是个相当广泛的话题,可能会占去文档的大部分篇幅。 但为了让你能够了解个大概,这里先给出几个例子。

在上面提到的例子中,一个语句既可以通过 XML 定义,也可以通过注解定义。我们先看看 XML 定义语句的方式,事实上 MyBatis 提供的所有特性都可以利用基于 XML 的映射语言来实现,这使得 MyBatis 在过去的数年间得以流行。如果你用过旧版本的 MyBatis,你应该对这个概念比较熟悉。 但相比于之前的版本,新版本改进了许多 XML 的配置,后面我们会提到这些改进。这里给出一个基于 XML 映射语句的示例,它应该可以满足上个示例中 SqlSession 的调用。

<?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">

<!--
    namespace:名称空间
-->

<mapper namespace="com.itheima.mapper.UserMapper">

    <!--statement-->
    <select id="selectAll" resultType="user">
        select * from tb_user;
    </select>
<!--    <select id="selectById" resultType="user">
        select *
        from tb_user where id = #{id};

    </select>-->


    <select id="select" resultType="user">
        select *
        from tb_user
        where
            username = #{arg0}
        and password = #{param2}
    </select>


</mapper>

5)编码

5-1. 定义 POJO 类

package com.itheima.pojo;


// alt + 鼠标左键 整列编辑
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 + '\'' +
                '}';
    }
}

5-2. 加载核心配置文件,获取 SqlSessionFactory 对象

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

在这里插入图片描述

5-3. 获取 SqlSession 对象,执行 SQL 语句

在这里插入图片描述

5-4. 释放资源

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

在这里插入图片描述

2.2. 解决 SQL 映射文件的警告提示

在这里插入图片描述

  • 产生原因:Idea 和数据库没有建立连接,不识别表信息
  • 解决方式:在 Idea 中配置 MySQL 数据库连接


在这里插入图片描述

在这里插入图片描述

3. Mapper 代理开发

3.1. 目的

在这里插入图片描述

又写si了…

  • 解决原生方式中的硬编码
  • 简化后期执行 SQL

在这里插入图片描述

3.2. 使用 Mapper 代理方式完成入门案例

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

在这里插入图片描述

1.定义与 SQL 映射文件同名的 Mapper 接口,并且将 Mapper 接口和 SQL 映射文件放置在同一目录下

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
不方便管理!!!
要配置文件与代码 分开!那怎么办啊

那我是不是只需要建立相同层级!

——注意:Mapper文件的包容易出错,建包时可写成 " com/itheima/mapper "

在这里插入图片描述
在这里插入图片描述
但是 现在我们显示的还是
在这里插入图片描述
我们把xml文件拖进来

编译!我们发现确实在一起了


2.设置 SQL 映射文件的 namespace 属性为 Mapper 接口全限定名

3.在 Mapper 接口中定义方法,方法名就是 SQL 映射文件中sql语句的 id,并保持参数类型和返回值类型一致

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

4.编码

  • 通过 SqlSession 的 getMapper 方式获取 Mapper 接口的代理对象
  • 调用对应方法完成 sql 的执行
//2. 获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 获取Mapper接口的代理对象
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 执行方法
List<Brand> brands = brandMapper.selectAll();
System.out.println(brands);

包扫描!

在这里插入图片描述

在这里插入图片描述

4. MyBatis 核心配置文件

配置
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:

  • configuration(配置)
    • properties(属性)
    • settings(设置)
    • typeAliases(类型别名)
    • typeHandlers(类型处理器)
    • objectFactory(对象工厂)
    • plugins(插件)
    • environments(环境配置)
      • environment(环境变量)
        • transactionManager(事务管理器)
        • dataSource(数据源)
    • databaseIdProvider(数据库厂商标识)
    • mappers(映射器)
  • 官网:点击前往

注意:配置各个标签,需要遵循前后顺序

4.1. 类型别名(typeAliasess)

<typeAliases>
	<package name="com.itheima.pojo"/>
</typeAliases>

在这里插入图片描述
相当于 给POJO下的实体类起了个别名 默认的情况下 就是 类本身的名不区分大小写 且不用带包
在这里插入图片描述

在这里插入图片描述
细节:配置各个标签时,需要遵守前后顺序

在这里插入图片描述

4.2. 数据库配置连接环境信息

在这里插入图片描述

在这里插入图片描述

5. 配置文件完成增删改查

在这里插入图片描述

在这里插入图片描述

5.1. 准备环境

  • 数据库表tb brand
  • 实体类Brand
  • 测试用例
  • 安装MyBatisX插件

5.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;

5.1.2. 实体类 Brand

package com.itheima.pojo;

/**
 * 品牌
 *
 * alt + 鼠标左键:整列编辑
 *
 * 在实体类中,基本数据类型建议使用其对应的包装类型
 */

public class Brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    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 Integer getOrdered() {
        return ordered;
    }

    public void setOrdered(Integer ordered) {
        this.ordered = ordered;
    }

    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 + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}

当前的层级关系
在这里插入图片描述

5.1.3. 测试用例

在这里插入图片描述

5.1.4. 安装MyBatiisX 插件

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

在这里插入图片描述

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

MyBatis 本身是一个用于在 Java 中进行持久性数据访问的开源框架。如果 “MyBatiisX” 是 MyBatis 的插件,那么安装它可能会带来一些好处,具体取决于该插件提供的功能。

一般来说,MyBatis 插件可以提供以下一些好处:

  1. 增强功能: 插件可以扩展或增强 MyBatis 的功能,为开发人员提供更多的选项和工具来简化开发过程。

  2. 性能优化: 一些插件可能专注于提高 MyBatis 的性能,通过优化查询或缓存策略,以提高应用程序的响应速度。

  3. 简化配置: 插件可能提供一些简化配置的功能,使得在使用 MyBatis 的过程中更加方便。

  4. 集成其他技术: 插件可以用于集成其他技术或框架,使得 MyBatis 能够更好地与其他组件协同工作。

  5. 代码生成: 一些插件可能提供代码生成的功能,可以减少手动编写重复性代码的工作。

请注意,具体的好处取决于插件的具体功能和你的项目需求。在考虑安装任何插件之前,建议查看插件的文档,了解它提供了什么功能以及它是否适合你的项目。此外,插件的稳定性、维护情况以及社区支持也是考虑的因素之一。

在这里插入图片描述

5.2. 查询

5.2.1. 查询所有数据

在这里插入图片描述

  1. 编写接口方法: Mapper接口

    • 参数:无
    • 结果: List< Brand>
    • List<Brand> selectAll();
  2. 编写SQL语句: SQL映射文件

<select id="selectAll" resultType="brand">
	select * from tb_ brand;
</select>
  1. 执行方法,测试

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

怎么办!!!!!!!

属性名与列名不一致

1)起别名:在 SQL 语句中,对不一样的类名起别名,别名与实体类属性名一样。可以定义 < sql> 片段,提升复用性。

<!-- * 起别名:对不一样的列名起别名,让别名和实体类的属性名一样
   * 缺点:每次查询都要定义一次别名
* sql片段
   * 缺点:不灵活
-->
<!-- sql片段 -->
    <sql id="brand_column">
         id, brand_name as brandName, company_name as companyName, ordered, description, status
     </sql>

     <select id="selectAll" resultType="brand">
         select
             <include refid="brand_column" />
         from tb_brand;
     </select>

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

<!--
    id:唯一标识
    type:映射的类型,支持别名
-->

<resultMap id="brandResultMap" type="brand">
    <!--
        id:完成主键字段的映射
            column:表的列名
            property:实体类的属性名
        result:完成一般字段的映射
            column:表的列名
            property:实体类的属性名
    -->
    <result column="brand_name" property="brandName"/>
    <result column="company_name" property="companyName"/>
</resultMap>



<select id="selectAll" resultMap="brandResultMap">
    select *
    from tb_brand;
</select>

在这里插入图片描述

5.2.2. 查看详情

  1. 编写接口方法: Mapper接口
    • 参数: id
    • 结果: Brand
    • Brand selectByld(int id);
  2. 编写SQL语句: SQL 映射文件
<select id="selectByld" parameterType="int" resultType="brand">
	select * from tb_ brand where id = #{id};
</select>
  1. 执行方法,测试

在这里插入图片描述

使用细节

  1. 参数占位符:

    • 1) #{}: 执行SQL时,会将#{}占位符替换为?,将来自动设置参数值
      1. ${}: 拼sQL。会存在SQL注入问题
      1. 使用时机:
      • 参数传递,都使用#{}
      • 如果要对表名、列名不固定 ,进行动态设置,只能使用${}进行sq|拼接。
  2. parameterType:

    • 用于设置参数类型,该参数可以省略
    • 在这里插入图片描述
  3. SQL语句中特殊字符处理:

    • 转义字符&lt
    • <![CDATA[内容]]>: `CD提示`
    • 在这里插入图片描述

在这里插入图片描述

5.2.3. 条件查询

1.多条件查询
  1. 编写接口方法: Mapper接口
    • 参数:所有查询条件
    • 结果: List < Brand>
List<Brand> selectByCondition(@Param("status')int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
List<Brand> selectByCondition(Brand brand);
List<Brand> selectByCondition(Map map);
  1. 编写SQL语句: SQL映射文件
  2. 执行方法,测试
<select id="selectByCondition" resultMap="brandResultMap">
	select *
	from tb brand
	where
		status = #{status}
		and company_ name like #{companyName}
		and brand_ name like #{brandName}
</select>

在这里插入图片描述

SQL 语句设置多个参数的三种方式

1)散装参数:需要使用 @Param (" SQL 中的参数占位符名称")

List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);

2)实体类封装参数:只需要保证 SQL 中的参数名和实体类属性名对应上,即可设置成功

List<Brand> selectByCondition(Brand brand);

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

List<Brand> selectByConditionSingle(Brand brand);

测试代码:
MyBatisTest

@Test
    public void testSelectByCondition() throws IOException {
        //接收参数
        int status = 1;
        String companyName = "华为";
        String brandName = "华为";

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

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

        Map map = new HashMap();
        // map.put("status" , status);
        map.put("companyName", companyName);
        // map.put("brandName" , brandName);

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

        //2. 获取SqlSession对象
        SqlSession sqlSession = sqlSessionFactory.openSession();

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

        //4. 执行方法

        //List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);
//        List<Brand> brands = brandMapper.selectByCondition(brand);
        List<Brand> brands = brandMapper.selectByCondition(map);
        System.out.println(brands);

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

    }

在这里插入图片描述

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

在这里插入图片描述
动态 SQL

动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。

如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach
<!--
        动态条件查询
            * if: 条件判断
                * test:逻辑表达式
            * 问题:
                * 恒等式  where 1 = 1
                * <where> 替换 where 关键字
    -->
    <select id="selectByCondition" resultMap="brandResultMap">
        select *
        from tb_brand
        /* where 1 = 1*/
        <where>

            <if test="status != null">
                and status = #{status}
            </if>
            <if test="companyName != null and companyName != '' ">
                and company_name like #{companyName}
            </if>
            <if test="brandName != null and brandName != '' ">
                and brand_name like #{brandName}
            </if>
        </where>

    </select>

where 就是我们之前说的到的 可以灵活的去掉and

在这里插入图片描述

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

在这里插入图片描述

<select id="selectByConditionSingle" resultMap="brandResultMap">
        select *
        from tb_brand
        <where>
            <choose><!--相当于switch-->
                <when test="status != null"><!--相当于case-->
                    status = #{status}
                </when>
                <when test="companyName != null and companyName != '' "><!--相当于case-->
                    company_name like #{companyName}
                </when>
                <when test="brandName != null and brandName != ''"><!--相当于case-->
                    brand_name like #{brandName}
                </when>

            </choose>
        </where>
    </select>

在这里插入图片描述

在这里插入图片描述

5.3. 添加

在这里插入图片描述

在这里插入图片描述

5.3.1. 主键返回

在这里插入图片描述

返回添加主键返回

<insert useGeneratedKeys="true" keyProperty="id">
<insert id="addOrderltem" >
	insert into tb_ order_item (goods_name, goods_price, count,order_id)
	values (#{goodsName} #{goodsPrice},#{count}, #{orderld});
</insert>

生成了 但是没有绑定到对象上面!

<insert id="addOrder" useGeneratedKeys="true" keyProperty="id">
	insert into tb_order (payment, payment_type, status)I
	values (#{payment},#{paymentType},#{status});
</insert>

在这里插入图片描述

5.4. 修改

5.4.1. 修改全部字段

在这里插入图片描述

  1. 编写接口方法: Mapper接口

    • 参数:所有数据
    • 结果: void
    • void update(Brand brand);
  2. 编写SQL语句: SQL映射文件

  3. 执行方法,测试

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

在这里插入图片描述

5.4.2. 修改动态字段

在这里插入图片描述

  1. 编写接口方法: Mapper接口
    • 参数:部分数据,封装到对象中
    • 结果: void
  2. 编写SQL语句: SQL映射文件
  3. 执行方法,测试
<update id="update">
	update tb_user
	set
		username = #{username},
		password = #{password},
		gender = #{gender},
		addr = #{addr}
	where
		id = #{id}
</update>

不能用到通用性,因为只能全改 否则就是赋值成null了
到👇

<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>

在这里插入图片描述

5.5. 删除

5.5.1. 删除一个

  1. 编写接口方法: Mapper接口

    • 参数: id
    • 结果: void
    • void deleteByld(int id);
  2. 编写SQL语句: SQL映射文件

  3. 执行方法,测试

<delete id="deleteByld">
	delete from tb_brand where id = #{id}
</delete>

5.5.2. 批量删除

在这里插入图片描述

  1. 编写接口方法: Mapper接口
    • 参数: id数组
    • 结果: void
    • void deleteBylds(@Param("ids") int[] ids);
  2. 编写SQL语句: SQL映射文件
  3. 执行方法,测试
<delete id="deleteBylds">
	delete from tb_brand
	where id in (?,?,?)
</delete>

不知道用几个问号啊!
所以要动态!!!!

<!--
        mybatis会将数组参数,封装为一个Map集合。
            * 默认:array = 数组
            * 使用@Param注解改变map集合的默认key的名称
    -->

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

在这里插入图片描述

6. 参数传递

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

建议:将来都使用 @Param 注解来修改 Map 集合中默认的键名,并使用修改后的名称获取值,这样可读性更高

6.1. 单个参数

  • POJO类型:直接使用,属性名 和 参数占位符名称一致
  • Map集合:直接使用,键名 和 参数占位符名称一致
  • Collection:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put("arg0",collection集合);
map.put("collection",collection集合);

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

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

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

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

其他类型:直接使用

在这里插入图片描述

6.2. 多个参数

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

map.put("arg0",参数值1)
        map.put("param1",参数值1)
        map.put("param2",参数值2)
        map.put("agr1",参数值2)
        ---------------@Param("username")
        map.put("username",参数值1)
        map.put("param1",参数值1)
        map.put("param2",参数值2)
        map.put("agr1",参数值2)

在这里插入图片描述

7. 注解完成增删改查

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

写了注解 就不需要写xml的配置文件了

@Select("select * from tb_user where id = #{id}")
public User selectByld(int id);
  • 查询: @Select
  • 添加: @Insert
  • 修改: @Update
  • 删除:@Delete

提示:

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

使用注解来映射简单语句会使代码显得更加简洁但对于稍微复杂一点的语句, Java 注解不仅力不从心,还会让你本就复杂的SQL语句更加混乱不堪。因此, 如果你需要做一些很复杂的操作, 最好用XML来映射语句。

选择何种方式来配置映射,以及认为是否应该要统映射语句定义的形式,完全取决于你和你的团队。换句话说,永远不要拘泥于一种方式, 你可以很轻松的在基于注解和XML的语句映射方式间自由移植和切换。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java】网络编程基础—InetAddress类和URL编程

&#x1f33a;个人主页&#xff1a;Dawn黎明开始 &#x1f380;系列专栏&#xff1a;Java ⭐每日一句&#xff1a;为了那个远方&#xff0c;你要奋不顾身 &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️ 文章目录 一.&#x…

【开源】基于Vue.js的独居老人物资配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统展示四、核心代码4.1 查询社区4.2 新增物资4.3 查询物资4.4 查询物资配送4.5 新增物资配送 五、免责说明 一、摘要 1.1 项目介绍 基于JAVAVueSpringBootMySQL的独居老人物资配送系统&#xff0c;包含了社区档案、…

C++模拟实现——红黑树封装set和map

一、红黑树迭代器的实现 基本的框架和实现链表的迭代器思路是一样的&#xff0c;都是对指针进行封装处理&#xff0c;然后实现一些基本的运算符重载&#xff0c;最重要的是operator&#xff0c;需要不递归的实现走中序的规则&#xff0c;这里只实现那最核心的几个基本功能&…

Day35力扣打卡

打卡记录 相邻字符不同的最长路径&#xff08;树状DP&#xff09; 链接 若节点也存在父节点的情况下&#xff0c;传入父节点参数&#xff0c;若是遍历到父节点&#xff0c;直接循环里 continue。 class Solution:def longestPath(self, parent: List[int], s: str) -> in…

如何看待人工智能行业发展

随着人工智能技术的飞速发展&#xff0c;这个领域的就业前景也日益广阔。人工智能在各行各业都有广泛的应用&#xff0c;包括医疗、金融、制造业、教育等。因此&#xff0c;对于想要追求高薪、高技能职业的人来说&#xff0c;学习人工智能是一个非常有前景的选择。 首先&#x…

【Python进阶】近200页md文档14大体系知识点,第4篇:linux命令和vim使用

本文从14大模块展示了python高级用的应用。分别有Linux命令&#xff0c;多任务编程、网络编程、Http协议和静态Web编程、htmlcss、JavaScript、jQuery、MySql数据库的各种用法、python的闭包和装饰器、mini-web框架、正则表达式等相关文章的详细讲述。 全套Python进阶笔记地址…

阿里云ECS11月销量王 99元/年

这一波好像真没得说&#xff0c;老用户居然都有份&#xff0c;买来练习、测试冒似已经够了&#xff01; 阿里云ECS11月销量王 99元/年 2核2G 3M固定带宽不限流量&#xff0c;新老同享&#xff0c;新购、续费同价&#xff0c;开发必备&#xff01; 活动规则 云服务器ECS 云创季…

读像火箭科学家一样思考笔记03_第一性原理(上)

1. 思维的两种障碍 1.1. 为什么知识会成为一种缺陷而非一种美德 1.1.1. 知识是一种美德 1.1.2. 知识同样的特质也会把它变成一种缺点 1.1.3. 知识确实是个好东西&#xff0c;但知识的作用应该是给人们提供信息&#xff0c;而不是起约束作用 1.1.4. 知识应该启发智慧&#…

程序员告诉你:人工智能是什么?

随着科技的快速发展&#xff0c;人工智能这个词汇已经逐渐融入了我们的日常生活。然而&#xff0c;对于大多数人来说&#xff0c;人工智能仍然是一个相对模糊的概念。 首先&#xff0c;让我们从人工智能的定义开始。人工智能是一种模拟人类智能的技术&#xff0c;它涵盖了多个领…

【Flink】系统架构

DataStream API 将你的应用构建为一个 job graph&#xff0c;并附加到 StreamExecutionEnvironment 。当调用 env.execute() 时此 graph 就被打包并发送到 JobManager 上&#xff0c;后者对作业并行处理并将其子任务分发给 Task Manager 来执行。每个作业的并行子任务将在 task…

微服务调用链路追踪

概述 本文介绍微服务调用链路追踪&#xff0c;涉及技术有&#xff1a;sleuth和zipkin。sleuth负责追踪调用链路数据&#xff0c;zipkin负责调用链路数据可视化展现。 本文的操作是在 服务网关实践 的基础上进行。 环境说明 jdk1.8 maven3.6.3 mysql8 spring cloud2021.0.8 …

Linux socket编程(4):服务端fork之僵尸进程的处理

在上一节利用fork实现服务端与多个客户端建立连接中&#xff0c;我们使用fork函数来实现服务端既可以accept新的客户端连接请求&#xff0c;又可以接收已连接上的客户端发来的消息。但在Linux中&#xff0c;在子进程终止后&#xff0c;父进程需要处理该子进程的终止状&#xff…

人力资源小程序

人力资源管理对于企业的运营至关重要&#xff0c;而如今随着科技的发展&#xff0c;制作一个人力资源小程序已经变得非常简单和便捷。在本文中&#xff0c;我们将为您介绍如何通过乔拓云网制作一个人力资源小程序&#xff0c;只需五个简单的步骤。 第一步&#xff1a;注册登录乔…

练习题——【学习补档】库函数的模拟实现

各种库函数的模拟实现 一、模拟实现strlen1.地址-地址型2.递归型3.计数器型 二、模拟实现strcpy三、模拟实现strcmp四、模拟实现strcat五、模拟实现strstr 一、模拟实现strlen 模拟实现strlen有三种方法 1.地址-地址型 2.递归型 3.计数器型1.地址-地址型 // //1.地址-地址型 …

学霸教你自学人工智能

在这个信息爆炸的时代&#xff0c;人工智能已经渗透到我们生活的方方面面。无论是语音助手、自动驾驶汽车&#xff0c;还是医疗诊断&#xff0c;人工智能都在发挥着越来越重要的作用。如果你对人工智能充满热情&#xff0c;希望在这个领域有所建树&#xff0c;那么&#xff0c;…

STM32CubeMX学习笔记-CAN接口使用

STM32CubeMX学习笔记-CAN接口使用 CAN总线传输协议1.CAN 总线传输特点2.位时序和波特率3.帧的种类4.标准格式数据帧和遥控帧从STM32F407参考手册中可以看出主要特性如下CAN模块基本控制函数CAN模块消息发送CAN模块消息接收标识符筛选发送中断的事件源和回调函数 CubeMX项目设置…

庖丁解牛:NIO核心概念与机制详解 04 _ 分散和聚集

文章目录 Pre概述分散/聚集 I/O分散/聚集的应用聚集写入Code Pre 庖丁解牛&#xff1a;NIO核心概念与机制详解 01 庖丁解牛&#xff1a;NIO核心概念与机制详解 02 _ 缓冲区的细节实现 庖丁解牛&#xff1a;NIO核心概念与机制详解 03 _ 缓冲区分配、包装和分片 概述 分散/聚…

C++二分查找算法:有序矩阵中的第 k 个最小数组和

本文涉及的基础知识点 二分查找算法合集 本题的简化 C二分查找算法&#xff1a;查找和最小的 K 对数字 十分接近m恒等于2 题目 给你一个 m * n 的矩阵 mat&#xff0c;以及一个整数 k &#xff0c;矩阵中的每一行都以非递减的顺序排列。 你可以从每一行中选出 1 个元素形成…

FPGA_IIC代码-正点原子 野火 小梅哥 特权同学对比写法(3)

FPGA_IIC代码-正点原子 野火 小梅哥 特权同学对比写法&#xff08;3&#xff09; 工程目的IIC时序图IIC 读写操作方法汇总正点原子IIC实验工程整体框图和模块功能简介&#xff0c;如表下图所示&#xff1a; IIC 驱动模块设计时钟规划状态跳转流程单次写操作的波形图如下图所示&…

程序员带你入门人工智能

随着人工智能技术的飞速发展&#xff0c;越来越多的程序员开始关注并学习人工智能。作为程序员&#xff0c;我们可能会对如何开始了解人工智能感到困惑。今天&#xff0c;我将向大家介绍一些如何通过自学了解人工智能的经验和方法&#xff0c;帮助大家更好地入门这个充满挑战和…