IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> 在IDEA2021-2中使用MyBatis -> 正文阅读

[开发工具]在IDEA2021-2中使用MyBatis

前言

我是跟随狂神的B站教学视频以及mybatis官网学习的,狂神B站传送门:https://www.bilibili.com/video/BV1NE411Q7Nx
喜欢看视频的直接去看就行了,讲的非常nice

用到的数据库表名user我改成了login,因为user是sql server关键字(老师用的mysql,我用的sql server)
其他步骤大致相同,相当于我的学习笔记,掺杂了一些个人见解
只想学基础增删改查的看完前三部分就行

我的学习顺序:MyBatis=>Spring=>SpringMVC=>SpringBoot
其他相关博客会陆续发布…

一、准备工作

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

1、进入Mybatis官网

传送门 https://mybatis.org/mybatis-3/zh/index.html
点击侧边栏中的 入门
可以看到在maven中的依赖代码
在这里插入图片描述

2、新建maven空项目

在这里插入图片描述
点击next,项目命名为mybatis
在这里插入图片描述
点击finish
删除src,方便新建module
在这里插入图片描述

3、配置pom.xml

1)导入三个依赖 mssql-jdbc、mybatis、junit

 <dependencies>
     <!-- https://mvnrepository.com/artifact/com.microsoft.sqlserver/mssql-jdbc -->
     <dependency>
         <groupId>com.microsoft.sqlserver</groupId>
         <artifactId>mssql-jdbc</artifactId>
         <version>9.4.0.jre16</version>
     </dependency>

     <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
     <dependency>
         <groupId>org.mybatis</groupId>
         <artifactId>mybatis</artifactId>
         <version>3.5.6</version>
     </dependency>

     <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>4.12</version>
     </dependency>
     
 </dependencies>

2)再配置build中的resources节点,防止无法导出配置文件(所有pom文件都要做此修改)

 <build>
        <!--防止资源导出失败-->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

4、新建module

命名test
在这里插入图片描述
可以看到父子项目的依赖完全相同
在这里插入图片描述

5、连接数据库

连接名为test的数据库
在这里插入图片描述
在这里插入图片描述

二、配置mybatis相关

1、新建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.microsoft.sqlserver.jdbc.SQLServerDriver"/>
                <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=test"/>
                <property name="username" value="sa"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

只要修改四处,把对应的value修改即可
在这里插入图片描述

2、编写mybatis工具类

新建MybatisUtils类
在这里插入图片描述
我们需要从 XML 中构建 SqlSessionFactory
再从 SqlSessionFactory 中获取 SqlSession

package com.jiyu.utils;

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;

public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    //1、从 XML 中构建 SqlSessionFactory
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //2、从 SqlSessionFactory 中获取 SqlSession
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

3、实体类

1)数据库建表login
在这里插入图片描述
增加数据
在这里插入图片描述
2)建立Login类
在这里插入图片描述

4、dao接口

新建LoginDao接口
在这里插入图片描述

接口中的方法
在这里插入图片描述

5、接口实现(xml映射文件)

一个sql语句既可以通过 XML 定义,也可以通过注解定义。
先看xml的方法
新建LoginMapper.xml(以后实现接口方法的xml文件都简称xml映射文件
在这里插入图片描述

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

<mapper namespace="com.jiyu.dao.LoginDao">
    <select id="getLoginList" resultType="com.jiyu.entity.Login">
        select * from login
    </select>
</mapper>

修改以下四处即可
在这里插入图片描述

6、测试

1)先在核心配置文件中注册mapper
修改一处代表Mapper.xml文件路径的代码即可
在这里插入图片描述
2)在测试文件中新建LoginDaoTest
在这里插入图片描述

package com.jiyu.dao;

import com.jiyu.entity.Login;
import com.jiyu.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

/**
 * @author jiyu
 * @create 2021-09-21 19:18
 * @description
 */
public class LoginDaoTest {
    @Test
    public void test(){
        //获得sqlSession
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //方法一:getMapper
        LoginDao loginDao = sqlSession.getMapper(LoginDao.class);
        List<Login> loginList = loginDao.getLoginList();

        //方法二:selectList(不太好)
        //List<Login> loginList = sqlSession.selectList("com.jiyu.dao.LoginDao.getLoginList");

        for(Login login:loginList){
            System.out.println(login);
        }

        //关闭sqlSession
        sqlSession.close();
    }
}

运行后显示结果
在这里插入图片描述

三、CRUD测试

之前建立的接口LoginDao是为了方便理解
现在改名为LoginMapper
在这里插入图片描述

1、根据id查询用户

1)在接口(LoginMapper.java)中,建立方法

Login getLoginById(int id);

2)在对应的xml映射文件(LoginMapper.xml)中编写对应sql语句

<select id="getLoginById" parameterType="int" resultType="com.jiyu.entity.Login">
        select * from login where id=#{id}
