一. Mybatis入门案例

1648518999727.png

  1. # 入门案例的步骤
  2. 1. pom文件中导入依赖
  3. 2. 编写配置文件
  4. 3. 编写接口和实体类
  5. 4. 测试类

0. 数据准备

create database day08;
use day08;
create table user (
  id int primary key auto_increment,
  username varchar(20) not null,
  birthday date,
  sex char(1) default '男',
  address varchar(50)
);

insert into user values (null, '孙悟空','1980-10-24','男','花果山水帘洞');
insert into user values (null, '白骨精','1992-11-12','女','白虎岭白骨洞');
insert into user values (null, '猪八戒','1983-05-20','男','福临山云栈洞');
insert into user values (null, '蜘蛛精','1995-03-22','女','盤丝洞');

select * from user;

1. 在pom文件中导入依赖

<dependencies>
        <!--mybatis核心包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.0</version>
        </dependency>
        <!--logback日志包: mybatis底层使用的日志框架,用于打印mybatis运行信息-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.26</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!--mysql驱动 : mybatis底层封装了JDBC(接口),所以驱动(实现类)必须要有 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.18</version>
        </dependency>
        <!--
            junit单元测试框架
        -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2. 编写配置文件

logback.xml

logback日志框架的配置文件,规定了mybatis输出日志的格式
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--
        CONSOLE :表示当前的日志信息是可以输出到控制台的。
    -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--输出流对象 默认 System.out 改为 System.err-->
        <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>
        <!--日志输出路径-->
        <file>C:/code/itheima-data.log</file>
        <!--指定日志文件拆分和压缩规则-->
        <rollingPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--通过指定压缩文件名称,来确定分割文件方式-->
            <fileNamePattern>C:/code/itheima-data2-%d{yyyy-MMdd}.log%i.gz</fileNamePattern>
            <!--文件拆分大小-->
            <maxFileSize>1MB</maxFileSize>
        </rollingPolicy>
    </appender>

    <!--

    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
   , 默认debug
    <root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
    -->
    <root level="ALL">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE" />
    </root>
</configuration>

mybatis-config.xml

mybatis核心配置文件: 待会详解!!!
<?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>
    <!--mybatis环境的配置-->
    <environments default="development">
        <!--通常我们只需要配置一个就可以了, id是环境的名字 -->
        <environment id="development">
            <!--事务管理器:由JDBC来管理-->
            <transactionManager type="JDBC"/>
            <!--数据源的配置:mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/day08"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--加载映射文件,放到src下即可-->
        <mapper resource="userMapper.xml"/>
    </mappers>
</configuration>

userMapper.xml

UserMapper接口的sql映射文件(待会详解!!!)
<?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.itheima.sh.dao.UserMapper">
    <!--
        查询语句
        resultType:返回的实体类的类型,类全名
    -->
    <select id="findAllUsers" resultType="com.itheima.sh.pojo.User">
        select * from user
    </select>
</mapper>

3. 编写接口和实体类

package com.itheima.sh.dao;

import com.itheima.sh.pojo.User;

import java.util.List;

public interface UserMapper {
    /**
     查询所有的用户
     */
    List<User> findAllUsers();
}
package com.itheima.sh.pojo;

import java.util.Date;

public class User {

    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    public User() {
    }

    public User(Integer id, String username, Date birthday, String sex, String address) {
        this.id = id;
        this.username = username;
        this.birthday = birthday;
        this.sex = sex;
        this.address = address;
    }

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

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

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

4. 测试类

package com.itheima.sh.test;

import com.itheima.sh.dao.UserMapper;
import com.itheima.sh.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 org.junit.Test;

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

public class MyBatisTest01 {

    //从MySQL中查询所有的用户
    @Test
    public void test02() throws Exception{
        //1.从xml文件中构建SqlSessionFactory
        //定义核心配置文件路径
        String resource = "mybatis-config.xml";
        //加载核心配置文件获取输入流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //2.从SqlSessionFactory中获取session
        SqlSession session = sqlSessionFactory.openSession();

        //3.使用session获取接口的动态代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);
        //4.使用接口对象调用接口中的方法
        List<User> userList = mapper.findAllUsers();
        //5.遍历集合
        for (User user : userList) {
//            System.out.println(user); // 打印黑字: 普通信息
            System.err.println(user); // 打印红字: 一般用来打印异常信息
        }
        //关闭会话
        session.close();
    }
}

运行结果

06-Mybatis课堂笔记(1) - 图2

二. 入门案例运行原理

从测试类入手

1648521312709.png

package com.itheima.sh.test;

import com.itheima.sh.dao.UserMapper;
import com.itheima.sh.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 org.junit.Test;

import java.io.InputStream;
import java.util.List;
/*
    建造者模式: 创建对象
    工厂设计模式: 创建对象
    代理模式: 动态代理(a. 创建代理对象 b. 基于接口)
 */
public class MyBatisTest01 {

