MyBatis学习 | 简介&HelloWord

24 篇文章 0 订阅


学习地址🔗

一、简介

💬概述:MyBatis是一个半自动、轻量级的持久化层(ORM)框架,原是Apache的一个开源项目iBatis,后面该项目迁移到Google,iBatis(3.0之后的版本)也改名为MyBatis

❓ 关于MyBatis的介绍解释

  • 半自动:MyBatis框架需要开发人员在xml文件或注解中手动创建SQL语句(或通过插件生成),才能将SQL执行结果与对应的JavaBean建立映射关系,然后通过JavaBean获取结果集(而全自动只需根据对应的JavaBean就能获取到SQL的执行结果集)
  • 轻量级:MyBatis需要配置的依赖(jar包)较少,也不需要额外添加其他依赖,整体体积也较小,可以独立使用
  • 持久化层框架:持久化简单理解就是将数据永久地存储到数据库中
  • ORM框架:ORM是指Object Relational Mapping,即对象关系映射,ORM框架会根据xml映射文件(元数据)将JavaBean与数据库中对应的表建立映射关系,从而将对象持久化到数据库中

🔑优点(参考博文:MyBatis面试题(2020最新版)mybatis-execution

  1. 基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在xml映射文件里,解除SQL与Java代码的耦合,便于统一管理
  2. 提供xml标签,支持编写动态SQL语句,并可重用
  3. 与JDBC相比,减少了代码量,消除了大量冗余的代码,不需要手动开关连接
  4. 很好的与各种数据库兼容(MyBatis底层使用JDBC来连接数据库,只要JDBC支持的数据库MyBatis都支持)
  5. 提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护
  6. 能够与Spring很好的集成

🔑其他与数据库交互的技术

  • 工具类

    • 常见:原生JDBC、DBUtils、Spring中的JdbcTemplate
    • 缺点
      ① SQL语句夹杂在Java代码中,耦合度高导致硬编码内伤
      ② 实际开发中SQl语句会经常需要优化修改,后期维护困难
  • 全自动ORM框架

    • 常见:Hibernate是典型的全自动ORM框架

    • 缺点(相对于MyBatis)
      ① 难以处理复杂的SQL语句
      ② SQL语句都是框架内自动生成的,开发人员无法对SQL语句进行优化或特殊化处理(HQL可以解决)
      ③ 基于全自动、全映射的特点,实现大量字段的JavaBean进行部分字段映射比较困难

      💡 全映射是指查询表记录时,只能把查询出全部字段,不能查询部分字段


二、HelloWord

2.1 环境搭建

① 在idea中创建普通的maven工程,然后在maven工程的pom.xml文件中添加插件标签,设置工程编译打包时的资源文件,该操作必须设置,如果不设置,会因为maven的资源过滤而找不到对应的映射文件

<build>
    <!-- maven的资源过滤 -->
    <resources>
        <resource>
            <!-- 工程进行编译打包时把src/main/java目录下的properties文件和xml文件也打包进去 -->
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>

❓ 关于maven工程的编译打包文件

  • 在maven工程进行编译打包时,默认会把src/main/resource目录下的所有文件(包括.properties和.xml文件)拷贝到target/classes目录下
  • 而对于src/main/java目录下的文件,maven工程在编译打包时只会把.java文件拷贝到target/classes目录下,不会处理其他文件(maven的资源过滤)

❓ 关于<resource>标签中三个子标签(参考博文:Maven的pom.xml中resources标签的用法

  1. <directory>:指定需要进行文件打包的目录,一般指定为src/main/java、src/main/resource
  2. <includes>:指定需要进行打包的文件。在<includes>中使用<include>子标签指定打包的文件,可以指定多种不同类型的文件
  3. <filtering>:指定在打包(拷贝)文件前是否需要对文件进行预编译(比如将.java文件编译成.class文件后再进行拷贝),默认值是false,即不进行预编译

② 导入相关jar包:mybatis.jar(MyBatis依赖)、mysql-connector-java.jar(MySQL连接驱动)、junit.jar(测试依赖)

③ 在src/main/java目录下创建包com.key.mybatis,再在mybatis包下创建dao、utils、entity三个包,分别用于存放持久层接口及其对应的映射文件、工具类、实体类,在src/test/java下同样建立com.key.mybatis

2.2 创建全局配置文件

在src/main/resource目录下创建一个mybatis-config.xml文件,然后将官方文档中关于MyBatis的全局配置文件内容复制过来

<?xml version="1.0" encoding="utf8" ?>
<!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="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    
    <!-- 注册映射文件 -->
    <mappers>
        <mapper resource="org/mybatis/example/BlogMapper.xml"/>
    </mappers>
</configuration>

2.3 创建工具类

在utils包下创建一个工具类MyBatisUtil,类中使用静态代码块获取SqlSessionFactory工厂对象,并创建方法,方法中通过工厂对象获取SqlSession会话对象

public class MyBatisUtil {
    private static SqlSessionFactory sqlSessionFactory;

    /* 静态代码块中获取SqlSessionFactory对象 */
    static {
        // 先初始化输入流
        InputStream in = null;

        try {
            // 1. 获取全局配置文件的资源路径
            String resource = "mybatis-config.xml";

            // 2. 根据全局配置文件的路径获取对应输入流
            in = Resources.getResourceAsStream(resource);

            // 3. 根据输入流获取SqlSessionFactory对象
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 4. 关闭输入流
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 根据SqlSessionFactory获取SqlSession对象
     */
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

2.4 创建数据库表和对应的JavaBean

🔑创建数据库表——用户表

use `mybatis`;

/* 创建用户表 */
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
	`id` INT UNSIGNED NOT NULL PRIMARY KEY UNIQUE AUTO_INCREMENT COMMENT '主键id',
	`user_name` VARCHAR(20) NOT NULL COMMENT '用户名',
	`password` VARCHAR(20) NOT NULL UNIQUE COMMENT '密码' 
) ENGINE = INNODB DEFAULT CHARSET = utf8 COMMENT '用户表';

/* 插入几条数据 */
INSERT INTO `user`(`user_name`, `password`)
VALUES('周星驰', '12345');
INSERT INTO `user`(`user_name`, `password`)
VALUES('周慧敏', '12444');
INSERT INTO `user`(`user_name`, `password`)
VALUES('周润发', 'abcde');
INSERT INTO `user`(`user_name`, `password`)
VALUES('周华健', 'yyds');

🔑创建数据库表对应的JavaBean

public class User {
    private Integer id;
    private String username;
    private String password;

    public User() {
    }

    public User(Integer id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    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;
    }

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

2.5 创建SQL映射文件

在src/main/java目录下的dao中创建一个UserMapper.xml文件,作为User类对应的SQL映射文件,然后将官方文档中的相关内容复制过去

<?xml version="1.0" encoding="utf8" ?>
<!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
    
    <!--
        SQL标签编写
    -->

    <select id="selectBlog" resultType="Blog">
        select * from Blog where id = #{id}
    </select>
</mapper>

2.6 非接口式与接口式编程

2.6.1 非接口式编程

① 在SQL映射文件UserMapper.xml中创建SQL语句,并修改相关参数

需要修改的参数修改后的值解释
根标签<mapper>中的名称空间namespace属性值com.key.mybatis.dao.UserDao非接口式编程中该属性可设置任意值,但建议写成全类名的形式
<select>标签的id属性值selectUser非接口式编程中该属性可设置任意值
<select>标签的resultType属性值com.key.mybatis.entity.User设置结果集的类型
<select>标签中的SQL语句select id ‘id’, user_name ‘username’, password ‘password’ from user where id = #{id}SQL语句编写,其中#{id}相当于一个占位符,用于获取传递过来的id值
<mapper namespace="com.key.mybatis.dao.UserDao">

    <!--
        SQL标签编写
    -->

    <!-- HelloWord测试SQL1.0,非接口式 -->
    <select id="selectUser" resultType="com.key.mybatis.entity.User">
        select `id` 'id', `user_name` 'username', `password` 'password'
        from `user`
        where `id` = #{id}
    </select>
</mapper>

❓ 为什么SELECT语句中要给每一个字段取别名:因为user表中的user_name字段与User类中的成员变量username名称不一致,MyBatis无法为它们两个建立映射关系,也就无法将查询记录中user_name的值赋值给username,因此需要给每一个字段分别取一个与对应成员变量名一样的别名;如果不给每一个字段取别名,而是直接使用*简单代表所有字段,查询出来的User对象中username属性值为null

② 在全局配置文件中,修改数据源<dataSource>的四个属性,通过<mapper>标签注册SQL映射文件UserMapper.xml

<mappers>
    <mapper resource="com/key/mybatis/dao/UserMapper.xml"/>
</mappers>

③ 在src/test/java目录下的mybatis包下创建测试类HelloWordTest,测试类中添加测试方法testMtBatis01(),方法中进行以下步骤

3.1 先通过MyBatis工具类获取SqlSession会话对象

3.2 然后调用SqlSession对象的selectOne()方法,并返回一个结果集对象(User对象),selectOne()方法中需要设置两个参数,分别对应映射文件中<select>标签的id属性值、SQL语句中的id值(即#{id}需要获取的值)

❓ 关于selectOne()方法的两个参数

  • 参数1 --> 对应映射文件中<select>标签的id属性值(SQL语句的唯一标识),与映射文件进行绑定,因为有可能在不同的SQL映射文件中存在相同的id属性值,所以在selectOne()中只写上id的值可能会引起歧义,因此建议在id值前加上名称空间namespace的值(映射文件的唯一标识)
  • 参数2 --> 对应SQL语句中的id值,这里的id是指数据库表中的id字段(主键)。该参数的作用相当于JDBC中的填充占位符(设置参数),而对应的占位符就是SQL语句中的#{id}

3.3 打印结果集对象

3.4 最后调用close()方法关闭SqlSession对象

@Test
public void testMyBatis01() {
    // 1. 从MyBatis工具类中获取SqlSession对象
    SqlSession sqlSession = MyBatisUtil.getSqlSession();

    // 2. 根据sqlSession对象执行映射文件中对应的SQL语句,并获取结果集对象
    User user =  sqlSession.selectOne(
        "com.key.mybatis.dao.UserDao.selectUser",
        1);

    // 3. 打印获取到的结果集对象
    System.out.println(user);

    // 4. 关闭sqlSession对象
    sqlSession.close();
}

④ 测试结果test-helloword01

2.6.2 接口式编程⭐

① 创建SQL映射文件对应的持久层接口UserDao,接口中添加操作数据库的方法

public interface UserDao {

    /**
     * 查询所有用户信息
     * @return 返回用户集合
     */
    List<User> getAllUsers();
}

② 在SQL映射文件UserMapper.xml中创建SQL语句,并修改相关参数

需要修改的参数修改后的值解释
根标签<mapper>中的名称空间namespace属性值com.key.mybatis.dao.UserDao设置与映射文件对应的持久层接口的全类名,将接口与SQL映射文件进行绑定
<select>标签的id属性值getAllUsers设置与SQL语句对应的持久层接口中的方法名,将接口方法与SQL语句进行绑定
<select>标签的resultType属性值com.key.mybatis.entity.User设置结果集的类型
<select>标签中的SQL语句select id ‘id’, user_name ‘username’, password ‘password’ from userSQL语句编写
<mapper namespace="com.key.mybatis.dao.UserDao">

    <!--
        SQL标签编写
    -->

    <!-- HelloWord测试SQL2.0,接口式 -->
    <select id="getAllUsers" resultType="com.key.mybatis.entity.User">
        select `id` 'id', `user_name` 'username', `password` 'password'
        from `user`
    </select>
</mapper>

③ 在全局配置文件中,修改数据源<dataSource>的四个属性,通过<mapper>标签注册SQL映射文件UserMapper.xml(与非接口式编程一样)

④ 在src/test/java目录下的mybatis包下创建测试类HelloWordTest,测试类中添加测试方法testMtBatis02(),方法中进行以下步骤

4.1 先通过MyBatis工具类获取SqlSession会话对象

4.2 然后调用SqlSession对象的getMapper()方法,并返回UserDao接口的一个实现类对象mapper(映射对象)

4.3 通过mapper对象调用接口中的getAllUsers()方法,并获取结果集(List集合)

4.4 打印结果集

4.5 最后调用close()方法关闭SqlSession对象

@Test
public void testMyBatis02() {
    // 1. 从工具类中获取SqlSession对象
    SqlSession sqlSession = MyBatisUtil.getSqlSession();

    // 2. 加载EmployDao接口获取接口对应映射器对象
    UserDao mapper = sqlSession.getMapper(UserDao.class);

    // 3. 通过mapper接口的方法,获取结果集对象
    List<User> users = mapper.getAllUsers();

    // 4. 打印结果
    users.forEach(System.out :: println);

    // 5. 关闭sqlSession对象
    sqlSession.close();
}

④ 测试结果test-helloword02

2.7 简单总结

🔑关于接口式编程

  • 使用原生API与MyBatis框架的区别
    • 原生API:需要为持久层接口(XxxDao)手动创建一个实现类(XxxDaoImpl)
    • MyBatis框架:无需为持久层接口创建实现类,只需将接口(XxxDao)与SQL映射文件(XxxMapper.xml)进行绑定以及将接口中的方法与映射文件中的SQL语句进行绑定
  • mapper对象(映射对象):MyBatis在将接口与SQL映射文件进行绑定时,会为该接口创建一个代理对象,该代理对象就是sqlSession.getMapper(XxxDao.class)方法返回的mapper对象(类型是还是XxxDao),通过该代理对象就可以调用接口中的方法(具体怎么创建后续会分析源码解释)

🔑关于SqlSession对象

  • SqlSession对象代表持久层与数据库进行的一次会话,类似于IO流对象,用完要及时关闭(释放资源),不然可能会引起内存泄漏、性能降低等问题
  • SqlSession对象底层中使用的还是Connection数据库连接对象,因此它与Connection对象一样都是非线程安全的,不能被共享(不能设置为全局变量),每次使用应该取获取新的对象

🔑两个重要的xml配置文件

① MyBatis全局配置文件:用于设置数据库连接池、数据源信息、事务管理以及注册映射文件等

💡 MyBatis全局配置可以不使用xml文件实现,可以直接创建配置类,类中设置各个属性,但比较麻烦

② SQL映射文件:是必须要有的文件,文件中创建并保存SQL语句以及设置每一个SQL语句的映射信息,将SQL语句抽取出来,与Java代码分隔开,既降低了代码的耦合度,也方便开发人员对SQL语句进行特殊处理和优化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值