MyBatis学习记录


我亦无他,唯手熟尔。
时间:2023年5月2日12:41:27
新手入门,如有错误及疑问,欢迎指出。

MyBatis图表

MyBatis介绍

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

持久层

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

框架

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

JDBC缺点

JDBC缺点

MyBatis简化

MyBatis简化

MyBatis快速入门之查询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', '男', '西安');

user表

2、创建模块,导入坐标

在这里插入图片描述

<!--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>
<!--logback.xml 放在resources文件夹下-->
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--
        CONSOLE :表示当前的日志信息是可以输出到控制台的。
    -->
    <appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%level] %blue(%d{HH:mm:ss.SSS}) %cyan([%thread]) %boldGreen(%logger{15}) - %msg %n</pattern>
        </encoder>
    </appender>

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

3、编写MyBatis核心配置文件(mabatis-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>

    <typeAliases>
        <package name="com.wly.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://localhost:3306/mybatis?useSSL=false"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--加载sql映射文件-->
        <!--<mapper resource="com/wly/mapper/UserMapper.xml"/>-->
        <!--Mapper代理方式-->
        <package name="com.wly.mapper"/>
    </mappers>

</configuration>

4、编写SQL映射文件 --> 同一管理sql语句,解决硬编码问题

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">
<!--
    namespace:名称空间
-->
<mapper namespace="test">
    <select id="selectAll" resultType="com.wly.pojo.User">
        select * from tb_user;
    </select>
    <select id="selectById" resultType="user">
        select * from tb_user where id = #{id};
    </select>
</mapper>
public interface UserMapper {
    List<User> selectAll();
    User selectById(int id);
}

5、编码

  • 定义POJO类
  • 加载核心配置文件,获取AqlSessionFactory对象
  • 获取SqlSession对象,执行SQL
  • 释放资源

GPT:
在Maven工程中,POJO是指"Plain Old Java Object",翻译成中文即为“普通的Java对象”。POJO是一种轻量级的Java对象,没有任何限制或者必须继承某个复杂框架或实现某个接口,其本质上就是一个普通的Java类,仅仅是提供对类的属性访问方法(getters/setters方法)和默认构造函数的实现。POJO类通常用来表示业务实体,在Maven工程中,POJO作为数据对象被应用于各种业务场景中,例如存储数据、传递数据等。
POJO简单易懂、易于维护,也更加灵活,同时也避免了强依赖于一个特定的框架。

SqlSessionFactory 是 MyBatis 框架的核心接口之一,它负责启动 MyBatis 应用程序中的数据库连接和事务管理。
MyBatis 的 SqlSessionFactory 是一个建议的线程安全对象,它是数据访问层中最重要的一个类。SqlSessionFactory 负责创建 SqlSession 对象,并对数据库进行配置和管理,由于 SqlSession 产生的成本比较高,因此 SqlSessionFactory 的实例通常被应用程序缓存起来,以便反复使用。
SqlSessionFactory 接口的实现类 SqlSessionFactoryImpl 提供了一个静态方法 build()。该方法用于从 MyBatis 配置文件中构建 SqlSessionFactory 实例。具体而言,MyBatis 会读取核心配置文件 mybatis-config.xml,在其中配置 SqlSessionFactory 和其他配置信息。在使用 MyBatis 框架时,我们需要通过上述 build() 方法获取 SqlSessionFactory 实例并调用它的 openSession() 方法获取 SqlSession 实例,然后使用 SqlSession 对象进行数据库操作。

public class MyBatisDemo {
    public static void main(String[] args) throws IOException {
        //1.加载mybatis的核心配置文件,获取SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //2.获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //3.执行sql
        List<User> users = sqlSession.selectList("test.selectAll");
        System.out.println(users);
        //4. 释放资源
        sqlSession.close();
    }
}
使用Mapper代理方式完成

1、定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放在同一目录下
2、设置SQL映射文件的namespace属性为Mapper接口全限定名
3、在Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一直
4、编码
1、通过SqlSession的getMapper方法获取Mapper接口的代理对象
2、通过调用方法完成sql的执行
代理目录

细节: 如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载
细节

// 获取UserMapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectAll();

MyBatis核心配置文件概述

environments标签

数据库环境的配置,支持多环境配置
环境标签
其中,事务管理器(transactionManager)类型有两种:

  • JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
  • MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false来阻止它默认的关闭行为。

其中,数据源(dataSource)类型有三种:

  • UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。
  • POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
  • JNDI:这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI上下文的引用。

mapper标签

该标签的作用是加载映射的,加载方式有如下几种:
使用相对于类路径的资源引用,例如:
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
使用完全限定资源定位符(URL),例如:
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
使用映射器接口实现类的完全限定类名,例如:
<mapper class="org.mybatis.builder.AuthorMapper"/>
将包内的映射器接口实现全部注册为映射器,例如:
<package name="org.mybatis.builder"/>

Properties标签

实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件

typeAliases标签


mybatis框架已经为我们设置好的一些常用的类型的别名
常用类别名
常用配置

MyBatis相应API

SqlSession工厂构建器SqlSessionFactoryBuilder

常用API:SqlSessionFactory build(InputStream inputStream)
通过加载mybatis的核心文件的输入流的形式构建一个SqlSessionFactory对象

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

其中, Resources 工具类,这个类在 org.apache.ibatis.io 包中。Resources 类帮助你从类路径下、文件系统或一个 web URL 中加载资源文件。

SqlSession工厂对象SqlSessionFactory

SqlSessionFactory 有多个个方法创建 SqlSession 实例。常用的有如下两个:
sqlsession

SqlSession会话对象

SqlSession 实例在 MyBatis 中是非常强大的一个类。在这里你会看到所有执行语句、提交或回滚事务和获取映射器实例的方法。
执行语句的方法主要有:

<T> T selectOne(String statement, Object parameter) 
<E> List<E> selectList(String statement, Object parameter) 
int insert(String statement, Object parameter) 
int update(String statement, Object parameter) 
int delete(String statement, Object parameter)

操作事务的方法主要有:

void commit()  
void rollback() 

MyBatisX 插件

MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。
主要功能:

  • XML 和 接口方法 相互跳转
  • 根据接口方法生成 statement

安装:
mybatis插件

实践案例-查询所有数据

-- 删除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;

1、编写接口方法

  • 参数:无
  • 结果:List
/**
* 查询所有
*/
List<Brand> selectAll();

2、编写SQL语句:SQL映射文件

<select id="selectAll" resultType="Brand">
    select *
    from tb_brand;
</select>

3、执行方法,测试

实体类属性名 和 数据库表列名 不一致,不能自动封装数据

  1. 起别名:在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样可以定义 片段,提升复用性
  2. resultMap:定义<resultMap> 完成不一致的属性名和列名的映射
<select id="selectAll" resultType="Brand">
     select id, brand_name as brandName, company_name as companyName, ordered, description, status
     from tb_brand;
</select>
<?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.wly.mapper.BrandMapper">
    <!--
    数据库表的字段名称和实体类的属性名称不一样
    则不能自动封装数据。
    方式1:起别名,对不一样的列名起别名,让别名和实体类的属性名一样.缺点:每次查询都要定义一次别名
    方式2:resultMap
            1、定义<resultMap>标签
            2、在<select>标签中,使用resultMap属性替换resultType属性
    -->

    <!--
        id:唯一标识
        type:映射的类型,支持别名
    -->
    <resultMap id="brandResultMap" type="brand">
        <!--
            id:完成主键字段的映射
            result:完成一般字段的映射
        -->
        <result column="brand_name" property="brandName"/>
        <result column="company_name" property="companyName"/>
    </resultMap>

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

    <!--方式1:起别名-->
    <!--<select id="selectAll" resultType="Brand">
        select id, brand_name as brandName, company_name as companyName, ordered, description, status
        from tb_brand;
    </select>-->

    <!--使用sql片段替代上述过长字符串-->
    <!--sql片段 缺点:不灵活-->
    <!--<sql id="brand_column">
        id, brand_name as brandName, company_name as companyName, ordered, description, status
    </sql>
    <select id="selectAll_1" resultType="Brand">
        select
            <include refid="brand_column"/>
        from tb_brand;
    </select>-->

    <!--不起别名的话,由于名字不一样会有缺失值-->
    <!--<select id="selectAll" resultType="Brand">
        select *
        from tb_brand;
    </select>-->

    <select id="selectById" resultMap="brandResultMap">
        select *
        from tb_brand where id = #{id}
    </select>

    <!--
        条件查询
    -->
    <select id="selectByCondition" resultMap="brandResultMap">
        select *
        from tb_brand
        where
            status = #{status}
            and company_name like #{companyName}
            and brand_name like #{brandName}
    </select>
</mapper>

实践案例-查看详情

查看详情
1、编写接口方法:Mapper接口

  • 参数:id
  • 结果:Brand
/**
 * 查看详情:根据Id查询
 */
Brand selectById(int id);

2、编写SQL语句:SQL映射文件

<select id="selectById" resultMap="brandResultMap">
    select *
    from tb_brand where id = #{id}
</select>

3、执行方法,测试

@Test
public void testSelectById() throws IOException {
    //接收参数
    int id = 2;

    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
    Brand brand = brandMapper.selectById(id);
    System.out.println(brand);
    sqlSession.close();
}

总结:

  • 参数占位符:
    1)#{}:执行SQL时,会将#{}占位符替换为?,将来自动设置参数值
    2)${}:拼SQL。会存在SQL注入问题
    3)使用时机:
    参数传递,都使用#{}
    如果要对表名、列名进行动态设置,只能使用${}进行sql拼接。
  • parameterType
    • 用于设置参数类型,该参数可以省略
  • SQL 语句中特殊字符处理:
  • 转义字符
  • <![CDATA[ 内容 ]]>:CD提示

实践案例-多条件查询

1、编写接口方法:Mapper接口

  • 参数:所有查询条件
  • 结果:List
List<Brand> selectByCondition(@Param("status")int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
List<Brand> selectByCondition(Brand brand);
List<Brand> selectByCondition(Map map);

2、编写SQL语句:SQL映射文件

<!--
    条件查询
-->
<select id="selectByCondition" resultMap="brandResultMap">
    select *
    from tb_brand
    where
        status = #{status}
        and company_name like #{companyName}
        and brand_name like #{brandName}
</select>

3、执行方法,测试

SQL语句设置多个参数有几种方式?

  1. 散装参数:如果方法中有多个参数,需要使用@Param("SQL中的参数名称")
    使用麻烦
  2. 实体类封装参数
    只需要保证SQL中的参数名 和 实体类属性名对应上,即可设置成功
  3. map集合
    只需要保证SQL中的参数名 和 map集合的键的名称对应上,即可设置成功

实践案例:多条件查询(动态条件)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

树下一朵云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值