Maven,MyBatis

139 阅读20分钟

Maven

概述

  1. Maven是专门用于管理和构建Java项目的工具,它的主要功能有:
    1. 提供了一套标准化的项目结构

      • Maven提供了一套标准化的项目结构,所有IDE使用Maven构建的项目结构完全一样,所有IDE创建的Maven项目可以通用 联想截图_20230312141827.png
    2. 提供了一套标准化的构建流程(编译,测试,打包,发布....)

      • 标准化的构建流程
        联想截图_20230312142059.png Maven提供了一套简单的命令来完成项目构建
    3. 提供了一套依赖管理机制

      • 依赖管理
        • 依赖管理其实就是管理你项目所依赖的第三方资源(jar包、插件...)

          1. 下载jar包
          2. 复制jar包到项目
          3. 将jar包加入工作环境

          联想截图_20230312143227.png

          • 当jar包需要很多时,下载需要很多时间,而且下载的版本不同又会有影响,然后手动导jar包也十分的繁琐,但是Maven提供了一个管理jar包的机制
          • Maven只需要一个简单的配置就可以完成jar包的导入了
            1. Maven使用标准的坐标配置来管理各种依赖
            2. 只需要简单的配置就可以完成依赖管理(pom.xml)
            <!--    导入mysql驱动jar包-->
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.37</version>
                </dependency>
            </dependencies>
            

          联想截图_20230312144330.png

          联想截图_20230312145245.png

Maven简介

  1. Apache Maven是一个项目管理和构建工具,它基于项目对象模型(pom)的概念,通过一小段描述信息来管理项目的构建、报告和文档
  2. 官网:maven.apache.org/
    • Maven作用
      • 标准化的项目结构
      • 标准化的构建流程
      • 方便的依赖管理
  3. Maven模型 联想截图_20230312150844.png
    • 项目对象模型(Project Object Model)
    • 依赖管理模型(Dependency)
    • 插件(Plugin)
  4. 仓库分类
    • 本地仓库:自己计算机上的一个目录
    • 中央仓库:由Maven团队维护的全国唯一的仓库
    • 远程仓库(私服):一般由公司团队搭建的私有仓库
      • 当项目中使用坐标引入对应的依赖jar包后,首先会查找本地仓库中是否有对应的jar包:
        • 如果有,则在项目直接引用
        • 如果没有,则去中央仓库下载对应的jar包到本地仓库
      • 当项目有远程仓库(私服),首先会查找本地仓库中是否有对应的jar包,没有则在远程仓库里下载,若还是没有,则在中央仓库中寻找 联想截图_20230312152822.png