</select>

在这里插入图片描述

3)在测试文件(LoginDaoTest.java)测试

@Test
    public void getLoginById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);

        Login login = mapper.getLoginById(1);
        System.out.println(login);

        sqlSession.close();
    }

结果正确
在这里插入图片描述

总结:增删改查都是三步:
1、编写接口中的方法
2、编写对应xml映射文件(要在核心配置文件中注册mapper),主要写sql语句
3、测试
但是增删改需要提交事务,代码有一点不同

2、增删改

增删改的步骤和查找一样,只是在测试时需要提交事务
下面直接贴代码

1)接口(LoginMapper.java)

package com.jiyu.dao;

import com.jiyu.entity.Login;

import java.util.List;

public interface LoginMapper {
    //查询全部用户
    List<Login> getLoginList();

    //根据id查询用户
    Login getLoginById(int id);

    //增加一个用户
    int addLogin(Login login);

    //修改用户
    int updateLogin(Login login);

    //删除一个用户
    int deleteLogin(int id);
}

2)xml映射文件(LoginMapper.xml)

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

<mapper namespace="com.jiyu.dao.LoginMapper">

    <select id="getLoginList" resultType="com.jiyu.entity.Login">
        select * from login
    </select>

    <select id="getLoginById" parameterType="int" resultType="com.jiyu.entity.Login">
        select * from login where id=#{id}
    </select>

    <insert id="addLogin" parameterType="com.jiyu.entity.Login">
        insert into login (id,name,pwd) values (#{id},#{name},#{pwd})
    </insert>
    
    <update id="updateLogin" parameterType="com.jiyu.entity.Login">
        update login
        set name = #{name},pwd=#{pwd}
        where id=#{id};
    </update>

    <delete id="deleteLogin" parameterType="int">
        delete
        from login
        where id=#{id};
    </delete>
</mapper>

3)测试(LoginDaoTest.java)

package com.jiyu.dao;

import com.jiyu.entity.Login;
import com.jiyu.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

/**
 * @author jiyu
 * @create 2021-09-21 19:18
 * @description
 */
public class LoginDaoTest {
    @Test
    public void test(){
        //获得sqlSession
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        //方法一:getMapper
        LoginMapper loginDao = sqlSession.getMapper(LoginMapper.class);
        List<Login> loginList = loginDao.getLoginList();

        //方法二:selectList(不太好)
        //List<Login> loginList = sqlSession.selectList("com.jiyu.dao.LoginDao.getLoginList");

        for(Login login:loginList){
            System.out.println(login);
        }

        //关闭sqlSession
        sqlSession.close();
    }

    @Test
    public void getLoginById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();

        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);

        Login login = mapper.getLoginById(1);
        System.out.println(login);

        sqlSession.close();
    }

    //增删改需要提交事务  sqlSession.commit()
    @Test
    public void addLogin(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);

        int res = mapper.addLogin(new Login(4, "zhaosi", "zhaosipass"));
        if(res>0){
            System.out.println("success!");
        }

        //提交事务
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void updateLogin(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);

        mapper.updateLogin(new Login(4,"zhaosisi","zhaosipass"));

        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void deleteLogin(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);

        mapper.deleteLogin(4);

        sqlSession.commit();
        sqlSession.close();
    }
}

3、map

数据库表的字段或者实体类参数过多,考虑使用map
map传参,在sql中取出key即可
对象传参,在sql中取出对象的属性即可
只有一个基本类型参数时,可以直接在sql中取到
多个参数用map或者注解

下面是两个例子
主要是利用map.put()方法建立一个map后,作为参数将多个数据传入sql

1、addLogin2:增加Login

1)接口

int addLogin2(Map<String,Object> map);

2)xml映射文件

<insert id="addLogin2" parameterType="map">
        insert into login (id, name, pwd)
        values (#{userId},#{userName},#{password});
</insert>

3)测试

@Test
    public void addLogin2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);

        Map<String, Object> map = new HashMap<>();

        map.put("userId",5);
        map.put("userName","wangwu");
        map.put("password","wangwupass");

        mapper.addLogin2(map);

        sqlSession.commit();
        sqlSession.close();
    }

2、getLoginById2:通过id获取Login

1)接口

    Login getLoginById2(Map<String,Object> map);

2)xml映射文件

<select id="getLoginById2" parameterType="map" resultType="com.jiyu.entity.Login">
        select * from login where id=#{id} and name=#{name};
</select>

3)测试

@Test
    public void getLoginById2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);

        Map<String, Object> map = new HashMap<>();

        map.put("id",1);
        map.put("name","jiyu");

        Login login = mapper.getLoginById2(map);
        System.out.println(login);

        sqlSession.close();
    }

4、模糊查询

1)接口

    List<Login> getLoginLike(String value);

2)xml映射文件
方法一(较为安全)