    //从MySQL中查询所有的用户
    @Test
    public void test02() throws Exception{
        //TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
        //定义核心配置文件路径
        String resource = "mybatis-config.xml";
        //加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
        SqlSession session = sqlSessionFactory.openSession();

        //TODO: 3.使用session获取接口的动态代理对象
            //接口类型 变量 = 接口的实现类对象
            //在源码里面并没看到实现类在哪里, 那说明实现类是运行时动态生成的(动态代理)
            // invoke方法的实现: 根据 接口映射文件 编写的(jdbc)
        UserMapper mapper = session.getMapper(UserMapper.class);
        //TODO: 4.使用接口类型的对象调用接口中的方法
        List<User> userList = mapper.findAllUsers();
        //5.遍历集合
        for (User user : userList) {
//            System.out.println(user); // 打印黑字: 普通信息
            System.err.println(user); // 打印红字: 一般用来打印异常信息
        }
        //关闭会话
        session.close();
    }
}

第三章 mybatis核心配置

【mybatis全局配置介绍】

mybatis-config.xml,是MyBatis的全局配置文件,包含全局配置信息,如数据库连接参数、插件等。整个框架中只需要一个即可。
1. mybatis全局配置文件是mybatis框架的核心配置,整个框架只需一个;
2. mybatis全局配置文件中的配置顺序:注意如果配置多项,必须按照以下顺序进行配置(dtd约束)
    1). properties:属性配置
    2). settings:设置
    3). typeAliases:类型别名设置
    4). environments:环境配置
        environment(环境变量)
        transactionManager(事务管理器)
        dataSource(数据源)
    5). mappers:映射器

1. enviroments标签

<!-- TODO: environments标签 : mybatis环境的配置
        1. mybatis可以配置多个环境 (复数)
            1). 实际工作中可能会有多个环境
                I. 开发环境
                II. 测试环境
                III. 生产环境
            2).environments标签可以有多个environment子标签
            3). 具体的使用哪个环境 由environments的 default指定
        2. environment标签
            1). id属性 : 当前环境的标识
            2). transactionManager子标签 : 事务管理器(不用的,后续会被spring的声明式事务所替代)
            3). dataSource子标签 (连接池)
                type=POOLED : 用mybatis自带连接池(如果要切换其他连接池,比如druid,在spring学习)
                driver用来配置驱动
                url用来配置数据库的地址
                username数据库的用户名
                password数据库的密码
    -->
    <environments default="development">
        <!--通常我们只需要配置一个就可以了, id是环境的名字 -->
        <environment id="development">
            <!--事务管理器:由JDBC来管理-->
            <transactionManager type="JDBC"/>
            <!--数据源的配置:mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/day08"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
       <!-- <environment id="test">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/day09"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
        </environment>-->
    </environments>

2. properties标签

1648524230532.png

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/day09
jdbc.username=root
jdbc.password=root
 <!--
        environments标签内目前只有jdbc四项配置能够切换,
        这个切换直接放在核心配置文件中,很不方便,mybatis可以将这4个变量抽取出去
        TODO: properties标签
        1. 作用: 加载properties配置文件
        2. 后续可以使用mybatis的通配符,引用properties配置文件中的数据
                ${properties中的key}
        3. 作用: 将变量从核心配置文件中解耦出去
    -->
    <properties resource="jdbc.properties"/>

    <environments default="development">
        <!--通常我们只需要配置一个就可以了, id是环境的名字 -->
        <environment id="development">
            <!--事务管理器:由JDBC来管理-->
            <transactionManager type="JDBC"/>
            <!--数据源的配置:mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

3. mappers标签

1648525998838.png

1648525619929.png