Maven安装配置

  1. 解压apache-maven-3.6.1.rar既安装完成(官网上下载)
  2. 配置环境变量MAVEN_HOME为安装路径的bin目录
    • 第一步:新建MAVEN_HOME(maven的安装目录) 联想截图_20230312160323.png
    • 第二步:双击Path
      联想截图_20230312160334.png
    • 第三步:新建(%MAVEN_HOME%\bin) 联想截图_20230312160353.png
    • 第四步:全部确定
    • 第五步:验证(打开cmd -->输入mvn -version ), 若出现以下,则配置成功
      联想截图_20230312160259.png
  3. 配置本地仓库:修改conf/setting.xml中的<localRepository>为一个指定目录
    • 第一步:找到conf --> setting.xml -->双击打开
    • 第二步:往下拉找到localReposition
      联想截图_20230312161731.png
    • 第三步:将上一步找出来的注释的最后一行粘贴出来(<localRepository>/path/to/local/repo</localRepository>联想截图_20230312162014.png
    • 第四步:修改本地仓库位置,其实要是不修改的话,我们是有默认的本地仓库位置的,不过在C盘,所以我们要修改。(在Maven安装目录下新建一个文件夹mvn_resp -->复制文件夹位置 -->粘贴到localRepository
      联想截图_20230312162707.png 联想截图_20230312162812.png
  4. 配置阿里云私服:修改conf/setting.xml中的<mirrors>标签,为其添加如下子标签:
    • 配置阿里云私服是为了提高jar包下载速度
    <mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>central</mirrorOf>
        <name>Nexus aliyun</name>
        <url>https://maven.aliyun.com/nexus/content/groups/public/</url>
        <blocked>true</blocked>
      </mirror>
    </mirrors>
    

Maven基本使用

  1. Maven常用命令
    • compile:编译
    • clean:清理
    • test:测试
    • package:打包
    • install:安装
    1. 首先新建一个项目
      联想截图_20230312192218.png 联想截图_20230312192301.png 联想截图_20230312192318.png 联想截图_20230312192327.png
    2. mvn compile:在项目根目录下,右键(在终端打开)-->输入mvn compile -->回车
      联想截图_20230312192538.png 联想截图_20230312194213.png 出现了BUILD SUCCESS即成功 联想截图_20230312194304.png 成功之后,会多出一个target目录 联想截图_20230312194456.png 要是把target目录给删了,可以重新运行(mvn compile),这次会很快运行完,因为已经不用再重新下载了。
    3. mvn clean:删除target目录
    4. mvn package:将生成的字节码文件打包成jar包(因为这是一个Java项目,所以会打包成一个jar包,如果是一个web项目,则会打包成一个var包)
    5. mvn test:会自动执行test目录下的Java文件
    6. mvn install:将当前这个项目安装到本地仓库上去
  2. Maven生命周期
  • Maven构建项目生命周期描述的是一次构建过程经历了多少个事件
  • Maven对项目构建的生命周期划分为3套
    • clean:清理工作
    • default:核心工作,例如编译,测试,打包,安装等
    • site:产生报告,发布站点等
  • 同一生命周期内,执行后边的命令,前边的所有命令会自动执行
    联想截图_20230312200816.png

IDEA配置Maven

  1. IDEA配置Maven环境

    1. 创建空项目-->选择IDEA File -->Settings(设置)
    2. 搜索maven
    3. 设置IDEA使用本地安装的Maven,并修改配置文件路径
      联想截图_20230312202500.png
  2. Maven坐标详解

  • 什么是坐标?
    • Maven 中的坐标是资源的唯一标识
    • 使用坐标来定义项目或引入项目中需要的依赖
  • Maven 坐标主要组成
    • groupld:定义当前Maven项目隶属组织名称 (通常是域名反写,例如:com.alibaba)
    • artifactld: 定义当前Maven项目名称 (通常是模块名称,例如 order-service、goods-service)
    • version:定义当前项目版本号 联想截图_20230312203337.png
  1. IDEA创建Maven项目
    1. 创建模块,选择Maven,点击Next

    2. 填写模块名称,坐标信息,点击finish,创建完成

    3. 编写HelloWorld,并运行

    package com;
    
    public class HelloWorld {
        public static void main(String[] args) {
            System.out.println("hello Maven");
        }
    }
    
  2. IDEA导入Maven项目
    1. 点击最右边的Maven
      联想截图_20230313193553.png
    2. 点击“+”号 联想截图_20230313193618.png
    3. 选择pom文件
      联想截图_20230313193749.png
  3. 配置Maven-Helper插件(如果搜不到,则在官网下下载)
    1. 选择IDEA中File-->Settings
    2. 选择Plugins
    3. 搜索Maven,选择第一个Maven Helper,点击install安装,弹出面板中点击Accept
    4. 重启IDEA

依赖管理

使用坐标导入jar包

  1. 在pom.xml中编写<dependencies>标签
  2. <dependencies>标签其中使用<dependency>引入坐标
  3. 定义坐标的groupld,artifactld,version
  4. 点击刷新按钮,使坐标生效
<!--    导入mysql驱动jar包-->
    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.24</version>
        </dependency>       
    </dependencies>
  1. 有时候会忘记点刷新按钮让它生效,可以设置让它自己自动生效
    1. setting(设置)
    2. Build,Execution,Deployment(构建,执行,部署)--> Build Tools(构建工具)
    3. anychanges(任何变更)
      联想截图_20230314193244.png
  2. 也可以手动导入jar包
    1. Fn+Alt+insert
    2. 依赖项(Dependency) 联想截图_20230314193244.png
    3. 搜索mysql-->选中所需要的版本
      联想截图_20230314194146.png

依赖范围

  1. 通过设置坐标的依赖范围(scope),可以设置对应的jar包的作用范围:编译环境、测试环境、运行环境
依赖范围编译classpath测试classpath运行classpath例子
compileYYYlogback
test-Y-Junit
providedYY-servlet-api
runtime-YYjdbc驱动
systemYY-存储在本地的jar包
import引入DependencyManagement~~~
  1. <scope>默认值:compile(就是在哪个环境都有效,通常只要默认就行)

MyBatis

概述

什么是MyBatis

  • MyBatis是一款优秀的持久层框架,用于简化JDBC开发
  • MyBatis本是Apache的一个开源项目iBatis,2020年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github
  • 官网:mybatis.org/mybatis-3/z…

持久层

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

框架

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

JDBC缺点

  1. 硬编码 --》配置文件
    • 注册驱动,获取连接
    • SQL语句
  2. 操作繁琐--》自动完成
    • 手动设置参数
    • 手动封装结果集

MyBatis简化

配置文件
<!--连接池信息-->
<dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///db1?useSSL=false"/><property name="username" 
value="root"/><property name="password" value="1234"/></dataSource>
<!--SQL语句-->
<select id="selectByGender" parameterType="string"resultType="com.itheima
.pojo.User";select * from tb_user where gender = #{gender};
</select>
<!--设置参数-->
List<User> users=sqlSession.selectList("test.selectByGender","男");

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

Mybatis快速入门(mybatis.net.cn/getting-sta…)

  1. 创建tb_user表,添加数据 联想截图_20230315193151.png

  2. 创建模块,导入坐标

    • logback所需的jar包和xml文件(maven导入)
      • logback-classic-1.2.3.jar
      • logback-core-1.2.3.jar
      • slf4j-api-1.7.26.jar
      • logback.xml 联想截图_20230316195833.png 查看mysql版本号:mysql中输入SELECT VERSION();
    • xml文件(这个文件复制到src-->main-->resources下)
      <?xml version="1.0" encoding="UTF-8"?>
      <configuration>
          <!-- CONSOLE :表示当前的日志信息是可以输出到控制台的 -->
          <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
              <!--输出流对象 默认 System.out 改为 System.err  其中err:控制台输出日志为红色,而out为黑色-->
              <target>System.out</target>
              <encoder>
                  <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
                  <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%-5level]  %c [%thread] : %msg%n</pattern>
              </encoder>
          </appender>
          <!-- File:表示当前的日志信息是可以输出到文件的 -->
          <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
              <encoder>
                  <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
                  <charset>utf-8</charset>
              </encoder>
              <!--日志输出路径(logback_message.log是文档名,下方还有一处文件名(不用写.log))-->
              <file>D:\codeLogback\xie-data.log</file>
              <!--指定日志文件拆分和压缩规则(防止文件过大)-->
              <rollingPolicy
                      class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                  <!--通过指定压缩文件名称,来确定分割文件方式-->
                  <fileNamePattern>D:\codeLogback\xie-data-%d{yyyy-MM-dd}.log%i.gz</fileNamePattern>
                  <maxFileSize>1MB</maxFileSize> <!--文件拆分大小-->
              </rollingPolicy>
          </appender>
      
          <!--
          level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF (关掉), 默认debug(可忽略大小写)
          <root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
          -->
          <root level="INFO"> <!--打印规则:只打印不低于当前级别的日志-->
              <appender-ref ref="CONSOLE"/> <!--如果这个地方不配置关联打印的位置,改位置将不会记录日志-->
              <appender-ref ref="FILE" />
          </root>
      </configuration>
      
  3. 编写MyBatis核心配置文件-->替换连接信息解决硬编码的问题

    1. 在recources在创建一个mybatis_config.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>
        <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>
        </environments>
        <mappers>          
        <!--加载SQL映射文件-->
          <mapper resource="org/mybatis/example/BlogMapper.xml"/>
        </mappers>
      </configuration>
      
  4. 编写SQL映射文件-->统一管理SQL语句,解决硬编码问题

    1. 在recources创建一个UserMapper.xml文件(映射文件起名有规则,如果是User表,则起UserMapper,但如果是open表,则起名为OpenMapper)
      <?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:名称空间,名字可以随便取,这里取得名字是test-->
      
      <mapper namespace="test">
          <select id="selectBlog" resultType="Blog">
              select * from tb_user where id = #{id}
          </select>
      <!--    <select></select>:定义查询语句
              id:SQL语句的唯一标识,需要改值
              resultType:对应返回的结果类型,将来我们的数据打算包装成什么类型,我们就写什么类型,所以接下来就是要把user类给创建出来(
              -->
      </mapper>
      
    2. 创建User类(Java目录下)
    3. <mapper namespace="test">
              <select id="selectBlog" resultType="Blog">
                  select * from tb_user where id = #{id}
              </select>
      
      改成
      <mapper namespace="test">
          <select id="selectAll" resultType="com.xie.pojo.User">
              select * from tb_user;  //可以随意写SQL语句
          </select>
      

    com.xie.pojo.User:是创建的User表的目录

    1. 将mybatis_config.xml的加载SQL映射文件部分修改
      <!--加载SQL映射文件-->
           <mapper resource="org/mybatis/example/BlogMapper.xml"/>
         </mappers>
      
      改成
      <!--        加载SQL映射文件-->
              <mapper resource="UserMapper.xml"/>
          </mappers>
      
      因为UserMapper.xml文件和mybatis_config.xml文件都是在rescources目录下,所以是同一级目录,所以直接写"UserMapper.xml"
  5. 编码

    1. 定义POJO类(User表)
       ackage com.xie.pojo;
       public class User {
           private Integer id;
           private String username;
           private String password;
           private String gender;
           private String addr;
      
           public Integer getId() {
               return id;
           }
           }
      

    右键生成setting,getting,toString方法

    package com.xie.pojo;
    
    public class User {
        private Integer id;
        private String username;
        private String password;
        private String gender;
        private String addr;
    
        public Integer getId() {
            return id;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id=" + id +
                    ", username='" + username + ''' +
                    ", password='" + password + ''' +
                    ", gender='" + gender + ''' +
                    ", addr='" + addr + ''' +
                    '}';
        }
    
        public String getAddr() {
            return addr;
        }
    
        public void setAddr(String addr) {
            this.addr = addr;
        }
    
        public String getGender() {
            return gender;
        }
    
        public void setGender(String gender) {
            this.gender = gender;
        }
    
        public String getUsername() {
            return username;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public void setUsername(String username) {
            this.username = username;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    }
    
    1. 加载核心配置文件,获取sqlSessionFactory对象
    2. 获取sqlSession对象,执行SQL语句
    3. 释放资源
      package com.xie;
      
      import com.xie.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;
      
      //MyBatis快速入门代码
      public class MyBatis {
          public static void main(String[] args) throws IOException {
      //        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();
      //        3. 执行SQL
              List<User> users=sqlSession.selectList("test.selectAll");
              System.out.println(users);
      //        4.释放资源
              sqlSession.close();
          }
      }
      

    List<User> users=sqlSession.selectList("test.selectAll");中的test.selectAll是UserMapper.xml文件中的名称空间.id标识

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

    • 产生问题:idea和数据库没有建立连接,不识别表信息
    • 解决方式:在idea中配置MySQL数据库连接
      联想截图_20230316210027.png

Mapper代理开发

  1. 目的

    1. 解决原生方式中的硬编码

    2. 简化后期执行SQL

      //3.执行SQL
      List<User> users=sqlSession.selectList("test.selectAll");
      System.out.printf(users);
      
      //3.获取接口代理对象
      UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
      //4.执行方法,其实就是执行SQL语句
      List<User> users=users=userMapper.selectAll();
      

    第二种方法有很多优势,首先它不依赖于字符串字面值,会更安全一点;其次,如果你的 IDE 有代码补全功能,那么代码补全可以帮你快速选择到映射好的 SQL 语句。

  2. Mapper代理需要遵循的要求

    1. 定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置在同一目录下
      联想截图_20230321185130.png 联想截图_20230321185147.png 联想截图_20230321192621.png 在resources目录下要是想要建包,则不能直接新建“com.xie.mapper”,要不然idea会认为一个目录就叫做com.xie.mapper,所以要改成“com/xie/mapper” 联想截图_20230321192711.png
    2. 设置SQL映射文件的namespace属性为Mapper接口全限定名
      联想截图_20230321193230.png
    3. 在Mapper 接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
      • 在映射文件中有一个SQL id叫做selectAll,那就意味着将来在Usermapper(类)里面要有一个方法,叫做selectAll,而且参数和返回类型要一致。
      • 在UserMapper.xml这个映射文件中有一个返回类型,叫做User
      package com.xie.mapper;
      
        import com.xie.pojo.User;
      
        import java.util.List;
      
        public interface UserMapper {
      
            List<User> selectAll();
            //因为在UserMapper.xml中返回的是一个User集合,所以这返回的是List<User>,如果返回的对象是User,则只能查询出一个对象
      
        }
      

    联想截图_20230321194526.png

    1. 编码
      1. 通过 SqlSession 的 getMapper方法获取 Mapper接口的代理对象
        • 新建一个类(MyBatisDemo2),然后运行,能得到相同的结果
        package com.xie;
        
        import com.xie.mapper.UserMapper;
        import com.xie.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;
        
        //MyBatis代理开发
        public class MyBatisDemo2 {
            public static void main(String[] args) throws IOException {
        //        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();
        //        3. 执行SQL
               // List<User> users=sqlSession.selectList("test.selectAll");
                //3.1获取serMapper接口的代理对象
                UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
                List<User> users=userMapper.selectAll();
                System.out.println(users);
        //        4.释放资源
                sqlSession.close();
        
            }
        }
        
        结果
        联想截图_20230321200116.png
      2. 调用对应方法完成sql的执行
  3. 整个运行流程

    1. myBatisDemo2类中第2步获取了sqlSession对象
    2. 在第3.1步中通过sqlSeession来获取对应的Mapper接口(UserMapper.class)代理对象(UserMapper)
    3. 通过第3.1步这行代码可以找到UserMapper这个接口
    4. 又因为在当前这个目录(UserMapper)下面有一个同名的映射文件,所以又可以找到映射文件(UserMapper.xml)下对应的SQL语句
    5. 找到之后,通过UserMapper.selectAll()(回到MyBatisDemo2类中的第3.1步)调用UserMapper这个接口里的selectAll()方法
    6. selectAll()(接口UserMapper中的)对应的是SQL语句的id,找到UserMapper.xml中的对应的id,找到id之后,就可以获取SQL语句了
    7. 有了SQL语句后,因为我们的返回值是List,所以其实它的底层执行的还是sqlSession.selectList,它帮我们写List<User> users=sqlSession.selectList("test.selectAll");这行代码(在之前学过的MyBatisDemo类中有)
  4. 细节:如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载

    • 意思是在mybatis-config.xml中加载SQL映射文件时,现在的映射文件有包的名称,写起来不是很方便,而且将来会有很多很多这样的映射文件,就要写一排,不方便。如果用了Mapper代理开发方式,有另外简化的方式来加载映射文件。可以 <package name="com.xie.mapper"/>这一行代码全部搞定
      联想截图_20230321203031.png

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

  1. enviroment(mybatis.org/mybatis-3/z…
    1. 可以写多个environment,即可以导入多个库
      联想截图_20230321203725.png 第一个库是开发库,第二个测试库
  2. typeAliases(类型别名)
    mybatis.org/mybatis-3/z… 联想截图_20230321204538.png
    • 配置完之后相当于我们给所有pojo目录下的所有实体类起了个别名,别名默认为是类名,不需要带包名称了。
    • 意味着我们将来写UserMapper.xml中的返回类型(resultType)时,可以直接写resultType="类名"(不区分大小写)
  3. 细节:配置各个标签时,需要遵循前后顺序
    顺序:
    联想截图_20230321205413.png

配置文件完成增删改查

案例:完成品牌数据的增删改查操作

联想截图_20230322184650.png

  • 要完成的功能列表清单
准备环境
  1. 数据库表tb_brand
    联想截图_20230322191040.png 联想截图_20230322191052.png

  2. 实体类Brand
    联想截图_20230322191256.png

  3. 测试用例
    联想截图_20230322191423.png 联想截图_20230322191431.png

  4. 安装MyBatisX插件

    • MybtisX插件
      • MybatisX是一款基于idea的快速开发插件,为效率而生
      • 主要功能
        • XML和接口方法相互跳转
        • 根据接口方法生成statement(例如UserMapper.xml中的SQL语句)
      • 安装:
        联想截图_20230322191803.png
查询
查询所有数据
  1. 编写接口方法:Mapper接口

    • 参数:无
    • 结果:List 联想截图_20230322193607.png
  2. 编写SQL语句:SQL映射文件
    联想截图_20230322193620.png

  3. 执行方法,测试
    联想截图_20230322194525.png MyBatis完成操作需要几步
    三步:编写接口方法-》编写SQL-》执行方法
    注意 联想截图_20230322200416.png

查看详情

联想截图_20230322200921.png

  1. 编写接口方法:Mapper接口
    • 参数:id
    • 结果:Brand
      联想截图_20230322204117.png
  2. 编写SQL语句:SQL映射文件
    联想截图_20230322204234.png
  3. 执行方法,测试
    联想截图_20230322204259.png
  • 总结
    1. 参数占位符
      • #{}: 执行SQL时,会将#{}占位符替换为?,将来自动设置参数值
      • S{}: 拼sQL。会存在sQL注入问题
      • 使用时机:
        • 参数传递,都使用#{}
        • 如果要对表名、列名进行动态设置,只能使用${}进行sql拼接
    2. parameterType 用于设置参数类型,该参数可以省略
    3. SQL 语句中特殊字符处理
      • 转义字符
        <![CDATA[ 内容]]>
条件查询
  1. 多条件查询 联想截图_20230322210127.png
    1. 编写接口方法(BrandMapper.java)
      • 参数:所有查询条件
      • 结果:List<Brand>
      /**    条件查询
       *        参数接受
       *             1.散装参数(如果方法中有多个参数,需要使用@Param("SQL参数占位符名称"))
       *             2.对象参数:只需要保证SQL中的参数名和实体类属性名对应上,即可设置成功
       *             3. map集合参数:只需要保证SQL中参数名和map集合的键的名称对应上,即可设置成功
          **/
           Brand selectById(int id);
           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);
      }
      
    2. 编写SQL语句,SQL映射文件(BrandMapper.xml)
      <!--    条件查询-->
      <select id="selectByCondition"resultMap="brandResultMap">
          select *
      from tb_brand
      where status=#{status} and company_name like #{companyName} and brand_name like #{brandName}
      </select>
      
    3. 执行方法,测试
      • 散装参数
      //    散装参数
          @Test
          public void testSelectByCondition() throws IOException {
      //        接受参数
              int status=1;
              String companyName="华为";
              String brandName="华为";
      //        处理参数
              companyName ="%"+companyName+"%";
              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);
              System.out.println(brands);
      //        5.释放资源
              sqlSession.close();
          }
      
      • 对象参数
      //    对象参数
          @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);
      //        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);
              System.out.println(brands);
      //        5.释放资源
              sqlSession.close();
          }
      
      • map集合参数
      //    map集合参数
          @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. 多条件-动态条件查询 mybatis.org/mybatis-3/z… SQL语句会随着用户的输入或外部条件的变化而变化,我们称为动态SQL
    • MyBatis对动态SQL有很大的支撑:
      • if:用于判断参数是否有值,使用test属性进行条件判断
        • 存在的问题:第一个条件不需要逻辑运算符
        • 解决方案:
          • 使用恒等式让所有条件格式都一样
          • <where>标签替换where关键字
      • choose(when,otherwise)
      • trim(where,set)
      • foreach