<select id="getLoginLike" resultType="com.jiyu.entity.Login">
        select * from login where name like #{value};
</select>

方法二(容易sql注入)

<select id="getLoginLike" resultType="com.jiyu.entity.Login">
        select * from login where name like "%"#{value}"%";
</select>

3)测试(如果使用方法二,则将"%李%“改为"李”)

 @Test
    public void getLoginLike(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);

        List<Login> loginList = mapper.getLoginLike("%李%");

        for(Login login:loginList){
            System.out.println(login);
        }

        sqlSession.close();
    }

四、对配置文件的深度解析

1、环境配置(environments)

每个数据库对应一个 SqlSessionFactory 实例
每个 SqlSessionFactory 实例只能选择一种环境

在核心配置文件mybatis-config.xml中,可以配置多个environment
如图建立了id为test的环境
在这里插入图片描述
可以通过<environments default="test">设置默认使用的环境为test
下面的代码分别表示事务管理器和数据源的类型

<transactionManager type="JDBC"/>
            <dataSource type="POOLED">

2、属性(properties)

属性可以在外部进行配置,并可以进行动态替换。
既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置

如果一个属性在不只一个地方进行了配置,那么,MyBatis 将按照下面的顺序来加载:

首先读取在 properties 元素体内指定的属性。 然后根据 properties 元素中的 resource属性读取类路径下属性文件,或根据 url 属性指定的路径读取属性文件,并覆盖之前读取过的同名属性。最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。
因此,通过方法参数传递的属性具有最高优先级,resource/url属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性。

以下是编写配置文件的示例

1)新建db.properties
在这里插入图片描述

driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
url=jdbc:sqlserver://localhost:1433;databaseName=test
username=sa
password=123456

2)在核心配置文件中引入
先通过<properties resource="db.properties"/>引入外部配置文件
再通过<environments default="test">修改默认环境为test
在test环境中,修改四个value值即可
以后修改连接的数据库就可以在db.properties文件中修改了(无需改动核心配置文件)
在这里插入图片描述

3、类型别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写

1)typeAlias
在mybatis-config.xml核心配置文件中输入

<typeAliases>
        <typeAlias type="com.jiyu.entity.Login" alias="Login"/>
</typeAliases>

在LoginMapper.xml映射文件中,原本法人resultType为com.jiyu.entity.Login
此时可以更改为别名Login

在这里插入图片描述
2)package

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean。

<typeAliases>
        <package name="com.jiyu.entity"/>
</typeAliases>

每一个在包 com.jiyu.entity 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 com.jiyu.entity.Login 的别名为 login;若有注解,则别名为其注解值。

@Alias("login")
public class Login {
    ...
}

4、设置(settings)

MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为

下面几个是比较重要的
在这里插入图片描述

在这里插入图片描述
在遇到日志时会进行讲解

5、映射器(mappers)

既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要来定义 SQL 映射语句了。 但首先,我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件。 你可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 file:/// 形式的 URL),或类名和包名等。

这些配置会告诉 MyBatis 去哪里找映射文件,剩下的细节就应该是每个 SQL 映射文件了

1)使用相对于类路径的资源引用(推荐使用)

<mappers>
        <mapper resource="com/jiyu/dao/LoginMapper.xml"/>
</mappers>

2)使用映射器接口实现类的完全限定类名

<mappers>
        <mapper class="com.jiyu.dao.LoginMapper"/>
</mappers>

注意该方法的使用限制:
接口和对应的Mapper配置文件必须同名且在同一个文件夹下!

3)将包内的映射器接口实现全部注册为映射器

<mappers>
 	 <package name="com.jiyu.dao"/>
</mappers>

和第二种方法的限制一样!

6、作用域(Scope)和生命周期

理解我们之前讨论过的不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。

1)SqlSessionFactoryBuilder
一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)

2)SqlSessionFactory
一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。

3)SqlSession
每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域
如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。

五、属性名和字段名不一致的解决方法

1、在 SELECT 语句中给字段名起别名

MyBatis 会在幕后自动创建一个 ResultMap,再根据属性名来映射列到 JavaBean 的属性上。

<select id="selectUsers" resultType="User">
 select
   user_id             as "id",
   user_name           as "userName",
   hashed_password     as "hashedPassword"
 from some_table
 where id = #{id}
</select>

2、在xml中使用结果映射(resultMap)

resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份 resultMap 能够代替实现同等功能的数千行代码。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

直接使用官网的例子:

先定义一个resultMap(id是主键,result是普通的字段)

<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

然后在引用它的语句中设置 resultMap 属性就行了(注意我们去掉了 resultType 属性)

<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>

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

六、日志

如果一个数据库操作出现异常,需要排错,就需要用到日志

曾经使用的方法:sout、debug
现在:日志工厂

在这里插入图片描述

