大数据------JavaWeb------MyBatis(完整知识点汇总)

MyBatis

MyBatis简介

  • 定义

    • 它是一款优秀的持久层框架,用于简化JDBC开发
    • 它原来是Apache的一个开源项目iBatis,后来改名为MyBatis
    • 中文官网:https://mybatis.org/mybatis-3/zh_CN/index.html
  • JaveEE三层架构

    • 表现层(做页面展示)
    • 业务层(做逻辑处理)
    • 持久层(负责将数据保存到数据库的那一层代码。即做数据持久化的)
  • 框架

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

    • 硬编码
      • 将一些字符串信息写到代码中,且这些字符串信息后续可能会有所改变,比如:注册驱动和获取连接的部分
    • 操作繁琐
      • 手动设置参数:比如利用PreparedStatement类中的public void setXxx(参数1,参数2)方法来对SQL语句中的?进行赋值时,若?较多,则需要调用多次该方法,这样就比较繁琐
      • 手动封装ResultSet结果集:封装结果集时需要将结果集中需要的数据拿出来然后放到对象中,最后将对象放到集合中,比较繁琐

    MyBatis可将造成硬编码部分的代码写到配置文件中;将操作繁琐部分的代码简化,如下图所示

    在这里插入图片描述

  • MyBatis优点

    • 是一款优秀的持久层框架
    • 支持自定义 SQL、存储过程以及高级映射
    • 免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作
    • 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  • MyBatis两种版本

    • 普通版------MyBatis
    • 增强版------MyBatis-Plus

MyBatis环境搭建

MyBatis快速入门(可跟着MyBatis官网的入门来操作)