1648525810489.png
1648525941542.png

 <!--
        TODO: mappers标签(用于指定dao层接口对应的sql映射文件)
    -->
    <mappers>
        <!--加载映射文件,得让mybatis知道有这个配置文件
            缺陷: 如果有多个dao层接口就需要编写多个映射
        -->
       <!-- <mapper resource="userMapper.xml"/>
        <mapper resource="xx.xml"/>-->

        <!--
            包扫描: 扫描所有指定包下的接口与其对应的sql映射文件
            对接口的映射文件要求:
                1). 文件名必须和接口名一致
                2). 文件名的路径必须和接口路径一致
        -->
        <package name="com.itheima.sh.dao"/>
    </mappers>

4. settings标签

  <!--
        TODO: settings标签(用于设置)
        1. 内部可作多项配置
        2. 目前只需要掌握一项配置: 驼峰映射
                   对象的属性名为 小驼峰     那么映射 表中字段名 单词_单词...
            比如说: 对象的属性名为 userName 那么映射 表中字段名 user_name
                            passWordString               pass_word_string
                                sex                      sex
    -->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

5.typeAliases标签

1648536794956.png

   <!--
        TODO: typeAliases标签: 用于设置类型别名
        1. package : 扫描哪个包
            比如我们这里的pojo包被扫描了, 那么pojo包下所有的类都自动起别名
            com.itheima.sh.pojo.User -> User/user
    -->
    <typeAliases>
        <package name="com.itheima.sh.pojo"/>
    </typeAliases>

完整核心配置文件

<?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标签内目前只有jdbc四项配置能够切换,
        这个切换直接放在核心配置文件中,很不方便,mybatis可以将这4个变量抽取出去
        TODO: properties标签
        1. 作用: 加载properties配置文件
        2. 后续可以使用mybatis的通配符,引用properties配置文件中的数据
                ${properties中的key}
        3. 作用: 将变量从核心配置文件中解耦出去
    -->
    <properties resource="jdbc.properties"/>

    <!--
        TODO: settings标签(用于设置)
        1. 内部可作多项配置
        2. 目前只需要掌握一项配置: 驼峰映射
                   对象的属性名为 小驼峰     那么映射 表中字段名 单词_单词...
            比如说: 对象的属性名为 userName 那么映射 表中字段名 user_name
                            passWordString               pass_word_string
                                sex                      sex
    -->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <!--
        TODO: typeAliases标签: 用于设置类型别名
        1. package : 扫描哪个包
            比如我们这里的pojo包被扫描了, 那么pojo包下所有的类都自动起别名
            com.itheima.sh.pojo.User -> User/user
    -->
    <typeAliases>
        <package name="com.itheima.sh.pojo"/>
    </typeAliases>
    <!-- TODO: environments标签 : mybatis环境的配置
        1. mybatis可以配置多个环境 (复数)
            1). 实际工作中可能会有多个环境
                I. 开发环境
                II. 测试环境
                III. 生产环境
            2).environments标签可以有多个environment子标签
            3). 具体的使用哪个环境 由environments的 default指定
        2. environment标签
            1). id属性 : 当前环境的标识
            2). transactionManager子标签 : 事务管理器(不用的,后续会被spring的声明式事务所替代)
            3). dataSource子标签 (连接池)
                type=POOLED : 用mybatis自带连接池(如果要切换其他连接池,比如druid,在spring学习)
                driver用来配置驱动
                url用来配置数据库的地址
                username数据库的用户名
                password数据库的密码
    -->
    <environments default="development">
        <!--通常我们只需要配置一个就可以了, id是环境的名字 -->
        <environment id="development">
            <!--事务管理器:由JDBC来管理-->
            <transactionManager type="JDBC"/>
            <!--数据源的配置:mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
       <!-- <environment id="test">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/day09"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
        </environment>-->
    </environments>

    <!--
        TODO: mappers标签(用于指定dao层接口对应的sql映射文件)
    -->
    <mappers>
        <!--加载映射文件,得让mybatis知道有这个配置文件
            缺陷: 如果有多个dao层接口就需要编写多个映射
        -->
       <!-- <mapper resource="userMapper.xml"/>
        <mapper resource="xx.xml"/>-->

        <!--
            包扫描: 扫描所有指定包下的接口与其对应的sql映射文件
            对接口的映射文件要求:
                1). 文件名必须和接口名一致
                2). 文件名的路径必须和接口路径一致
        -->
        <package name="com.itheima.sh.dao"/>
    </mappers>

