【黑马程序员】MyBatis 快速入门


前言

跟着B站的黑马程序员学习 MyBatis 快速入门
课程传送门:黑马程序员——MyBatis 快速入门

Mybatis代码链接:https://pan.baidu.com/s/1K5BqlQwLPpum3NuuY89ccQ?pwd=6nrd
提取码:6nrd


一、MyBatis 介绍

1.什么是MyBatis

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

2.持久层

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

3.框架

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

4.JDBC 弊端

在这里插入图片描述

5.MyBatis 简化

在这里插入图片描述

二、MyBatis 快速入门

1.查询user表中所有数据

在这里插入图片描述

在这里插入图片描述
1)创建 user 表,添加数据

create database mybatis;
use mybatis;

drop table if exists tb_user;

create table tb_user(
	id int primary key auto_increment,
	username varchar(20),
	password varchar(20),
	gender char(1),
	addr varchar(30)
);

INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '男', '北京');
INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津');
INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');

2)创建模块,导入坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>mybatis-demo</artifactId>
    <version>1.0-SNAPSHOT</version>

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

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

        <!--mysql 驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.46</version>
        </dependency>

        <!--junit 单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
            <scope>test</scope>
        </dependency>


        <!-- 添加slf4j日志api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.20</version>
        </dependency>
        <!-- 添加logback-classic依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- 添加logback-core依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>

    </dependencies>


</project>

3)编写 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>

    <typeAliases>
        <package name="com.itheima.pojo"/>
    </typeAliases>
    
    <!--
    environments:配置数据库连接环境信息。可以配置多个environment,通过default属性切换不同的environment
    -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!--数据库连接信息-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>

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

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

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

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

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

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

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

    </select>-->


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


</mapper>

5)编码
5-1. 定义 POJO 类

package com.itheima.pojo;


// alt + 鼠标左键 整列编辑
public class User {

    private Integer id;
    private String username;
    private String password;
    private String gender;
    private String addr;

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", gender='" + gender + '\'' +
                ", addr='" + addr + '\'' +
                '}';
    }
}

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

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

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

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

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

//4. 执行方法
List<Brand> brands = brandMapper.selectAll();
System.out.println(brands);

5-4. 释放资源

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

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

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

在这里插入图片描述

三、Mapper 代理开发

1.目的

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

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

在这里插入图片描述
1.定义与 SQL 映射文件同名的 Mapper 接口,并且将 Mapper 接口和 SQL 映射文件放置在同一目录下

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

在这里插入图片描述
2.设置 SQL 映射文件的 namespace 属性为 Mapper 接口全限定名

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

在这里插入图片描述
4.编码

  • 通过 SqlSession 的 getMapper 方式获取 Mapper 接口的代理对象
  • 调用对应方法完成 sql 的执行

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

四、MyBatis 核心配置文件

在这里插入图片描述

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

1.类型别名(typeAliasess)

在这里插入图片描述

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

在这里插入图片描述

五、配置文件完成增删改查

1.准备环境

1)数据库表 tb_brand

-- 删除tb_brand表
drop table if exists tb_brand;
-- 创建tb_brand表
create table tb_brand
(
    -- id 主键
    id           int primary key auto_increment,
    -- 品牌名称
    brand_name   varchar(20),
    -- 企业名称
    company_name varchar(20),
    -- 排序字段
    ordered      int,
    -- 描述信息
    description  varchar(100),
    -- 状态:0:禁用  1:启用
    status       int
);
-- 添加数据
insert into tb_brand (brand_name, company_name, ordered, description, status)
values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
       ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
       ('小米', '小米科技有限公司', 50, 'are you ok', 1);

SELECT * FROM tb_brand;

2)实体类 Brand

package com.itheima.pojo;

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

public class Brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用  1:启用
    private Integer status;


    public Integer getId() {
        return id;
    }

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

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public Integer getOrdered() {
        return ordered;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}

3)测试用例

在这里插入图片描述

4)安装MyBatiisX 插件

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

2.查询

1)查询所有数据

在这里插入图片描述

属性名与列名不一致

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

<!-- * 起别名:对不一样的列名起别名,让别名和实体类的属性名一样
   * 缺点:每次查询都要定义一次别名
* sql片段
   * 缺点:不灵活
-->

<!-- sql片段 -->
    <sql id="brand_column">
         id, brand_name as brandName, company_name as companyName, ordered, description, status
     </sql>

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

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

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

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



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

2)查看详情

在这里插入图片描述

使用细节

在这里插入图片描述

3)条件查询

1.多条件查询

在这里插入图片描述
SQL 语句设置多个参数的三种方式
1)散装参数:需要使用 @Param (" SQL 中的参数占位符名称")

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

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

List<Brand> selectByCondition(Brand brand);

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

List<Brand> selectByConditionSingle(Brand brand);

测试代码:

	@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.多条件-动态条件查询

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

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

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

    </select>
3.单条件-动态条件查询

在这里插入图片描述

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

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

3.添加

在这里插入图片描述

主键返回

在这里插入图片描述

<insert useGeneratedKeys="true" keyProperty="id">

4.修改

1)修改全部字段

在这里插入图片描述

2)修改动态字段

在这里插入图片描述

5.删除

1)删除一个

在这里插入图片描述

2)批量删除

在这里插入图片描述

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

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

六、参数传递

在这里插入图片描述

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

1.单个参数

  1. POJO类型:直接使用,属性名 和 参数占位符名称一致

  2. Map集合:直接使用,键名 和 参数占位符名称一致

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

    map.put("arg0",collection集合);
    map.put("collection",collection集合);
    
  4. List:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名

    map.put("arg0",list集合);
    map.put("collection",list集合);
    map.put("list",list集合);
    
  5. Array:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名

    map.put("arg0",数组);
    map.put("array",数组);
    
  6. 其他类型:直接使用

2.多个参数

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

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

七、注解完成增删改查

在这里插入图片描述


总结

以上就是本章要讲的内容,本文仅仅简单复述了老师讲课的文本内容,内容有误麻烦联系。

  • 11
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值