1、STDOUT_LOGGING(标准日志输出)

在核心配置文件中

<settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

运行后可以在控制台看到日志
主要看以下的部分
在这里插入图片描述

2、LOG4J

在百度百科中有如下解释:
在这里插入图片描述
使用方法:
1)导包
在pom.xml中新增依赖:

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

2)在resources下建立log4j.properties
可以参考博客https://www.jianshu.com/p/ccafda45bcea
以下是比较简单的配置(建议直接copy,不要自己手打,以后基本不会修改)

#1、配置根Logger

#日志记录的最低级别为DEBUG,输出到console和file两个目的地
log4j.rootLogger=DEBUG,console,file

#2、配置日志信息输出目的地(appender)

# 控制台(console)
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件(file)
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/jiyu.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yyy-MM-dd HH:mm:ss}][%c]%m%n

#3、配置日志信息的输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

这一处表示生成的日志文件名称以及所在目录(会自动新建)
在这里插入图片描述

3)配置setting

<settings>
        <setting name="logImpl" value="LOG4J"/>
</settings>

4)运行测试
随便运行一个方法,我这里运行的是getLoginLike()
控制台可以看到
在这里插入图片描述
日志文件jiyu.log可以看到
在这里插入图片描述

再在LoginDaoTest中写一个方法:

@Test
    public void testLog4j(){
        Logger logger = Logger.getLogger(LoginDaoTest.class);

        logger.info("info");
        logger.debug("debug");
        logger.error("error");
    }

运行后,控制台会输出:
在这里插入图片描述
也会在日志文件中输出

七、分页

1、熟悉sql语句

我用的是sql server,所以主要讲解在sql server中的分页,mysql的分页语句更加简单,不难理解

1)首先要会在idea中使用Query Consoles,方便后期我们的测试
在这里插入图片描述
在这里插入图片描述
2)mysql
使用limit

SELECT * FROM tableName LIMIT [offset] ,rows;

3)sql server
使用Offset /Fetch Next,必须有order by ***

select [column1]
      ,[column2]
      ...     
     ,[columnN]
from [tableName]
order by [columnM]
offset (pageIndex-1)*pageSize rows
fetch next pageSize rows only

在这里插入图片描述

2、使用Offset /Fetch Next

1)接口

List<Login> getLoginByFetch(Map<String,Integer> map);

2)xml映射文件

<select id="getLoginByFetch" parameterType="map" resultType="login">
        select * from login
        order by id
        offset #{pageIndex} rows
        fetch next #{pageSize} rows only
</select>

3)测试

 @Test
    public void getLoginByFetch(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);

        HashMap<String, Integer> map = new HashMap<>();
        map.put("pageIndex",0);
        map.put("pageSize",2);

        List<Login> loginList = mapper.getLoginByFetch(map);
        for (Login login : loginList) {
            System.out.println(login);
        }

        sqlSession.close();
    }

控制台输出如下:
在这里插入图片描述

3、使用RowBounds

该方法不需要使用sql(映射文件中的sql语句固定)。仅需要在方法中做一处改动即可

1)接口

    List<Login> getLoginByRowBounds();

2)xml映射文件

<select id="getLoginByRowBounds" resultType="login">
        select * from login
</select>

3)测试

@Test
   public void getLoginByRowBounds(){
       SqlSession sqlSession = MybatisUtils.getSqlSession();

       RowBounds rowBounds = new RowBounds(0, 2);//只需要改动这里的参数即可

       List<Login> loginList = sqlSession.selectList("com.jiyu.dao.LoginMapper.getLoginByRowBounds",null,rowBounds);
       for (Login login : loginList) {
           System.out.println(login);
       }

       sqlSession.close();
   }

在idea中可以看到两个参数的意义,其他两个文件写好后不需要改动
在这里插入图片描述

4、分页插件(Mybatis PageHelper)

官网传送门:https://pagehelper.github.io/
点击左上角 文档 即可查看使用教程,不做详细讲解
在这里插入图片描述

八、使用注解开发

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

1、新建module

1)建立名为test02的module
以下几个文件都是复制test模块的,暂时未做修改
在这里插入图片描述

2、修改几个文件

未提及的文件都是和test模块一模一样,无需修改的

1)核心配置文件

<?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>
<!--    引入外部配置文件-->
    <properties resource="db.properties"/>

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
        <typeAlias type="com.jiyu.entity.Login" alias="login"/>
    </typeAliases>

    <environments default="test">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
                <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=test"/>
                <property name="username" value="sa"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>

        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

<!--绑定接口-->
    <mappers>
        <mapper class="com.jiyu.dao.LoginMapper"/>
    </mappers>
</configuration>

2)接口

package com.jiyu.dao;

import com.jiyu.entity.Login;
import org.apache.ibatis.annotations.Select;

import java.util.List;
import java.util.Map;