查询(BrandMapper.xml)

<!--    动态条件查询
            * if:条件查询
                * test:逻辑表达式
            * 问题
                * 恒等式
                * <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>
  1. 单条件动态查询
    从多个条件中选择一个
    • choose(when,otherwise):选择,类似于Java中的Switch语句
    1. BrandMapper.java
    /**单条件动态查询**/
    List<Brand> selectByConditionSingle(Brand brand);
    
    1. BrandMapper.xml
    <select id="selectByConditionSingle" resultType="Brand">
    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>
    
    1. MyBatisTest.java
    @Test
        public void testSelectByConditionSingle() 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);
    
    //        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.selectByConditionSingle(brand);
            System.out.println(brands);
    //        5.释放资源
            sqlSession.close();
        }
    
添加
基础添加
  1. 编写接口方法
    • 参数:除了id之外的所有数据
    • 结果:void
  2. 编写SQL语句:SQL映射文件
  3. 执行方法,测试
    • MyBatis事务
      • oppenSession():默认开启事务,进行增删改查操作后需要使用sqlSession.commit();手动提交事务
    • oppSession(true):可以设置为自动提交事务(关闭事务)
  • BrndMapper.java
/*
* 添加
* */
void add(Brand brand);
  • BrandMapper.xml
<insert id="add">
    insert into tb_brand(brand_name, company_name, ordered, description, status)
    values (#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>
  • MyBatisTest.java
    @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
      联想截图_20230325163512.png

返回添加数据的主键
<insert useGeneratedKeys="true" keyProperty="id"> 如果没有这行代码的话,添加完数据后,并不能查询到对应的id。

  • BrandMapper.xml
<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>
  • MyBatisType.java
 @Test
    public void testAdd2() 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);
       Integer id=brand.getId();
        System.out.println(id);