</configuration>

第四章 mybatis 增删改查

基本环境

1648542243127.png

pom.xml

 <dependencies>
        <!--mybatis核心包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.0</version>
        </dependency>
        <!--logback日志包: mybatis底层使用的日志框架,用于打印mybatis运行信息-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.26</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!--mysql驱动 : mybatis底层封装了JDBC(接口),所以驱动(实现类)必须要有 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.18</version>
        </dependency>
        <!--
            junit单元测试框架
        -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

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="jdbc.properties"/>

    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <!--
        扫描pojo所在的包: 起别名
    -->
    <typeAliases>
        <package name="com.itheima.pojo"/>
    </typeAliases>
    <environments default="development">
        <!--通常我们只需要配置一个就可以了, id是环境的名字 -->
        <environment id="development">
            <!--事务管理器:由JDBC来管理-->
            <transactionManager type="JDBC"/>
            <!--数据源的配置:mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--
        扫描接口所在的包
            1. sql映射文件名必须和接口一致
            2. 路径必须一致
    -->
    <mappers>
        <package name="com.itheima.dao"/>
    </mappers>

</configuration>

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/day08
jdbc.username=root
jdbc.password=root

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--
        CONSOLE :表示当前的日志信息是可以输出到控制台的。
    -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--输出流对象 默认 System.out 改为 System.err-->
        <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>
        <!--日志输出路径-->
        <file>C:/code/itheima-data.log</file>
        <!--指定日志文件拆分和压缩规则-->
        <rollingPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--通过指定压缩文件名称,来确定分割文件方式-->
            <fileNamePattern>C:/code/itheima-data2-%d{yyyy-MMdd}.log%i.gz</fileNamePattern>
            <!--文件拆分大小-->
            <maxFileSize>1MB</maxFileSize>
        </rollingPolicy>
    </appender>

    <!--

    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF
   , 默认debug
    <root>可以包含零个或多个<appender-ref>元素,标识这个输出位置将会被本日志级别控制。
    -->
    <root level="ALL">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE" />
    </root>
</configuration>

重点

/*

    TODO mybatis的orm思想要求: 实例类 (pojo: Plain Old Java Object 简单的 Java 对象)
    一. 硬性规范(不能违背,违背会报错)
        1. 属性名必须要和字段名一致
        2. 必须要有get/set方法
        3. public 空参构造
    二. 软性规范(可以违背,推荐你这么做)
        1. 类名跟表名一致
        2. 字段类型如果没有特殊要求,直接写String
        3. 基本类型不要用,用对应包装类型

 */
public class User {
    private Integer id;
    private String username;
    private String birthday;
    private String sex;
    private String address;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday='" + birthday + '\'' +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

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

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
package com.itheima.dao;

import com.itheima.pojo.User;

import java.util.Date;
import java.util.List;

/*
    TODO 需求: 用mybatis完成user表的crud(增删改查)
    1. 编写一个接口
        1). 接口名: 表名Mapper 或者  表名Dao
        2). 定义抽象方法
            I. 参数
            II. 返回值
    2. 编写接口的sql映射文件
        1). 位置: 一定要注意
 */
public interface UserMapper {

    //查询全部 : select * from user;
    List<User> findAllUsers();

    //根据id查询用户: select * from user where id = ?
        //参数: int类型的id,返回值是User类型
    User findUserById(Integer id);

    //查询用户总数: select count(*) from user;
        //参数: 无 , 返回值: int类型
    Integer findUserTotal();

    //根据id删除用户: delete from user where id = ?;
        //参数需要int类型的id,返回值是被影响的行数int
        // id = 3
    int deleteById(Integer id);

    //增加一条用户数据: insert into user values(null,?,?,?,?);
        //参数: User对象 ,返回值是被影响的行数int
//   int  addUser(String username, Date birthday,String sex,String address);
    int addUser(User user);