public interface LoginMapper {
    @Select("select * from login")
    List<Login> getLogins();
}

3)测试
新建LoginMapperTest
在这里插入图片描述

import com.jiyu.dao.LoginMapper;
import com.jiyu.entity.Login;
import com.jiyu.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class LoginMapperTest {
    @Test
    public void getLogins(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);
        List<Login> logins = mapper.getLogins();
        for (Login login : logins) {
            System.out.println(login);
        }

        sqlSession.close();
    }
}

运行结果
在这里插入图片描述

3、CRUD

先设置事务自动提交
在MybatisUtils.java中,给openSession方法添加参数true,表示自动commit
在这里插入图片描述
1)接口

package com.jiyu.dao;

import com.jiyu.entity.Login;
import org.apache.ibatis.annotations.*;

import java.util.List;
import java.util.Map;

/**
 * @author jiyu
 * @create 2021-09-21 18:48
 * @description
 */
public interface LoginMapper {
    @Select("select * from login")
    List<Login> getLogins();

    //方法存在多个参数,所有的参数前面必须加上@param("")注解
    @Select("select * from login where id=#{id}")
    Login getLoginById(@Param("id") int id);

    @Insert("insert into login(id,name,pwd) values(#{id},#{name},#{pwd})")
    int addLogin(Login login);

    @Update("update login set name=#{name},pwd=#{pwd} where id=#{id}")
    int updateLogin(Login login);

    @Delete("delete from login where id=#{uid}")
    int deleteLogin(@Param("uid") int id);//注解使用的是@Param("uid")中的uid而非该方法的参数id
}

2)测试

import com.jiyu.dao.LoginMapper;
import com.jiyu.entity.Login;
import com.jiyu.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

/**
 * @author jiyu
 * @create 2021-09-26 23:33
 * @description
 */
public class LoginMapperTest {
    @Test
    public void getLogins(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);
        List<Login> logins = mapper.getLogins();
        for (Login login : logins) {
            System.out.println(login);
        }

        sqlSession.close();
    }

    @Test
    public void getLoginById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);
        Login loginById = mapper.getLoginById(1);
        System.out.println(loginById);
        sqlSession.close();
    }

    @Test
    public void addLogin(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);
        mapper.addLogin(new Login(666,"test","testpass"));

        sqlSession.close();
    }

    @Test
    public void updateLogin(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);
        mapper.updateLogin(new Login(666,"test666","test666pass"));

        sqlSession.close();
    }

    @Test
    public void deleteLogin(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);
        mapper.deleteLogin(666);

        sqlSession.close();
    }
}

九、复杂查询环境搭建

1、建表

新建名为complex relationship的数据库
连接
在这里插入图片描述
接下来新建表
1)teacher

create table teacher
(
    id   int not null
        constraint teacher_pk
            primary key nonclustered,
    name nvarchar(30)
)

数据
在这里插入图片描述
2)student
外键:tid(对应teacher的id)

create table student
(
	id int not null
		constraint student_pk
			primary key nonclustered,
	name nvarchar(30),
	tid int
		constraint student_teacher_id_fk
			references teacher
				on update cascade on delete cascade
)

数据
在这里插入图片描述
可以查看两张表的关系
在这里插入图片描述

在这里插入图片描述

2、新建module并测试

1)建立module:test03
2)module中的文件:(数字代表建立的顺序)
在这里插入图片描述
下面是所有文件的代码,用数字表示文件名
1、

driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
url=jdbc:sqlserver://localhost:1433;databaseName=complex relationship
username=sa
password=123456

2、(mappers部分在建立了两个接口文件后再写进去)

<?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>
<!--    引入外部配置文件-->
    <properties resource="db.properties"/>

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <typeAliases>
        <typeAlias type="com.jiyu.entity.Teacher" alias="teacher"/>
        <typeAlias type="com.jiyu.entity.Student" alias="student"/>
    </typeAliases>

    <environments default="test">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
                <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=test"/>
                <property name="username" value="sa"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>

        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper class="com.jiyu.dao.TeacherMapper"/>
        <mapper class="com.jiyu.dao.StudentMapper"/>
    </mappers>
</configuration>

3、

package com.jiyu.utils;

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;

public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    //1、从 XML 中构建 SqlSessionFactory
    static {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //2、从 SqlSessionFactory 中获取 SqlSession
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession(true);
    }
}

4、

package com.jiyu.entity;

public class Teacher {
    private int id;
    private String name;