示例:查询user表中所有的数据

  • 步骤

    • 第一步:创建mybatis数据库并在该数据库中创建tb_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)L,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', '男', '西安');
      

      在这里插入图片描述

    • 第二步:创建模块(该模块是Maven的项目),导入坐标

      • 创建MyBatis的Maven模块

        在这里插入图片描述

      • 导入坐标:从官网的入门中可看到将图示以来写到pom.xml文件中即可,其中x.x.x为MyBatis的版本号。MyBatis导入后也要导入MySQL的坐标依赖以及其它多个需要用到的相关依赖(依赖导入方法可详见Maven部分),具体代码详见下述

        在这里插入图片描述

            <dependencies><!--MyBatis依赖--><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.16</version></dependency><!--mysql驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!--Junit单元测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!--添加slf4j日志api--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>2.0.12</version></dependency><!--添加logback-classic依赖--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.5.6</version><scope>test</scope></dependency><!--添加logback-core依赖--><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.4.14</version></dependency></dependencies>
        
    • 第三步:编写SQL映射文件(统一管理sql语句,解决JDBC的硬编码问题)

      • 写sql映射文件(对应官网 探究已映射的 SQL 语句 ):在该Maven项目的源代码配置文件目录(即main包下的resources目录下)创建一个userMapper.xml文件,然后将官网的简单示例代码复制到该文件中进行对应修改,该文件代码简单示例如下

        sql映射文件命名规范tableNameMapper.xml即要操作的表名后加上Mapper,比如我现在要用该映射文件操作stu表,则sql映射文件名为stuMapper.xml

        <?xml version="1.0" encoding="UTF-8" ?>
        <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间
        -->
        <mapper namespace="test"><!--id:为sql语句的唯一标识resultType:为对应sql语句执行完毕后返回结果的类型假设我要将其执行的结果封装到一个类中则此时该属性后的值就应该为全类名由于我现在是对user表进行操作的,所以我就将执行结果保存到一个user类中所以就需要先在Maven项目的源代码java文件目录(即main包下的java目录下)创建一个user类,该类中的属性和方法随后再写即可,此处先创建出来是为了让resultType有属性值然后resultType="at.guigu.pojo.User"--><select id="selectAll" resultType="at.guigu.pojo.User">select * from tb_user;</select>
        </mapper>
        

        注意:

        ​ 若要将sql语句的查询结果封装成一个对象则该数据封装的对象一般放在名为pojo的包中

        ​ 若嫌弃resultType的属性值太长造成冗余,可为其设置别名

        在这里插入图片描述

    • 第四步:编写MyBatis核心配置文件(替换连接信息,解决JDBC的硬编码问题)

      • 从官网的入门中可看到将依赖导入到pom.xml文件后需要构建SqlSessionFactory(可在XML中构建,也可不使用XML构建)

        在这里插入图片描述

      • 在XML中构建SqlSessionFactory的步骤如下:

        1. 在该Maven项目的源代码配置文件目录(即main包下的resources目录下)创建一个mybatis-config.xml文件,然后将官网的简单示例粘贴进去即可,官网代码示例如下所示

          <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE configurationPUBLIC "-//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.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false&amp;serverTimezone=Asia/Shanghai"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><mappers><!--加载SQL映射文件:传入sql映射文件的路径--><mapper resource="UserMapper.xml"/></mappers>
          </configuration>
          

          由于mybatis-config.xml文件和UserMapper.xml文件均在一个目录下,属于同一级,所以在传入sql映射文件路径时直接写入该文件名即可

    • 第五步:编码

      • 定义POJO类(对于数据封装的对象一般放在名为pojo的包中)

        在刚刚创建的实体类User类中写入自己想要的sql语句执行后的结果的属性及方法

        package at.guigu.pojo;public class User {private int id;private String username;private String password;private String gender;private String addr;public User() {}public User(int id, String username, String password, String gender, String addr) {this.id = id;this.username = username;this.password = password;this.gender = gender;this.addr = addr;}public int getId() {return id;}public void setId(int 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;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +", gender='" + gender + '\'' +", addr='" + addr + '\'' +'}';}
        }
        
      • 源代码java文件目录创建类:加载核心配置文件,获取SqlSessionFactory对象;然后获取SqlSession对象,执行SQL语句;随后释放资源

        • 类中来加载MyBatis核心配置文件并获取SqlSessionFactory对象,获取该对象代码如下(直接从官网复制即可,不需记忆):

          //配置mybatis-config.xml文件路径
          String resource = "org/mybatis/example/mybatis-config.xml";
          //利用Resources类中的静态方法将配置文件加载到内存
          InputStream inputStream = Resources.getResourceAsStream(resource);
          获取SqlSessionFactory对象
          SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 
          
        • 获取SqlSession对象,执行SQL语句,使用的接口、类及方法如下

          SqlSessionFactory接口的方法解释
          SqlSession openSession()获取SqlSession对象
          SqlSession接口的方法解释
          <E> List<E> selectList(String statement)执行sql语句。参数为namespace.id

        代码如下:

        package at.guigu;import at.guigu.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;public class MyBatisDemoOne {public static void main(String[] args) throws Exception {//1 加载核心配置文件,获取`SqlSessionFactory`对象//1.1 配置mybatis-config.xml文件路径,由于该文件直接在resources目录下,所以直接写文件名即可String resource = "mybatis-config.xml";//1.2 利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream = Resources.getResourceAsStream(resource);//1.3 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2 获取SqlSession对象,执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.2 执行sql语句List<User> users = sqlSession.selectList("test.selectAll");System.out.println(users);}
        }
        

        注意 :在该代码中,<E> List<E> selectList(String statement)方法的参数仍会造成硬编码问题,因为不同的sql语句有不同的namespace和id,为解决该问题,可详见Mapper代理开发部分

问题解决

SQL映射文件的标红警告提示

在这里插入图片描述

  • 产生原因

    • idea和数据库未建立连接,导致idea不能识别表信息从而标红
  • 解决方法:在idea中配置mysql数据库连接信息

    • 按图示操作即可

      在这里插入图片描述

      在这里插入图片描述

      在这里插入图片描述

  • 该方法不仅是SQL映射文件的标红警告提示的方法,还是可以在idea中直接操作数据库的方法

    • idea与数据库连接后可在idea中新建写sql语句的console面板来操作数据库,如图所示

      在这里插入图片描述

      idea中写sql语句时很强大,自动提示和补全比较牛

Mapper代理开发

在这里插入图片描述

  • 作用

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

    在这里插入图片描述

  • Mapper代理开发步骤及要求

    • 第一步:定义与SQL映射文件同名的Mapper接口(Maven项目中接口统一在一个包中,此处假设mapper包中写接口类),并且将Mapper接口和SQL映射文件放置在同一个目录下

      • 定义与SQL映射文件同名的Mapper接口:由于博主的sql映射文件名为UserMapper.xml,所以接口名为UserMapper

      • 将Mapper接口和SQL映射文件放置在同一个目录下:在该Maven项目的源代码配置文件目录(即main包下的resources目录下)创建多层目录,多层目录对应Mapper接口所在的多层包,比如我的UserMapper接口在at.guigu.mapper包下,则此时就在resources目录下创建多层目录格式为at/guigu/mapper,然后将sql映射文件UserMapper.xml拖入到该mapper目录下

        在这里插入图片描述

      • 右键UserMapper.xmlSQL映射文件→Copy Path/ReferencePath From Source Root,复制UserMapper.xmlSQL映射文件现在的路径,然后更改mybatis-config.xmlMyBatis核心配置文件中sql映射文件的路径即可。

    • 第二步:设置SQL映射文件UserMapper.xml的namespace属性为Mapper接口的全限定名,修改后的代码如下所示

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间
      -->
      <mapper namespace="at.guigu.mapper.UserMapper"><!--id:为sql语句的唯一标识resultType:为对应sql语句执行完毕后返回结果的类型假设我要将其执行的结果封装到一个类中则此时该属性后的值即为全类名由于我现在是对user表进行操作的,所以我就将执行结果保存到一个user类中所以就需要先在Maven项目的源代码java文件目录(即main包下的java目录下)创建一个user类然后resultType="at.guigu.pojo.User"--><select id="selectAll" resultType="at.guigu.pojo.User">select * from tb_user;</select>
      </mapper>
      
    • 第三步:在Mapper接口UserMapper中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致

      • 由SQL映射文件可知,方法名为selectAll,返回值类型为User。然后判断对应的sql语句的返回结果是一个结果还是多个结果,若是一个则在接口中定义一个对象即可;若是多个则需定义集合,将来执行sql语句后的结果就会直接放在集合中

      在这里插入图片描述

    • 第四步:编码

      • 通过SqlSession的getMapper方法获取Mapper接口的代理对象
      • 调用对应方法完成sql语句的执行
    • 第三四步代码如下

      package at.guigu.pojo;import at.guigu.mapper.UserMapper;
      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;//MyBatis代理开发
      public class MyBatisDemoTwo {public static void main(String[] args) throws IOException {//1 加载核心配置文件,获取`SqlSessionFactory`对象//1.1 配置mybatis-config.xml文件路径,由于该文件直接在resources目录下,所以直接写文件名即可String resource = "mybatis-config.xml";//1.2 利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream = Resources.getResourceAsStream(resource);//1.3 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2 获取SqlSession对象,执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//2.3 执行sql语句List<User> users = userMapper.selectAll();System.out.println(users);}
      }
      

      在这里插入图片描述

  • 注意:若Mapper接口名称和SQL映射文件名称相同并且在同一目录下则可使用包扫描的方式简化SQL映射文件的加载

    • 由Mapper代理开发的要求可知,SQL映射文件的名称与对应Mapper接口的名称一定相同且Mapper接口与对应的SQL映射文件均在同一个目录下

      • 此处在同一个目录下是近似看作在同一个目录下,以博主的项目代码为例:UserMapper接口在java目录下的at.guigu.mapper包下,而对应的SQL映射文件在resources目录下的at.guigu.mapper目录下,由于目录结构相同,所以可近似看作在同一个目录下。此时MyBatis核心配置文件中sql映射文件的路径,就可写为如下形式:
      <mappers><!--加载SQL映射文件--><!--<mapper resource="at/guigu/mapper2/UserMapper.xml">--><package name="at.guigu.mapper"/>
      </mappers>
      
    • 优点:以后项目大的话就会有多个SQL映射文件,原来的方式(即<mapper resource="at/guigu/mapper2/UserMapper.xml">)只是一次加载一个映射文件,而现在的新方式(即<package name="at.guigu.mapper"/>)是加载该目录下的所有映射文件,不需要重复使用<mapper resource="SQL映射文件路径">来加载SQL映射文件

MyBatis核心配置文件(mybatis-config.xml)

  • 该核心配置文件中可进行的配置内容详见官网中的XML配置

    在这里插入图片描述

  • 部分标签解释如下(其它标签可详见官网)

    标签解释
    typeAliases设置包下单个类的类型别名或设置包下所有类的类型别名
    environments配置数据库连接环境信息,可配置多个environment,并通过default属性来切换不同的environment
    mappers定义 SQL 映射文件

设置别名

在MyBatis核心配置文件中设置别名(即mybatis-config.xml)

假设我在at.guigu.pojo包下由有多个实体类,实体类的全类名如下:

at.guigu.pojo.Author
at.guigu.pojo.Blog
at.guigu.pojo.Comment
at.guigu.pojo.Post
at.guigu.pojo.Section
at.guigu.pojo.Tag
  • 给单个类的全类名设置类型别名方式一

    <typeAliases><typeAlias alias="Author" type="at.guigu.pojo.Author"/><typeAlias alias="Blog" type="at.guigu.pojo.Blog"/><typeAlias alias="Comment" type="at.guigu.pojo.Comment"/><typeAlias alias="Post" type="at.guigu.pojo.Post"/><typeAlias alias="Section" type="at.guigu.pojo.Section"/><typeAlias alias="Tag" type="at.guigu.pojo.Tag"/>
    </typeAliases>
    
    • 设置完成后在SQL映射文件中定义resultType属性的属性值时即可不用写类的全类名,写其别名即可

      <select id="selectById" resultType="Author"></select>
      <select id="selectById" resultType="Blog"></select>
      <select id="selectById" resultType="Comment"></select>
      <select id="selectById" resultType="Post"></select>
      <select id="selectById" resultType="Section"></select>
      <select id="selectById" resultType="Tag"></select>
      
    • 博主自己的示例图如下

      在这里插入图片描述

  • 给单个类的全类名设置类型别名方式二:利用@Alias("别名")注解为类的全类名设置类型别名

    • 博主自己的示例图如下

    在这里插入图片描述

  • 给包下的所有类的全类名设置类型别名

    <typeAliases><package name="at.guigu.pojo"/>
    </typeAliases>
    
    • 此时相当于给at.guigu.pojo包下的所有类设置类型别名,该包下所有类的类型别名为对应类的首字母小写的类名,比如

      Author的类型别名为author
      Blog的类型别名为blog
      Comment的类型别名为comment
      Post的类型别名为post
      Section的类型别名为section
      Tag的类型别名为tag
      
    • 博主自己的示例图如下

      在这里插入图片描述

  • 注意

    • typeAliases标签在MyBatis核心配置文件中的顺序必须按照官网的顶层结构来写,写在environments标签之前
    • 若在MyBatis的核心配置文件中给某个类设置了别名后又利用注解给该类设置了别名,则会以注解设置的别名为准

MyBatis参数传递注意形式

在这里插入图片描述

  • MyBatis接口的方法可接收各种参数,它的底层会对不同的参数进行不同的封装处理(MyBatis底层提供了一个类ParamNameResolver来封装参数),参数总体有两类
    • 单个参数
      • POJO类型:将sql语句的查询结果封装成一个对象则该数据封装的对象一般放在名为pojo的包中。
      • Map集合、Collection集合、List集合、Array数组、其他类型(即基本数据类型或String类型等)
    • 多个参数
      • 多个参数时要利用注解@Param("参数")来将对应的方法参数放到SQL映射文件中SQL语句对应的参数占位符
  • 需要加@Param("参数")注解的有
    • 单个参数
      • Collection集合、List集合、Array(数组):它们几个都会被封装到Map集合中
    • 多个参数

MyBatis注解开发

  • 特点:

    • 传统的MyBatis是将SQL语句写在SQL映射文件中,而MyBatis注解开发是将SQL语句写在注解中

    • 使用注解开发要比使用配置文件开发更方便

    • 注解直接在对应接口的方法上,如图所示

      在这里插入图片描述

  • 用到的注解

    注解解释
    @Select选择数据
    @Insert插入数据
    @Update修改或更新表中数据
    @Delete删除表中数据
  • 注意

    • 注解是适用于简单的SQL语句,若要做一些复杂的SQL语句则最好使用XML映射
    • 即注解完成简单功能,配置文件完成复杂功能

MyBatis案例

在这里插入图片描述

  • 示例:完成品牌数据的增删改查操作
  • 要完成的功能列表清单
    • 查询
      • 查询所有数据
      • 查看详情
      • 条件查询
    • 添加
    • 修改
      • 修改全部字段
      • 修改动态字段
    • 删除
      • 删除一个
      • 批量删除

环境准备

  • 在mybatis数据库中创建数据库表tb_brand

    DROP TABLE IF EXISTS tb_brand;-- 创建品牌表brand
    CREATE TABLE IF NOT EXISTS 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;
    
  • 创建实体类Brand------若要将sql语句的查询结果封装成一个对象则该数据封装的对象一般放在名为pojo的包中

    package at.guigu.pojo;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 Brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {this.id = id;this.brandName = brandName;this.companyName = companyName;this.ordered = ordered;this.description = description;this.status = 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;}@Overridepublic String toString() {return "Brand{" +"id=" + id +", brandName='" + brandName + '\'' +", companyName='" + companyName + '\'' +", ordered=" + ordered +", description='" + description + '\'' +", status=" + status +'}';}
    }
    
  • 测试用例------写在测试代码java文件目录(即Maven项目的test目录下的java目录下)

    在这里插入图片描述

  • 安装MyBatisX插件

    在这里插入图片描述

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

    • 功能

      • XML和接口方法互相跳转

        • 安装完成后如图所示,接口中的方法及SQL映射文件中会对应出现小鸟,单击小鸟可实现XML和接口中方法的自动跳转

          在这里插入图片描述

      • 根据接口方法生成statement(即SQL语句)

        • 若接口中新写一个方法,该方法在SQL映射文件中并未定义SQL语句,则此时可借助该插件实现自动生成statement(即SQL语句),如下图所示

        在这里插入图片描述

        在这里插入图片描述

        在这里插入图片描述

实现功能列表清单

查询

查询所有数据
  • 代码略详见快速入门

  • 问题: 由于封装数据的类中属性名和数据库中表的字段名不一致(如图一)可能会造成最终结果显示不出来(如图二)

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

    在这里插入图片描述

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    • 解决方式一: 在SQL映射文件中对SQL语句中的字段名称起别名(即将数据库表中的字段名称的别名设置为与实体类的属性名称对应一样),如下代码所示

      • 该方法有个缺点:即每次查询都需要设置别名,所以详见解决方式二
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
      <mapper namespace="at.guigu.mapper.BrandMapper"><!--    <select id="selectAll" resultType="at.guigu.pojo.User">--><select id="selectAll" resultType="brand">
      <!--        select * from tb_brand;  改为如下形式-->select id, brand_name brandName, company_name companyName, ordered, description, statusfrom tb_brand;</select><!--    <select id="selectById" resultType="at.guigu.pojo.User">--><select id="selectById" resultType="brand">select * from tb_brand where id = #{id};</select></mapper>
      
    • 解决方式二: 在SQL映射文件中定义SQL片段并引用SQL片段

      • 该方法缺点:不灵活,若SQL片段中是所有的字段名,此时假如只需要查询若干个字段名怎么办
      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
      <mapper namespace="at.guigu.mapper.BrandMapper"><!--定义SQL片段--><sql id = "brand_column">id, brand_name brandName, company_name companyName, ordered, description, status</sql><select id="selectAll" resultType="brand"><!--引入SQL片段-->select <include refid="brand_column" />from tb_brand;</select><!--    <select id="selectById" resultType="at.guigu.pojo.User">--><select id="selectById" resultType="brand">select * from tb_brand where id = #{id};</select>
      </mapper>
      
    • 解决方式三: 利用<resultMap id="" type="">映射配置</resultMap>标签

      id:唯一标识此 resultMap 的 ID,一般命名为目标Java类名+ResultMap,即id = “brandResultMap”

      type:指定结果映射的目标 Java 类的完全限定名(全类名)(注意:支持使用别名)。MyBatis 会将查询结果映射到这个类的实例。此处type = "at.guigu.pojo.Brand"type = "brand"

      • 解释:用于定义一个**结果映射** ,指定如何将 SQL 查询结果集中的列映射到 Java 对象的属性。

      • 可用的标签体标签体

        标签体解释
        <id property= "Java类属性名" column="SQL字段名">标识主键列
        <result property="Java类属性名" column="SQL字段名"/>标识非主键列
        <association property="Java类属性名" javaType="java类全类名"></association>处理嵌套对象的映射,可以嵌套 <resultMap> 标签或者其他 <result>, <id> 标签
        <collection property="Java类属性名" ofType="com.example.Order"></collection>处理嵌套集合的映射,可以嵌套 <resultMap> 标签或者其他 <result>, <id> 标签。(注意:ofType的属性值为:集合中元素的 Java 类型。)
      • 具体过程详见如下xml文件

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
      <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName"/><result column="company_name" property="companyName"/></resultMap><!--将resultType改为resultMap且属性值为resultMap标签中id的属性值--><select id="selectAll" resultMap="brandResultMap">select * from tb_brand;</select>
      </mapper>
      
查看详情

在这里插入图片描述

  • 解释

    查看详情是通过返回对应的序号给后台,然后后台通过id找到对应数据传输到前端供浏览者获取信息,由于一个id对应一个品牌的信息,所以返回的是一个对象

    Mapper接口中定义的方法为Brand selectById(int id);

    SQL映射文件中的SQL语句为

    <select id="selectById" parameterType="int" resultMap="brandResultMap">select * from tb_brand where id = #{id};<!--#{id}用于接收传入的参数,相当于select * from tb_brand where id = ?;-->
    </select>
    
    • 注意:参数占位符来代替要传入SQL语句的参数

      • #{} :可放置SQL注入

      • ${} :存在SQL注入问题(最好不要用这个参数占位符,只有在表名或列名不固定的情况下才使用该参数占位符)

        select * from tb_brand where id = ${id};
        <!--假设传入参数为1则相当于select * from tb_brand where id = 1;-->
        
    • 注意2:<select></select>标签中的属性parameterType可设置传入的参数类型 ,它可以省略不写

    • 注意3:特殊字符处理(可详见day18XML知识点)

      • 利用转义字符:即XML文件中的特殊字符

        1. &lt;------<------小于
        2. &gt;------>------大于
        3. &amp;------&------和号
        4. &apos;------'------单引号
        5. &quot;------"------引号
        <!--    查看详情--><select id="selectById" parameterType="int" resultMap="brandResultMap">select * from tb_brand where id &gt #{id};</select>
        
      • 将特殊字符写在CDATA

        <!--    查看详情-->
        <select id="selectById" parameterType="int" resultMap="brandResultMap">select * from tb_brand where id <![CDATA[>]]>#{id};</select>
        
      • 特殊字符比较少时用转义字符,反之则用CDATA区

  • 完整代码如下

    • SQL映射文件

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
      <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--查询所有数据--><select id="selectAll" resultMap="brandResultMap">select * from tb_brand;</select><!--    查看详情--><select id="selectById" parameterType="int" resultMap="brandResultMap">select * from tb_brand where id = #{id};</select></mapper>
      
    • 接口

      package at.guigu.mapper;import at.guigu.pojo.Brand;
      import org.apache.ibatis.annotations.Param;import java.util.List;
      import java.util.Map;public interface BrandMapper {//查询所有数据List<Brand> selectAll();//查看详情Brand selectById(int id);
      }
      
    • 测试代码

      package at.guigu.test;import at.guigu.mapper.BrandMapper;
      import at.guigu.pojo.Brand;
      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 org.junit.Test;import java.io.IOException;
      import java.io.InputStream;
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;public class MyBatisTest {private static BrandMapper getBrandMapper() throws IOException {//1 加载核心配置文件,获取`SqlSessionFactory`对象//1.1 配置mybatis-config.xml文件路径,由于该文件直接在resources目录下,所以直接写文件名即可String resource = "mybatis-config.xml";//1.2 利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream = Resources.getResourceAsStream(resource);//1.3 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2 获取SqlSession对象,执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);return brandMapper;}//查询所有数据@Testpublic void testSelectAll() throws IOException {//获取Mapper接口对象BrandMapper brandMapper = getBrandMapper();//2.3 执行sql语句List<Brand> brands = brandMapper.selectAll();System.out.println(brands);}//查看详情@Testpublic void testSelectById() throws IOException {int id = 1;//接收前端传回的序号//获取Mapper接口对象BrandMapper brandMapper = getBrandMapper();//2.3 执行sql语句Brand brands = brandMapper.selectById(id);System.out.println(brands);}
      }
      
普通多条件查询

在这里插入图片描述

在这里插入图片描述

  • 编写接口方法的方式有三种

    在这里插入图片描述

    • 方式一散装参数接收: 定义含多个参数的接口方法时,要通过@Param("参数")注解来将对应的方法参数放到SQL映射文件中SQL语句对应的参数占位符上,其中注解参数名称要和SQL映射文件中SQL语句中的参数占位符名称对应一致
    • 方式二对象参数接收: 若三个参数都属于同一个对象的话则可以将它们封装成一个对象,然后将对象作为一个参数,即List<Brand> selectByCondition(Brand brand),此时SQL映射文件中SQL语句对应的参数占位符会自动从对象中找对应的值(前提是对象中的属性名称要和SQL语句中参数占位符名称一致)
    • 方式三Map集合参数接收: 可将以上三个参数封装到Map集合中作为键,并给其对应的键值,然后将Map集合作为一个参数,即List<Brand> selectByCondition(Map map),此时SQL映射文件中SQL语句对应的参数占位符会自动从对象中找对应的值(前提是Map集合中的键名要和SQL语句中参数占位符名称一致)
    • 以上三种方式在SQL映射文件中SQL语句的写法是一样的,如下,不一样的是接口中使用了方法重载以及运行的代码
  • 完整代码如下

    • SQL映射文件

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
      <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--多条件查询--><select id="selectByCondition" resultMap="brandResultMap">select * from tb_brandwherestatus = #{status} andcompany_name like #{companyName} andbrand_name like #{brandName}</select></mapper>
      
    • Mapper接口

      package at.guigu.mapper;import at.guigu.pojo.Brand;
      import org.apache.ibatis.annotations.Param;import java.util.List;
      import java.util.Map;public interface BrandMapper {//查询所有数据List<Brand> selectAll();//查看详情Brand selectById(int id);//多条件查询方式一:散装参数接收List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);//多条件查询方式二:对象参数接收List<Brand> selectByCondition(Brand brand);//多条件查询方式三:Map集合参数接收List<Brand> selectByCondition(Map map);
      }
      
    • 测试代码

      package at.guigu.test;import at.guigu.mapper.BrandMapper;
      import at.guigu.pojo.Brand;
      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 org.junit.Test;import java.io.IOException;
      import java.io.InputStream;
      import java.util.HashMap;
      import java.util.List;
      import java.util.Map;public class MyBatisTest {private static BrandMapper getBrandMapper() throws IOException {//1 加载核心配置文件,获取`SqlSessionFactory`对象//1.1 配置mybatis-config.xml文件路径,由于该文件直接在resources目录下,所以直接写文件名即可String resource = "mybatis-config.xml";//1.2 利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream = Resources.getResourceAsStream(resource);//1.3 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2 获取SqlSession对象,执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);return brandMapper;}//多条件查询方式一:散装参数接收@Testpublic void testSelectByCondition() throws IOException {//接收前端传回的多条件参数int status = 1;String companyName = "华为";String brandName = "华为";//处理参数companyName = "%" + companyName + "%";brandName = "%" + brandName + "%";//获取Mapper接口对象BrandMapper brandMapper = getBrandMapper();//2.3 执行sql语句List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);System.out.println(brands);}//多条件查询方式二:对象参数接收@Testpublic void testSelectByConditionTwo() 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);//获取Mapper接口对象BrandMapper brandMapper = getBrandMapper();//2.3 执行sql语句List<Brand> brands = brandMapper.selectByCondition(brand);System.out.println(brands);}//多条件查询方式三:Map集合参数接收@Testpublic void testSelectByConditionThree() throws IOException {//接收前端传回的多条件参数int status = 1;String companyName = "华为";String brandName = "华为";//处理参数companyName = "%" + companyName + "%";brandName = "%" + brandName + "%";//将多条件参数封装到对象中Map map = new HashMap();map.put("status", status);map.put("companyName", companyName);map.put("brandName", brandName);//获取Mapper接口对象BrandMapper brandMapper = getBrandMapper();//2.3 执行sql语句List<Brand> brands = brandMapper.selectByCondition(map);System.out.println(brands);}
      }
      
动态多条件查询

普通多条件查询时,多个条件若缺少其中一个条件(即用户输入条件时不一定会将所有条件都填写)则会导致查询失败,会解决该问题引入了动态多条件查询

  • 特点

    • SQL映射文件中的SQL语句会随着用户的输入或外部条件的变化而变化,称为动态SQL(MyBatis对动态SQL有强大的支撑)
  • MyBatis提供给动态SQL的标签如下

    标签解释
    <if test="逻辑表达式"></if>条件标签,使用test属性进行条件判断
    choose(when, otherwise)条件选择标签,类似于Java中的switch语句
    trim(where, set)
    foreach
    • if标签:常用于判断参数是否有值,使用test属性进行条件判断
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
    <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--多条件查询--><select id="selectByCondition" resultMap="brandResultMap">select * from tb_brandwhere<if test="status != null">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></select></mapper>
    

    if标签缺点: 多条件动态查询时除了第一个参数不能为空外,其它参数都可为空,因为SQL映射文件中不同SQL语句的条件之间通过and连接,此时假设第一个参数为null,则动态SQL语句就变为了select * from tb_brand where and company_name like ?,该SQL语句是个错误形式,因为where关键字后直接跟了and

    • 解决方式一: 创建恒等式,如下所示

      此时无论三个条件是否满足都不会造成SQL语句形式出错,因为此时where关键字后的第一个条件1 = 1是必然成立的

          <!--多条件查询--><select id="selectByCondition" resultMap="brandResultMap">select * from tb_brandwhere 1 = 1<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></select>
      
    • 解决方式二: 利用MyBatis提供的<where>标签来替换SQL的where关键字,如下所示

      • where标签特点

        ​ 1.会根据实际情况自动去除and关键字构成正确的SQL语句

        ​ 2.若无任何条件该标签会自动去除SQL语句中的where关键字,即此时动态SQL语句就变为select * from tb_brand;

          <!--多条件查询--><select id="selectByCondition" resultMap="brandResultMap">select * from tb_brand<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>
      
动态单条件查询------choose(when, otherwise)

在这里插入图片描述

  • 解释

    从多个条件中选择一个条件进行查询

  • 注意

    • choose标签类似于switch
    • when标签类似于case
    • otherwise标签相当于switch语句中的default
  • 对应的SQL映射文件如下

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
    <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--动态单条件查询--><select id="selectBySingleCondition" resultMap="brandResultMap">select * from tb_brandwhere<choose> <!--类似于switch--><when test="status != null">status = #{status}</when><when test="companyName != null and companyName != ''">company_name like #{companyName}</when><when test="brandName != null and brandName != ''">brand_name like #{brandName}</when><otherwise><!--相等于default,即若条件都没选则执行otherwise标签体的内容-->1=1</otherwise></choose></select></mapper>
    
    • 注意:在以上SQL映射文件中,若三个条件都没选则会执行default语句的代码,此时SQL语句为select * from where 1=1;,可能会返回错误的结果,所以可将<choose>标签放在<where>标签中来解决该问题,如下所示**( 推荐使用 ,where标签的特点详见动态多条件查询 )**

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
      <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--动态单条件查询--><select id="selectBySingleCondition" resultMap="brandResultMap">select * from tb_brand<where><choose> <!--类似于switch--><when test="status != null">status = #{status}</when><when test="companyName != null and companyName != ''">company_name like #{companyName}</when><when test="brandName != null and brandName != ''">brand_name like #{brandName}</when></choose></where></select>
      </mapper>
      

添加

基础添加

在这里插入图片描述

  • 解释:它会将网页要添加的数据封装成一个对象,然后添加到数据库表中

  • 注意:添加时,id不会让用户自己写,这个是自动生成的,所以参数是除了id之外的所有数据

  • SQL映射文件如下:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
    <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--基础添加--><insert id="add">insert into tb_brand (brand_name, company_name, ordered, description, status)values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status});</insert>
    </mapper>
    
  • 接口如下

    package at.guigu.mapper;import at.guigu.pojo.Brand;
    import org.apache.ibatis.annotations.Param;import java.util.List;
    import java.util.Map;public interface BrandMapper {//基础添加void add(Brand brand);
    }
    
  • 测试代码如下

    package at.guigu.test;import at.guigu.mapper.BrandMapper;
    import at.guigu.pojo.Brand;
    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 org.junit.Test;import java.io.IOException;
    import java.io.InputStream;public class MyBatisTest {//基础添加@Testpublic void testAdd() throws IOException {//接收前端传回的多个参数String companyName = "波导";String brandName = "波导手机";String description = "手机中的战斗机";int ordered = 100;int status = 1;//将参数封装到对象中Brand brand = new Brand();brand.setCompanyName(companyName);brand.setBrandName(brandName);brand.setDescription(description);brand.setOrdered(ordered);brand.setStatus(status);//1 加载核心配置文件,获取`SqlSessionFactory`对象//1.1 配置mybatis-config.xml文件路径,由于该文件直接在resources目录下,所以直接写文件名即可String resource = "mybatis-config.xml";//1.2 利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream = Resources.getResourceAsStream(resource);//1.3 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2 获取SqlSession对象,执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//2.3 执行sql语句brandMapper.add(brand);//手动提交事务sqlSession.commit();//3 释放资源sqlSession.close();}
    }
    

    手动提交事务的原因: 若无手动提交事务的代码则运行时能够运行成功但是数据库对应的表中并没有数据,原因是自动提交事务被关闭,所以我们需要手动提交事务,此时数据库的表中就会出现添加的数据,如图所示

    在这里插入图片描述

    • 注意:若不想在最后手动提交事务,则可在获取SqlSession对象时将事务自动提交开启,即SqlSession sqlSession = sqlSessionFactory.openSession(true);代表将参数autoCommit设置为true(即开启事务自动提交)
  • 问题:添加数据时会自动在数据库表中添加两条重复数据,如图所示,解决方法如下

    在这里插入图片描述

    在这里插入图片描述

主键返回
  • 解释

    在数据添加成功后需要获取插入数据库数据的主键的值(比如我在基础添加中添加了一个商品,现在添加成功后需要获取对应的主键值即id)

  • 注意

    • 在基础添加中的示例(添加了一个波导手机),由于id属于主键且课可以自增,所以在添加商品时不需要用户来添加id,而是系统自动添加id,所以用户需要输入的数据是除了主键id之外的所有数据,且这些数据是被封装到对象中然后通过若干方法最终到达数据库的,这就会有一个问题:添加商品成功后,无法通过Brand对象返回对应的id,这是因为并没有将对应的id封装到该对象中去,所以也就无法通过对象来获取用户添加的商品的对应主键id

    • 解决方法:将主键绑定到对象上,SQL映射文件如下:

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
      <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--主键返回--><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>
      </mapper>
      
      属性解释
      useGeneratedKeys是否将主键绑定到对象,默认为false
      keyProperty="name"数据库表的主键对应对象中属性的名称(即将主键与对象中的name属性关联)
    • 测试代码为

      package at.guigu.test;import at.guigu.mapper.BrandMapper;
      import at.guigu.pojo.Brand;
      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 org.junit.Test;import java.io.IOException;
      import java.io.InputStream;public class MyBatisTest {//基础添加@Testpublic void testAdd() throws IOException {//接收前端传回的多个参数String companyName = "波导";String brandName = "波导手机";String description = "手机中的战斗机";int ordered = 100;int status = 1;//将参数封装到对象中Brand brand = new Brand();brand.setCompanyName(companyName);brand.setBrandName(brandName);brand.setDescription(description);brand.setOrdered(ordered);brand.setStatus(status);//1 加载核心配置文件,获取`SqlSessionFactory`对象//1.1 配置mybatis-config.xml文件路径,由于该文件直接在resources目录下,所以直接写文件名即可String resource = "mybatis-config.xml";//1.2 利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream = Resources.getResourceAsStream(resource);//1.3 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2 获取SqlSession对象,执行SQL语句//2.1 获取SqlSession对象SqlSession sqlSession = sqlSessionFactory.openSession();//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//2.3 执行sql语句brandMapper.add(brand);//手动提交事务sqlSession.commit();//3 释放资源sqlSession.close();}
      }
      

      在这里插入图片描述

修改

  • 解释:修改(即编辑)已存在的商品数据信息

在这里插入图片描述

修改全部字段
  • SQL映射文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
    <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--修改商品数据:修改全部字段--><update id="update">update tb_brandset brand_name=#{brandName},company_name=#{companyName},ordered=#{ordered},description=#{description},status=#{status}where id=#{id};</update>
    </mapper>
    
  • 接口

    package at.guigu.mapper;import at.guigu.pojo.Brand;
    import org.apache.ibatis.annotations.Param;public interface BrandMapper {//修改数据:修改全部字段   并返回受影响的行数int update(Brand brand);
    }
    
  • 测试代码

    import at.guigu.mapper.BrandMapper;
    import at.guigu.pojo.Brand;
    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 org.junit.Test;import java.io.IOException;
    import java.io.InputStream;public class MyBatisTest {//修改全部字段@Testpublic void testUpdate() throws IOException {//接收前端传回的多个参数int id = 4;String companyName = "波导岛搭";String brandName = "波导岛手机的";String description = "手机中的战斗大机积极";int ordered = 90;int status = 1;//将参数封装到对象中Brand brand = new Brand();brand.setId(id);brand.setCompanyName(companyName);brand.setBrandName(brandName);brand.setDescription(description);brand.setOrdered(ordered);brand.setStatus(status);//1 加载核心配置文件,获取`SqlSessionFactory`对象//1.1 配置mybatis-config.xml文件路径,由于该文件直接在resources目录下,所以直接写文件名即可String resource = "mybatis-config.xml";//1.2 利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream = Resources.getResourceAsStream(resource);//1.3 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2 获取SqlSession对象,执行SQL语句//2.1 获取SqlSession对象并开启事务自动提交SqlSession sqlSession = sqlSessionFactory.openSession(true);//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//2.3 执行sql语句并返回受影响的行数System.out.println(brandMapper.update(brand));//3 释放资源sqlSession.close();}
    }
    

    在这里插入图片描述

    在这里插入图片描述

修改动态字段
  • 解释:用户将来修改的字段是不固定的,不可能提前知道要修改的字段名,此时就需要用到该技术

  • 利用<set>标签,特点

    • 该标签会自动判断是否有修改的字段,若无任何修改的字段则生成的动态SQL语句就不会有set关键字,若某个字段未被修改则生成的动态SQL语句会自动忽略该字段修改语句以及该字段修改语句后的逗号,以映射文件中SQL语句为例:
      • 假设现在无任何修改字段,则动态SQL语句变为:update tb_brand where id = ?;
      • 假设现在只有字段description被修改则动态SQL语句变为:update tb_brand where description = ? where id = ?;
  • SQL映射文件中SQL语句如下

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
    <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--修改商品数据:修改动态字段--><update id="updatePart">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>
    </mapper>
    
  • 接口

    package at.guigu.mapper;import at.guigu.pojo.Brand;
    import org.apache.ibatis.annotations.Param;public interface BrandMapper {//修改数据:修改部分字段,即修改动态字段  并返回受影响的行数int updatePart(Brand brand);
    }
    
  • 测试代码

    import at.guigu.mapper.BrandMapper;
    import at.guigu.pojo.Brand;
    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 org.junit.Test;import java.io.IOException;
    import java.io.InputStream;public class MyBatisTest {//修改全部字段@Testpublic void testUpdate() throws IOException {//接收前端传回的多个参数int id = 4;String companyName = "波导岛搭";String brandName = "波导岛手机的";String description = "手机中的战斗大机积极";int ordered = 90;int status = 1;//将参数封装到对象中Brand brand = new Brand();brand.setId(id);brand.setCompanyName(companyName);brand.setBrandName(brandName);brand.setDescription(description);brand.setOrdered(ordered);brand.setStatus(status);//1 加载核心配置文件,获取`SqlSessionFactory`对象//1.1 配置mybatis-config.xml文件路径,由于该文件直接在resources目录下,所以直接写文件名即可String resource = "mybatis-config.xml";//1.2 利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream = Resources.getResourceAsStream(resource);//1.3 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2 获取SqlSession对象,执行SQL语句//2.1 获取SqlSession对象并开启事务自动提交SqlSession sqlSession = sqlSessionFactory.openSession(true);//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//2.3 执行sql语句并返回受影响的行数System.out.println(brandMapper.updatePart(brand));//3 释放资源sqlSession.close();}
    }
    

    在这里插入图片描述

删除

删除一个
  • 解释:删除一条数据(商品)

  • SQL映射文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
    <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--删除一条数据(删除一个商品)--><delete id="delete">delete from tb_brand where id = #{id};</delete>
    </mapper>
    
  • Mapper接口

    package at.guigu.mapper;import at.guigu.pojo.Brand;
    import org.apache.ibatis.annotations.Param;public interface BrandMapper {//删除一条数据(删除一个商品)并判断删除是否成功boolean delete(int id);
    }
    
  • 测试代码

    import at.guigu.mapper.BrandMapper;
    import at.guigu.pojo.Brand;
    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 org.junit.Test;import java.io.IOException;
    import java.io.InputStream;public class MyBatisTest {//修改全部字段@Testpublic void testSingleDelete() throws IOException {//接收前端传回的参数int id = 4;//1 加载核心配置文件,获取`SqlSessionFactory`对象//1.1 配置mybatis-config.xml文件路径,由于该文件直接在resources目录下,所以直接写文件名即可String resource = "mybatis-config.xml";//1.2 利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream = Resources.getResourceAsStream(resource);//1.3 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2 获取SqlSession对象,执行SQL语句//2.1 获取SqlSession对象并开启事务自动提交SqlSession sqlSession = sqlSessionFactory.openSession(true);//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//2.3 执行sql语句并返回受影响的行数System.out.println(brandMapper.delete(id));//3 释放资源sqlSession.close();}
    }
    

    在这里插入图片描述

批量删除
  • 解释:一次删除多条数据(商品)

  • 注意

    删除多条数据时会根据id进行删除,并且会将id封装到数组中,通过遍历数组依次删除对应的数据(商品)

  • 用到的标签及属性

    标签解释
    <foreach></foreach>用于循环处理一组数据的标签。常用于在模板文件中循环遍历一个集合,例如列表或数组,并对集合中的每一项执行某些操作
    该标签中的属性解释
    collectionitems指定要迭代的集合或数组。
    itemvar指定循环中每次迭代时的当前项变量名称
    separator指定在每次迭代之间插入的字符串或标记
    open指定在循环开始时添加的字符串或标记
    close指定在循环结束时添加的字符串或标记
  • SQL映射文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
    <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--批量删除--><delete id="deleteByIds">delete from tb_brand where id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach></delete>
    </mapper>
    
    • 注意

      由于数组中id个数不确定,所以需要用到<foreach>标签来遍历数组,并将遍历到的参数之间用隔开,最终放在()内,假设现在数组ids中有三个id,则动态SQL语句为delete from tb_brand where id in(?,?,?);

  • 接口

    package at.guigu.mapper;import at.guigu.pojo.Brand;
    import org.apache.ibatis.annotations.Param;public interface BrandMapper {//批量删除boolean deleteByIds(@Param("ids") int[] ids);
    }
    
  • 测试代码

    import at.guigu.mapper.BrandMapper;
    import at.guigu.pojo.Brand;
    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 org.junit.Test;import java.io.IOException;
    import java.io.InputStream;public class MyBatisTest {//批量删除@Testpublic void testDelete() throws IOException {//接收前端传回的参数int[] ids = {2,3};//1 加载核心配置文件,获取`SqlSessionFactory`对象//1.1 配置mybatis-config.xml文件路径,由于该文件直接在resources目录下,所以直接写文件名即可String resource = "mybatis-config.xml";//1.2 利用Resources类中的静态方法将配置文件加载到内存InputStream inputStream = Resources.getResourceAsStream(resource);//1.3 获取SqlSessionFactory对象SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//2 获取SqlSession对象,执行SQL语句//2.1 获取SqlSession对象并开启事务自动提交SqlSession sqlSession = sqlSessionFactory.openSession(true);//2.2 获取Mapper接口UserMapper的代理对象BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);//2.3 执行sql语句并返回受影响的行数System.out.println(brandMapper.deleteByIds(ids));//3 释放资源sqlSession.close();}
    }
    

    在这里插入图片描述

  • 注意:SQL映射文件与对应接口有两种方式,以上示例中是一种方式,以下将对另一种方式进行说明

    • 由于MyBatis会自动将数组参数封装为一个Map集合,默认情况下该Map集合中键名为array,键值为传入的数组,所以SQL映射文件和接口也可写为如下形式

    • SQL映射文件

      <?xml version="1.0" encoding="UTF-8" ?>
      <!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!--namespace:名称空间-->
      <mapper namespace="at.guigu.mapper.BrandMapper"><!--结果映射--><resultMap id="brandResultMap" type="brand"><!--由于id为主键,且数据库中的字段名和对应结果映射的目标类中的属性名一样,所以此处不需要主键映射,只需进行非主键映射即可--><result column="brand_name" property="brandName" /><result column="company_name" property="companyName" /></resultMap><!--批量删除--><delete id="deleteByIds">delete from tb_brand where id in<foreach collection="array" item="id" separator="," open="(" close=")">#{id}</foreach></delete>
      </mapper>
      
    • 接口

      package at.guigu.mapper;import at.guigu.pojo.Brand;
      import org.apache.ibatis.annotations.Param;public interface BrandMapper {//批量删除boolean deleteByIds(int[] ids);
      }
      

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

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

相关文章

Coldrage Dagger

剃刀高地【寒怒匕首 Coldrage Dagger】 2020.11.26.剃刀高地刷【寒怒匕首】-1_网络游戏热门视频 2020.11.26.剃刀高地刷【寒怒匕首】-2_网络游戏热门视频

台式机通过网线直连笔记本,台式机通过笔记本上网【解决台式机没有网络的问题】

一、总览 将笔记本电脑和台式机使用网线连接起来。在笔记本电脑上打开网络和共享中心&#xff0c;进入“更改适配器设置”选项&#xff0c;找到当前连接的网卡&#xff0c;右键点击选择“属性”。在网卡属性中&#xff0c;找到“共享”选项卡&#xff0c;勾选“允许其他网络用…

湖北大学2024年成人高考函授报名专升本法学专业介绍

湖北大学&#xff0c;这所承载着深厚文化底蕴和学术积淀的高等学府&#xff0c;始终致力于为广大有志之士提供多元化的学习机会。在时代的浪潮中&#xff0c;为了满足社会对于高层次法律人才的需求&#xff0c;湖北大学特别推出了成人高等继续教育项目&#xff0c;为广大在职人…

黄历工具网/万年历/财神方位/日历/佛历/道历/24节气/PHP网站源码

黄历工具网/万年历/财神方位/日历/佛历/道历/24节气/PHP网站源码 演示地址&#xff1a; https://hl.caohongji.com/ 手机端地址&#xff1a; https://mhl.caohongji.com/ 客服&#xff1a; kkmp326 源码说明&#xff1a; 1、系统内的黄历宜忌、农历、日历、佛历、道…

前端基础--Vue2

前端技术发展史(了解) 1.前端历史 1.1.静态网页 1990 html 1.2.异步刷新-操作dom 1995 javascript 1.3.动态网站 Asp/jsp&#xff08;java&#xff09;,php等&#xff0c;后台臃肿 1.4.Ajax成为主流 异步请求 1.5.Html5 被认为是互联网的核心技术之一。HTML产生于19…

Docker之jekins的安装

jekins官网地址&#xff1a;Jenkins Plugins &#xff08;https://plugins.jenkins.io/&#xff09; jekins 的docker 官方地址&#xff1a;https://hub.docker.com/r/jenkins/jenkins jekins 的docker 允许命令文档地址&#xff1a; docker/README.md at master jenkinsci…

学分制系统 WebService_PantoSchool SQL注入致RCE漏洞复现

0x01 产品简介 学分制系统由上海鹏达计算机系统开发有限公司研发,是基于对职业教育特点和需求的深入理解,结合教育部相关文件精神,并广泛吸纳专家、学者意见而开发的一款综合性管理系统。系统采用模块化的设计方法,方便学校根据自身教学改革特点、信息化建设进程情况选择、…

Kubernetes之Scheduler详解

本文尝试从Kubernetes Scheduler的功能介绍、交互逻辑、伪代码实现、最佳实践、自定义Scheduler举例及其历史演进6个方面进行详细阐述。希望对您有所帮助&#xff01; 一、Kubernetes Scheduler 功能 Kubernetes Scheduler 是 Kubernetes 集群的核心组件之一&#xff0c;负责…

Qwen2本地web Demo

Qwen2的web搭建(streamlit) 千问2前段时间发布了&#xff0c;个人觉得千问系列是我用过最好的中文开源大模型&#xff0c;所以这里基于streamlit进行一个千问2的web搭建&#xff0c;来进行模型的测试 一、硬件要求 该文档中使用的千问模型为7B-Instruct&#xff0c;需要5g以…

ROT5、ROT13、ROT18、ROT47全系列加解密小程序

ROT5、ROT13、ROT18、ROT47全系列加解密小程序 这几天在看CTF相关的课程&#xff0c;涉及到古典密码学和近代密码学还有现代密码学。自己编了一个关于ROT全系列的加、解密小程序。 ​ ROT5、ROT13、ROT18、ROT47 编码是一种简单的码元位置顺序替换暗码。此类编码具有可逆性&a…

【铂电阻测温】如何保证热电阻采集的可靠性

TPS02RAH的输出接口为I2C&#xff0c;支持主机动态更改模块I2C地址&#xff0c;实现了单I2C总线挂载多个TPS02RAH测温模块的功能。 TPS02RAH的输出接口为I2C&#xff0c;支持主机动态更改模块I2C地址&#xff0c;实现了单I2C总线挂载多个TPS02RAH测温模块的功能。 参考链接 【…

领夹麦克风什么样的好,麦克风品牌排行榜前十名,无线麦克风推荐

​在人人可做自媒体的时代&#xff0c;众多普通人加入自媒体。对拍视频的自媒体人&#xff0c;好内容是基础&#xff0c;好设备是保障。想提升视频音质需专业无线麦克风。现无线麦克风品牌多&#xff0c;如何少花钱买高性价比产品是问题。作为资深自媒体人&#xff0c;我用过的…

电子看板,实现生产现场数字化管理

如何提高生产效率、优化资源配置、保障产品质量&#xff0c;成为企业在激烈竞争中脱颖而出的关键。电子看板作为一种创新的生产管理工具&#xff0c;为实现生产现场数字化管理提供了有力支持。电子看板是生产现场的“智能窗口”&#xff0c;它能够实时、准确地展示各类关键信息…

《2024年新生代妈妈真实孕育状态洞察报告》

专注于行业分析与市场研究的专业机构易观分析,正式发布了其最新研究成果——《2024年新生代妈妈真实孕育状态洞察报告》。该报告深入探讨了新生代妈妈在孕育过程中的实际需求与挑战,通过对母婴行业的市场规模、消费行为、用户触媒习惯、用户关怀以及特定品类场景的细致分析,揭示…

日元跌破160大关,日本当局何时干预?

KlipC报道&#xff1a;6月26日&#xff0c;日元又跌了&#xff0c;美元兑日元跌破160的整关口&#xff0c;超过了4月日本官员在市场上干预的水平&#xff0c;创1986年来新低。美联储降息的可能性降低&#xff0c;市场预计日元有可能延续当前的弱势。 KlipC分析师David表示&…

Ubuntu 20.04安装显卡驱动、CUDA、Pytorch(2024.06最新)

文章目录 一、安装显卡驱动1.1 查看显卡型号1.2 根据显卡型号选择驱动1.3 获取下载链接1.4 查看下载的显卡驱动安装文件1.5 更新软件列表和安装必要软件、依赖1.6 卸载原有驱动1.7 禁用默认驱动1.8 安装lightdm显示管理器1.9 停止显示服务器1.10 在文本界面中&#xff0c;禁用X…

关于新零售的一些思考

本文作为2024上半年大量输入之后的核心思考之一。工作到一定阶段之后&#xff0c;思考的重要性越来越高&#xff0c;后续会把自己的个人思考记录在这个新系列《施展爱思考》。背景是上半年面临业务转型从电商到新零售&#xff0c;本文是相关大量输入之后的思考&#xff0c;对新…

浅析Resource Quota中limits计算机制

前言 在生产环境中&#xff0c;通常需要通过配置资源配额&#xff08;Resource Quota&#xff09;来限制一个命名空间&#xff08;namespace&#xff09;能使用的资源量。在资源紧张的情况下&#xff0c;常常需要调整工作负载&#xff08;workload&#xff09;的请求值&#xf…

生信实证系列Vol.15:如何用AlphaFold2,啪,一键预测100+蛋白质结构

"结构就是功能"——蛋白质的工作原理和作用取决于其3D形状。 2020年末&#xff0c;基于深度神经网络的AlphaFold2&#xff0c;一举破解了困扰生物学界长达五十年之久的“蛋白质折叠”难题&#xff0c;改变了科学研究的游戏规则&#xff0c;可以从蛋白质序列直接预测…

MySQL高级-索引-使用规则-前缀索引

文章目录 1、前缀索引2、前缀长度3、查询表数据4、查询表的记录总数5、计算并返回具有电子邮件地址&#xff08;email&#xff09;的用户的数量6、从tb_user表中计算并返回具有不同电子邮件地址的用户的数量7、计算唯一电子邮件地址&#xff08;email&#xff09;的比例相对于表…