    //根据id修改用户: update user set username=?,birthday=?,sex=?,address=? where id = ?
        // 参数: User对象 ,返回值是被影响的行数int
    int updateUserById(User user);
}

userMapper.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">
<!--
    TODO: UserMapper接口的sql映射文件
    1. mapper根标签的namespace : 接口类型的全路径名(包名+接口名)

-->
<mapper namespace="com.itheima.dao.UserMapper">
    <!--
        查询语句
        id : 对应接口的方法名
        resultType:结果集类型
            1. 返回的User或者List<User>类型,一般要写类全名
                    1). 类全名: com.itheima.sh.pojo.User
                    2). 如果有设置 "typeAliases" 包扫描,可以直接写User或 user
            2.  返回的基本类型或string
                直接写即可
    -->
    <select id="findAllUsers" resultType="user">
        select * from user
    </select>
    <select id="findUserById" resultType="user">
        select * from user where id = #{id}
    </select>
    <select id="findUserTotal" resultType="int">
        select count(*) from user
    </select>

    <!--
        delete标签用于编写删除方法对应的sql
        1. id 方法名
        2. 返回值: 固定就是int, 返回被影响行数
        3. mybatis的通配符
             #{变量名}
    -->
    <delete id="deleteById">
        delete from user where id = #{id}
    </delete>
    <!--
            insert标签用于编写添加方法对应的sql
            1. id 方法名
            2. 返回值: 固定就是int, 返回被影响行数
            3. mybatis的通配符
                 #{变量名}
                 1). 如果方法的参数只有一个,且为基本类型或String
                    #{参数变量名}
                 2). 如果方法的参数只有一个,且为pojo类型
                    #{pojo的属性名}
                   #{username} 相当于 user.getUsername();
        -->
    <insert id="addUser">
        insert into user values(null,#{username},#{birthday},#{sex},#{address})
    </insert>

    <update id="updateUserById">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
         where id = #{id}
    </update>
</mapper>

测试类

package com.itheima.test;

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

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

public class TestDemo {

    @Test
    public void add() throws IOException {
        //TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
        //定义核心配置文件路径
        String resource = "mybatis-config.xml";
        //加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
        SqlSession session = sqlSessionFactory.openSession();

        //TODO: 3.使用session获取接口的动态代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);
        //TODO: 4.使用接口类型的对象调用接口中的方法
        User user = new User();
        user.setUsername("张三");
        user.setBirthday("1998-01-01");
        user.setAddress("杭州");
        user.setSex("女");

        mapper.addUser(user);
        //关闭会话
        session.commit();
        session.close();

    }

    @Test
    public void update() throws IOException {
        //TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
        //定义核心配置文件路径
        String resource = "mybatis-config.xml";
        //加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
        SqlSession session = sqlSessionFactory.openSession();

        //TODO: 3.使用session获取接口的动态代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);
        //TODO: 4.使用接口类型的对象调用接口中的方法
        User user = new User();
        user.setId(6);
        user.setUsername("张三丰");
        user.setBirthday("1998-01-01");
        user.setAddress("杭州");
        user.setSex("女");

        int count = mapper.updateUserById(user);
        System.out.println("被影响的行数:" + count);
        //关闭会话
        session.commit();
        session.close();

    }

    @Test
    public void delete() throws IOException {
        //TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
        //定义核心配置文件路径
        String resource = "mybatis-config.xml";
        //加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
        SqlSession session = sqlSessionFactory.openSession();

        //TODO: 3.使用session获取接口的动态代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);
        //TODO: 4.使用接口类型的对象调用接口中的方法
        int count = mapper.deleteById(6);
        System.out.println("被影响的行数:" + count);
        //关闭会话
        session.commit();
        session.close();

    }
}
package com.itheima.test;

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

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

public class TestDemo2 {

    @Test
    public void add() throws IOException {
        //TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
        //定义核心配置文件路径
        String resource = "mybatis-config.xml";
        //加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
        SqlSession session = sqlSessionFactory.openSession();

        //TODO: 3.使用session获取接口的动态代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);
        //TODO: 4.使用接口类型的对象调用接口中的方法
//        List<User> list = mapper.findAllUsers();
//        for (User user : list) {
//            System.err.println(user);
//        }
//        User user = mapper.findUserById(1);
//        System.err.println(user);

        Integer count = mapper.findUserTotal();
        System.err.println(count);
        //关闭会话
        session.commit();
        session.close();

    }


}

第五章 敏捷开发

1. 工具类

package com.itheima.com.itheima.util;

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

    private static SqlSessionFactory sqlSessionFactory;
    static{
        //TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
        try {
            String resource = "mybatis-config.xml";
            //加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
    //传入true,表示自动提交事务,传入false,手动提交
    public static SqlSession openSession(boolean flag){
        SqlSession session = sqlSessionFactory.openSession(flag);
        return session;
    }
    //需要手动提交事务
    public static SqlSession openSession(){
        SqlSession session = sqlSessionFactory.openSession();
        return session;
    }
    //配套手动提交事务使用: 成功提交
    public static void commitAndClose(SqlSession session){
        session.commit();
        session.close();
    }
    //配套手动提交事务使用: 失败回滚
    public static void rollbackAndClose(SqlSession session){
        session.rollback();
        session.close();
    }
}

测试

package com.itheima.test;

import com.itheima.com.itheima.util.MyBatisUtil;
import com.itheima.dao.UserMapper;
import com.itheima.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;

/*
    TODO 事务
    1. 事务操作
        1. 开启事务
        2. 增删改 操作
        3. 成功提交 或 失败回滚
    2. 注意: 如果事务开之后, 进行操作 , 不提交数据是不会保存到数据库

 */
public class TestDemo03 {

    @Test
    public void add() throws IOException {
        //TODO: 1.从xml文件中构建SqlSessionFactory (读取 mybatis-config.xml 核心配置文件 并解析: 类似于dom4j)
        //定义核心配置文件路径
        String resource = "mybatis-config.xml";
        //加载核心配置文件获取输入流(从类路径下加载指定文件名: resources目录 )
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //TODO: 2.从SqlSessionFactory中获取session (理解成Connection: java程序和数据库之间的链接)
            //手动操作事务 开启事务
        SqlSession session = sqlSessionFactory.openSession();
            //自动操作事务: 默认自动提交
//        SqlSession session = sqlSessionFactory.openSession(true);

        //TODO: 3.使用session获取接口的动态代理对象
        UserMapper mapper = session.getMapper(UserMapper.class);
        //TODO: 4.使用接口类型的对象调用接口中的方法
        User user = new User();
        user.setUsername("张三");
        user.setBirthday("1998-01-01");
        user.setAddress("杭州");
        user.setSex("女");

        mapper.addUser(user);
        //5. 关闭会话: 提交会回滚,最后释放连接
        session.commit(); // 成功提交
//        session.rollback(); // 失败回滚
        session.close();

    }

    @Test
    public void method01(){
        //获取自动提交事务的连接会话
        SqlSession session = MyBatisUtil.openSession(true);
        //操作
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("张三");
        user.setBirthday("1998-01-01");
        user.setAddress("杭州");
        user.setSex("女");
        mapper.addUser(user);
        //用完释放
        session.close();
    }

    @Test
    public void method02(){
    //获取需要手动提交事务的连接会话
//        SqlSession session = MyBatisUtil.openSession(false);
        SqlSession session = MyBatisUtil.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();
        user.setUsername("张三");
        user.setBirthday("1998-01-01");
        user.setAddress("杭州");
        user.setSex("女");
        mapper.addUser(user);
//        session.commit();
//        session.close();
        MyBatisUtil.commitAndClose(session);
    }
}

2. 模板

1648544753748.png

1648544898587.png

<?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="jdbc.properties"/>

    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <!--
        扫描pojo所在的包: 起别名
    -->
    <typeAliases>
        <package name="com.itheima.pojo"/>
    </typeAliases>
    <environments default="development">
        <!--通常我们只需要配置一个就可以了, id是环境的名字 -->
        <environment id="development">
            <!--事务管理器:由JDBC来管理-->
            <transactionManager type="JDBC"/>
            <!--数据源的配置:mybatis自带的连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!--
        扫描接口所在的包
            1. sql映射文件名必须和接口一致
            2. 路径必须一致
    -->
    <mappers>
        <package name="com.itheima.dao"/>
    </mappers>

</configuration>

第六章 mybatis单表查询

1. 结果集映射

public class User {
    private Integer id;
    //TODO 发现,类中的属性名mingzi 跟 表中字段名username 不一致
    private String mingzi;
    private String birthday;
    private String sex;
    private String address;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", mingzi='" + mingzi + '\'' +
                ", birthday='" + birthday + '\'' +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

    public Integer getId() {
        return id;
    }

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

    public String getMingzi() {
        return mingzi;
    }

    public void setMingzi(String mingzi) {
        this.mingzi = mingzi;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }
}
public interface UserMapper {

    List<User> findAllUsers();
}
<?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.itheima.query.dao.UserMapper">

    <!--
        TODO: 结果集映射
        1. 自动映射
            1). 只要类的属性名和表的字段名一致, mybatis会自动加你个结果集的每一行映射一个对象
            2). resultType属性 : user
        2.手动映射
            1). 类的属性名和结果集的字段名不一致, 需要手动映射
            2). resultMap标签 (结果集映射)
                I. 属性
                    a. id 此标签的标识
                    b. type 此映射结果的类型
                II. 子标签
                    id 标签 : 指定类中的属性和结果集中主键字段的映射关系
                    result标签 : 指定类中的属性和结果集中非主键字段的映射关系

                    比如user类的id属性跟结果集的id字段映射(主键)
                    比如user类的mingzi属性跟结果集的username字段映射(非主键)
               III. 简易写法
                     a. 主键映射必须要写
                     b. 非主键字段如果跟属性名一致,可以不写 autoMapping="true"
          3). 运用:
                单表查询,基本都是自动映射
                多表查询, 可能用上手动映射
    -->
 <!--   <resultMap id="userMap" type="user">
        <id property="id" column="id"/>
        <result property="mingzi" column="username"/>
        <result property="birthday" column="bt"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
    </resultMap>-->
    <resultMap id="userMap" type="user" autoMapping="true">
        <id property="id" column="id"/>
        <result property="mingzi" column="username"/>
        <result property="birthday" column="bt"/>
    </resultMap>
    <select id="findAllUsers" resultMap="userMap">
        select id,username ,birthday as bt,sex,address from user
    </select>

    <!--<select id="findAllUsers" resultType="user">
        select * from user
    </select>-->