    public Teacher(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public Teacher() {
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

5、

package com.jiyu.entity;

public class Student {
    private int id;
    private String name;
    private Teacher teacher;//关联老师

    public Student() {
    }

    public Student(int id, String name, Teacher teacher) {
        this.id = id;
        this.name = name;
        this.teacher = teacher;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Teacher getTeacher() {
        return teacher;
    }

    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", teacher=" + teacher +
                '}';
    }
}

6、

package com.jiyu.dao;

import com.jiyu.entity.Teacher;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface TeacherMapper {

    @Select("select * from teacher where id=#{tid}")
    Teacher getTeacher(@Param("tid") int id);
}

7、

package com.jiyu.dao;

public interface StudentMapper {
}

8、

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

<mapper namespace="com.jiyu.dao.TeacherMapper">

</mapper>

9、

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

<mapper namespace="com.jiyu.dao.StudentMapper">

</mapper>

10、

import com.jiyu.dao.TeacherMapper;
import com.jiyu.entity.Teacher;
import com.jiyu.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;

public class MyTest {
    public static void main(String[] args) {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher = mapper.getTeacher(1);
        System.out.println(teacher);


        sqlSession.close();
    }
}

运行结果
在这里插入图片描述
至此说明基本的环境已经配置好了

3、多对一的处理

目的:查询所有的学生信息,以及对应的老师的信息
对应sql语句:

select s.id,s.name,t.name from student s,teacher t where s.tid=t.id

但是该语句涉及到了两个实体(多表查询),所以在xml映射文件中不能仅通过简单的一句sql来实现

1、先看问题的引入:select * from student

1)接口(StudentMapper)

public List<Student> getStudent();

2)xml映射文件

<select id="getStudent" resultType="Student">
        select * from student
    </select>

3)测试

 @Test
   public void testStudent(){
       SqlSession sqlSession = MybatisUtils.getSqlSession();
       StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
       List<Student> students = mapper.getStudent();
       for (Student student : students) {
           System.out.println(student);
       }

       sqlSession.close();
   }

结果:在这里插入图片描述
出现了teacher=null的情况(因为对象的属性和表中的字段没有对应)
这个时候就需要一个对teacher的查询

2、解决方法一:嵌套 Select 查询(类似sql中的嵌套查询)

1)接口:不变
2)xml映射文件:
修改为

<select id="getStudent" resultMap="StudentTeacher">
        select * from student
    </select>
    <resultMap id="StudentTeacher" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
<!--        单一的属性用result,复杂的属性需要单独处理  对象:association(多对一) 集合:collection(一对多)-->
        <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
    </resultMap>

    <select id="getTeacher" resultType="Teacher">
        select * from teacher where id=#{id}
    </select>

association那一行表示:
在查询学生时,字段tid映射为teacher,并且是一个对象,对象类型为Teacher,这个对象需要使用一个select语句,对应的查询语句id为getTeacher

在官网对select的解释:
在这里插入图片描述
所以,column中的tid会作为参数传递给查询语句的大括号中的“id”,实际上,无论大括号内写什么,都不会影响最后的效运行结果,因为他的参数只取决于column的属性
在这里插入图片描述

3)测试:不变
直接运行
在这里插入图片描述

3、解决方法二:相当于联表查询(较为简单)

1)接口:

    public List<Student> getStudent2();

2)xml映射文件

	<select id="getStudent2" resultMap="StudentTeacher2">
        select s.id sid,s.name sname,t.name tname
        from student s,teacher t 
        where s.tid=t.id;
    </select>
    <resultMap id="StudentTeacher2" type="Student">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <association property="teacher" javaType="Teacher">
            <result property="name" column="tname"/>
        </association>
    </resultMap>

3)测试:

@Test
    public void testStudent2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> students = mapper.getStudent2();
        for (Student student : students) {
            System.out.println(student);
        }

        sqlSession.close();
    }

运行结果同方法一
该方法比方法一简洁,而且只需要一句sql,不需要像方法一那样写多句sql,建议使用该方法

4、一对多的处理

1、环境搭建

1)新建module:test04
2)java和resources文件夹下的都是从test03复制的,将dao中两个接口的方法清空,xml映射文件的mapper标签对中的内容清空,测试类MyTest也清空。其他文件暂且不修改

在这里插入图片描述

3)修改实体类
Student类。无参和有参构造器、get、set、toString方法自己生成(Shift+Alt+s)
在这里插入图片描述

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

2、问题的引入

1)接口(TeacherMapper)

public interface TeacherMapper {
    List<Teacher> getTeacher();
}

2)xml映射文件

<select id="getTeacher" resultType="Teacher">
        select * from teacher
</select> 

3)测试

public class MyTest {
    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        List<Teacher> teachers = mapper.getTeacher();
        for (Teacher teacher : teachers) {
            System.out.println(teacher);
        }

        sqlSession.close();
    }
}

结果:
在这里插入图片描述
可以看到students=null

3、解决方法

先用sql查询
在这里插入图片描述

1)接口

Teacher getTeacher2(@Param("tid") int id);

2)xml映射文件

	<select id="getTeacher2" resultMap="TeacherStudent">
        select s.id sid,s.name sname,t.name tname,t.id tid
        from student s,teacher t
        where s.tid=t.id and t.id=#{tid}
    </select>
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
<!--        集合中的泛型信息使用ofType获取-->
        <collection property="students" ofType="Student">
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