//            提交事务
        sqlSession.commit();
//        5.释放资源
        sqlSession.close();
    }
修改
修改全部字段
  1. 编写接口方法:Mapper接口
    • 参数:所有数据
    • 结果:void
    int update(Brand brand);
    
  2. 编写SQL语句:SQL映射文件
    <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
        public void testUpdate() throws IOException {
    //        接受参数
            int status=1;
            String companyName="波导手机";
            String brandName="波导波导";
            String description="波导手机,手机中的战斗机";
            int ordered=100;
            int id=5;
    //        封装参数
            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();
        }
    

联想截图_20230325164612.png

修改动态字段

比如用户修改密码时,只会修改密码,而不会改变其他的值

<update id="update">
    update tb_brand
    <set>
    <if test="brandName !=null and brandName !=''">
        set 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>
删除
删除一个
  1. 编写接口方法:Mapper接口
    • 参数:id
    • 结果:void
    void deleteById(int id);
    
  2. 编写SQL语句:SQL映射文件
<delete id="deleteById">
delete from tb_brand where id=#{id};
</delete>

3.执行方法,测试

   @Test
    public void testDeleteById() throws IOException {
//        接受参数
        int id=5;

//        1.获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//        2.获取SqlSession对象
//        SqlSession sqlSession=sqlSessionFactory.openSession();
        SqlSession sqlSession=sqlSessionFactory.openSession(true);
//        3.获取Mapper接口的代理对象
        BrandMapper brandMapper=sqlSession.getMapper(BrandMapper.class);
//        4.执行方法
       brandMapper.deleteById(id);
//            提交事务
        sqlSession.commit();
//        5.释放资源
        sqlSession.close();
    }