</mapper>

2. 参数映射

public interface UserMapper {

    List<User> findAllUsers();

    //根据用户名和性别查询用户
    List<User> findUserByUsernameAndSex(@Param("xx") String username,
                                        @Param("sex")String sex);
//    List<User> findUserByUsernameAndSex(User user);
    //根据用户名查询用户
    List<User> findUserByUsername(String username);
}
<?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.itheima.query.dao.UserMapper">



    <resultMap id="userMap" type="user2" autoMapping="true">
        <id property="id" column="id"/>
        <result property="mingzi" column="username"/>
        <result property="birthday" column="bt"/>
    </resultMap>
    <select id="findAllUsers" resultMap="userMap">
        select id,username ,birthday as bt,sex,address from user
    </select>

    <!--<select id="findAllUsers" resultType="user">
        select * from user
    </select>-->

    <!--
        TODO: 参数映射
            1. 自动映射
                1). 前提: 接口方法的参数列表有且仅有一个参数
                2). 规则
                    I. 基本类型 + string
                        #{参数变量名}
                    II. pojo:
                        #{pojo对象的属性名}
            2. 手动映射
                1). 前提: 几个参数无所谓
                2). 语法:
                    @Param("xx") String username
                    mybatis知道变量 xx 对应的username参数
                     #{xx} 就会读取到 username参数
            3. 运用
                1). 一个参数就不用写 @Param
                2). 两个参数以及以上必须要写@Param
    -->
  <!--  <select id="findUserByUsernameAndSex" resultType="user">
        select * from user where username = #{username} and sex = #{sex}
    </select>-->

    <select id="findUserByUsernameAndSex" resultType="user">
        select * from user where username = #{xx} and sex = #{sex}
    </select>

    <select id="findUserByUsername" resultType="user">
        select * from user where username = #{username}
    </select>

</mapper>
package com.itheima.test;

import com.itheima.query.dao.UserMapper;
import com.itheima.query.pojo.User;
import com.itheima.query.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class TestDemo {

    @Test
    public void method01(){

        SqlSession session = MyBatisUtil.openSession(true);
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> list = mapper.findAllUsers();
        for (User user : list) {
            System.err.println(user);
        }
        session.close();
    }

    @Test
    public void method02(){

        SqlSession session = MyBatisUtil.openSession(true);
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> list = mapper.findUserByUsernameAndSex("张三", "女");
//        List<User> list = mapper.findUserByUsername("张三");

//        User param = new User();
//        param.setUsername("张三");
//        param.setSex("女");
//        List<User> list = mapper.findUserByUsernameAndSex(param);


        for (User user : list) {
            System.err.println(user);
        }
        session.close();
    }
}