官网关于ofType的使用说明
在这里插入图片描述
3)测试

 @Test
    public void test2(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teacher2 = mapper.getTeacher2(1);
        System.out.println(teacher2);

        sqlSession.close();
    }

结果:
在这里插入图片描述

Teacher{id=1, name='张三老师', students=[
Student{id=1, name='学生1', tid=1}, 
Student{id=2, name='学生2', tid=1}, 
Student{id=3, name='学生3', tid=1},
 Student{id=4, name='学生4', tid=1}, 
 Student{id=5, name='学生5', tid=1}]}

十、动态sql

动态sql:根据不同的条件生成不同的sql语句。语法类似JSTL

1、建表

create table blog
(
	id nvarchar(50) not null,
	title nvarchar(100) not null,
	author nvarchar(30) not null,
	create_time datetime not null,
	views int not null
)

2、新建module

建立module: test05
在这里插入图片描述
只有MybatisUtils和db.properties是不变的,直接复制以前的,其他几个文件内容如下:
1)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>
<!--    引入外部配置文件-->
    <properties resource="db.properties"/>

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
        <setting name="mapUnderscoreToCamelCase" value="true"/><!--开启驼峰命名自动映射-->
    </settings>

    <typeAliases>
        <typeAlias type="com.jiyu.entity.Blog" alias="blog"/>
    </typeAliases>

    <environments default="test">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver"/>
                <property name="url" value="jdbc:sqlserver://localhost:1433;databaseName=test"/>
                <property name="username" value="sa"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>

        <environment id="test">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper class="com.jiyu.dao.BlogMapper"/>
    </mappers>
</configuration>

其中,<setting name="mapUnderscoreToCamelCase" value="true"/>用法如下
在这里插入图片描述
2)IdUtils
使用UUID生成随机ID

package com.jiyu.utils;

import org.junit.Test;

import java.util.UUID;

public class IdUtils {

    public static String getId(){
        return UUID.randomUUID().toString().replaceAll("-","");
    }

    @Test
    public void test(){
        System.out.println(IdUtils.getId());
        System.out.println(IdUtils.getId());
        System.out.println(IdUtils.getId());
        System.out.println(IdUtils.getId());
    }
}

运行test方法可以查看随机生成的id
3)Blog
实体类

package com.jiyu.entity;

import java.util.Date;

public class Blog {
    private String id;
    private String title;
    private String author;
    private Date createTime;
    private int views;
//省略了有参和无参构造器、get和set、toString方法
   }

4)BlogMapper
接口

package com.jiyu.dao;

import com.jiyu.entity.Blog;

public interface BlogMapper {

    int addBlog(Blog blog);
}

5)BlogMapper.xml
xml映射文件

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

<mapper namespace="com.jiyu.dao.BlogMapper">
    <insert id="addBlog" parameterType="Blog">
        insert into blog (id, title, author, create_time, views)
        values (#{id},#{title},#{author},#{createTime},#{views});
    </insert>
</mapper>

6)MyTest
测试

import com.jiyu.dao.BlogMapper;
import com.jiyu.entity.Blog;
import com.jiyu.utils.IdUtils;
import com.jiyu.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.Date;

public class MyTest {
    @Test
    public void addInitBlog(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        Blog blog=new Blog();
        blog.setId(IdUtils.getId());
        blog.setTitle("Mybatis如此简单");
        blog.setAuthor("jiyu");
        blog.setCreateTime(new Date());
        blog.setViews(9999);
        mapper.addBlog(blog);

        blog.setId(IdUtils.getId());
        blog.setTitle("Java如此简单");
        blog.setViews(1000);
        mapper.addBlog(blog);

        blog.setId(IdUtils.getId());
        blog.setTitle("Spring如此简单");
        blog.setViews(9999);
        mapper.addBlog(blog);

        blog.setId(IdUtils.getId());
        blog.setTitle("微服务如此简单");
        mapper.addBlog(blog);

        sqlSession.close();
    }
}

运行后,查看表blog,共插入了四条记录
在这里插入图片描述

3、if

1)接口

    List<Blog> queryBlogIF(Map map);

2)xml映射文件

<select id="queryBlogIF" parameterType="map" resultType="blog">
        select * from blog where 1=1
        <if test="title !=null">
            and title=#{title}
        </if>
        <if test="author !=null">
            and author=#{author}
        </if>
    </select>

3)测试

 @Test
    public void queryBlogIF(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap map = new HashMap();
        List<Blog> blogs = mapper.queryBlogIF(map);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }

        sqlSession.close();
    }

运行结果:
在这里插入图片描述
因为传入的map为空,所以sql语句相当于select * from blog