批量删除
  1. 编写接口方法:Mapper接口
    • 参数:id数组
    • 结果:void
void deleteByIds(@Param("ids")int[] ids);
  1. 编写SQL语句:SQL映射文件
    <!--
    mybatis 会将数组参数,封装为一个map集合,
    * 默认:array=数组
    * 使用@Param注解来改变map集合的默认key的名称
-->
<delete id="deleteByIds">
    delete
    from tb_brand
    where id in
    <foreach collection="ids" item="id" separator="," open="(" close=")">#{id}
          </foreach>
        ;
</delete>
  1. 执行方法,测试
 @Test
    public void testDeleteByIds() throws IOException {
//        接受参数
        int[] ids={7,6,8};

//        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.deleteByIds(ids);
//            提交事务
        sqlSession.commit();
//        5.释放资源
        sqlSession.close();
    }    

MyBatis参数传递

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

  • 单个参数:
    1. POJO类型
    2. Map集合
    3. Collection:
    4. List
    5. Array:
    6. 其他类型
  • 多个参数

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

注解完成增删查改

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

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

提示

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

使用注解来射简单语句会使码得更加首洁,但对于微复杂一点的语句a 解不力不以心,还会让你本就复杂的 SOL 语向更加混乱不。因此,如果你需要做一些很复杂的作,最好 用XML 来映射语句。
选择何种方式来配置映射,以及认为是否应该要统一谢语向定义的式,完全决和你的团队换句适说,永远不要于-种方式,你可以很经的在基于解和 M, 的语句映射方式间 由移植和切换。