当在测试文件加上这句代码,修改map后
在这里插入图片描述
运行结果:在这里插入图片描述
此时sql相当于select * from blog where title='Java如此简单'
所以只能查到一条数据
如果修改成下面这样,那么sql相当于select * from blog where author='jiyu'
在这里插入图片描述

4、where

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。

1)接口

    List<Blog> queryBlogWhere(Map map);

2)xml映射文件

	<select id="queryBlogWhere" parameterType="map" resultType="blog">
        select * from blog
        <where>
            <if test="title !=null">
                 title=#{title}
            </if>
            <if test="author !=null">
                and author=#{author}
            </if>
        </where>
    </select>

3)测试

@Test
    public void queryBlogWhere(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap map = new HashMap();
         map.put("title","Java如此简单");
//        map.put("author","jiyu");

        List<Blog> blogs = mapper.queryBlogWhere(map);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }

        sqlSession.close();
    }

5、choose、when、otherwise

官网的简介非常清楚
相当于switch case default
在这里插入图片描述
用法如下:
1)接口

    List<Blog> queryBlogChoose(Map map);

2)xml映射文件

	<select id="queryBlogChoose" parameterType="map" resultType="blog">
        select * from blog
            <where>
                <choose>
                    <when test="title !=null">
                        title=#{title}
                    </when>
                    <when test="author !=null">
                        and author=#{author}
                    </when>
                    <otherwise>
                        and views=#{views}
                    </otherwise>
                </choose>
            </where>
    </select>

3)测试

@Test
    public void queryBlogChoose(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap map = new HashMap();

        map.put("title","Java如此简单");
//        map.put("author","jiyu");
        map.put("views",9999);

        List<Blog> blogs = mapper.queryBlogChoose(map);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }

        sqlSession.close();
    }

这三行代码挨个注释再运行方法,可以深入理解choose的运用
在这里插入图片描述

6、set

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

1)接口

    int updateBlog(Map map);

2)xml映射文件

<update id="updateBlog" parameterType="map">
        update blog
        <set>
            <if test="title !=null">
                title=#{title},
            </if>
            <if test="author !=null">
                author=#{author}
            </if>
        </set>
        where id=#{id}
    </update>

3)测试

@Test
    public void updateBlog(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap map = new HashMap();

        map.put("title","Java如此简单2");
        map.put("author","jiyu");
        map.put("id","75124c5898224b39aff8769a6697103b");
//        map.put("views",9999);

        mapper.updateBlog(map);

        sqlSession.close();
    }

运行后对应的title改变
在这里插入图片描述

7、trim

官网说明如下,不做过多说明
在这里插入图片描述
在这里插入图片描述

8、foreach

如图是对应关系
在这里插入图片描述
接下来开始引入问题

先更改表中的各个id,方便测试
在这里插入图片描述

问题:遍历1、2、3号记录

sql:

select *
from blog
where (id=1 or id=2 or id=3);

在这里插入图片描述
1)接口

    List<Blog> queryBlogForeach(Map map);

2)xml映射文件

	<select id="queryBlogForeach" parameterType="map" resultType="blog">
        select * from blog
        <where>
            <foreach collection="ids" item="id" open="(" close=")" separator="or">
                id=#{id}
            </foreach>
        </where>
    </select>

ids就是由map传入的
在这里插入图片描述
这一段表明,
开头是"("
结尾是 “)”
分隔符是 “or”
可以看做

select *
from blog
where (id=? or id=? or id=?......);

3)测试

@Test
    public void queryBlogForeach(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);

        HashMap map = new HashMap();

        ArrayList<Integer> ids = new ArrayList<>();
        ids.add(1);
        ids.add(2);
        ids.add(3);

        map.put("ids",ids);

        List<Blog> blogs = mapper.queryBlogForeach(map);

        for (Blog blog : blogs) {
            System.out.println(blog);
        }

        sqlSession.close();
    }

在这里插入图片描述

9、SQL片段

将一些常用的SQL代码复用

下面的代码在之前我们经常会用到,所以可以用include标签引用

<if test="title !=null">
 	title=#{title},
</if>
<if test="author !=null">
    author=#{author}
</if>

先定义这段sql

	<sql id="if-title-author">
        <if test="title !=null">
            and title=#{title}
        </if>
        <if test="author !=null">
            and author=#{author}
        </if>
    </sql>

在引用的时候格式如下,直接写在要引用的位置,相当于写了定义的那段sql

<include refid="if-title-author"></include>

refid对应<sql id="if-title-author">中的id

十一、缓存

一级缓存:基于sqlSession级别
二级缓存:基于namespace级别

下面是官网中比较重要的话
在这里插入图片描述
在这里插入图片描述
这部分我就不详细说了,可以去看狂神的讲解,非常详细

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2021-09-30 12:08:32  更:2021-09-30 12:10:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 3:19:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码