【MyBatis】框架特点,ORM思想,事务管理机制

1. Mybatis概述:

1.1 基础知识:

  • SSM三大框架: Spring + SpringMVC + MyBatis

  • 框架其实就是对通用代码的封装, 提前写好一堆接口和类, 在做项目的时候直接引入这些常用的借口和类(引入框架), 基于这些现有的接口和类进行开发, 可以大大提高开发效率.

  • 框架一般是以jar包的形式存在的, jar包中有class文件以及各种配置文件等.

1.2 三层架构:

  • JDBC就是在数据访问层(持久层)来编写的

  • Mybatis在持久层, 属于持久层框架

1.3 JDBC的不足:

  • Mybatis可以理解为增强版的JDBC

  • Mybatis就是对JDBC的封装, 通过Mybatis来完成CRUD.

  • 不足:

  • sql语句不应该写死到java程序中, 如果想要修改增删查改的语句, 那么修改的程度就比较大.

  • 代码十分冗余

    扫描二维码关注公众号,回复: 14812769 查看本文章
  • 给?传值非常的繁琐.

1.4 了解ORM思想:

ORM 对象关系映射, Mybatis就是一个半自动化的ORM框架, 基本上持久层的框架都是遵循ORM思想的.

这意味着, Mybatis可以使得java对象和数据库表中的一条记录相互转变

  • O(object) Java虚拟机中的java对象

  • R(relational) 关系型数据库

  • M(mapping) 映射, 将java对象映射到数据库表中的一行记录, 或者是将数据库表中的一行记录映射成java虚拟机中的一个对象.

1.5 Mybatis框架的特点:

  1. 支持定制化sql, 存储过程, 基本映射以及高级映射

  1. 避免了几乎所有的JDBC代码中手动设置参数以及获取结果集

  1. 支持XML开发, 也支持注解式开发.(大部分都是xml方式开发)

  1. 将接口和java中的pojo类映射成数据库中的记录

  1. 体积小, 需要俩个jar包, 俩个配置文件

  1. 完全做到了sql解耦合

  1. 提供了基本映射标签

  1. 提供了高级映射标签

  1. 提供了XML标签, 支持动态SQL的编写

2. Mybatis入门程序:

准备一个数据库:
- id: 主键
- car_num: 汽车编号
- brand: 品牌
- guide_price: 厂家指导价
- produce_time: 生产日期
- car_type: 汽车类型

2.1 步骤:

  • 放到resource目录下的文件, 也相当于放到了类的根目录下.

  • 在mybatis中, 负责执行sql语句的那个对象是sqlsession(会话)

  • SqlSession <- sqlsessionFactory <- SqlSessionFactoryBuilder.builder

  • 一般情况下一个数据库对应一个SqlSessionFactory对象


1. 设置打包的方式, 打成jar包

2. 引入依赖
    - Mybatis依赖
    - Mysql驱动依赖

3. 编写mybatis核心配置文件  mybatis-config.xml(不是必须这个名字, 一般放到resource中)
    - CV配置文件的信息, 并且把连接数据库的信息修改一下就行
    - 在mybatis中, 负责执行sql语句的那个对象是sqlsession
    - sqlsession是专门用来执行sql语句的, 是一个java程序和数据库之间的一次会话
    - 想要获取sqlsession对象需要先得到SqlSessionFactory对象, 通过SqlSessionFactory工厂来生产sqlsession对象, 获取SqlSessionFactory对象需要先获取SqlSessionFactoryBuilder.builer方法
    - SqlSession <- sqlsessionFactory <- SqlSessionFactoryBuilder.builder
    - 一般情况下一个数据库对应一个SqlSessionFactory对象

4. 编写XxxMapper.xml文件
    - 在这个配置文件中编写sql语句
    - <insert id="ajkbfa"> </insert> 这里的id是这条sql语句的唯一标识

5. 在mytbatis-config.xml文件中指定XxxMapper.xml文件的路径
    - <mapper resource="CarMapper.xml"/>
    - resource属性会自动从类的根路径下开始查找资源

6. 编写mybatis程序, 使用mybatis的类库, 编写mybatis程序, 连接数据库做CRUD即可

7. 从XML中构建SqlSessionFactory对象
    - 在Mybatis中一定有一个重要的对象, 这个对象是: SqlSessionFactory对象

8. mybatis中有俩个主要的配置文件
    - mybatis-config.xml, 这就是核心配置文件, 主要配置连接数据库的信息等 (只有一个)
    - XxxxMapper.xml, 这个文件是专门用来编写sql语句的配置文件 (一个表一个XxxMapper.xml)

2.2 代码:

public static void main(String[] args) {
    // 获取SqlSessionFactoryBuilder对象
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    
    // 获取SqlSessionFactory对象
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    // 一般情况下, 一个数据库对应一个SqlSessionFactory对象
    sqlSessionFactory sqlsessionfactory = sqlSessionFactoryBuilder.build(is);
    
    // 获取SqlSession对象
    SqlSession session = sqlsessionfactory.openSession();
    
    // 执行sql语句
    int count = session.insert("insertCar"); // 返回值是影响数据库当中的记录条数
    System.out.println(count);
    
    session.commit();        // 手动提交
    session.close();
}

2.3 注意细节:

1. mybatis中sql语句的结尾 ; 可以省略掉

2. InputStream is = Resources.getResourceAsStream(), 获取输入流.
    优点: 采用这种方式, 从类路径加载资源, 项目的移植性很高, 项目从windows移植到linux, 代码不需要修改, 因为这个资源文件一直都在类路径当中.
    这个代码底层的源代码就是 
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream();

3. InputStream is = new FileInputStream("d:\\mybatis-config.xml");
    缺点: 代码移植性差, 程序不够健壮, 移植到其他操作系统上导致以上路径无效, 还需要修改java代码中的路径, 这样就违背了OCP原则.

4. InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream();
    ClassLoader.getSystemClassLoader() 获取系统的类加载器
    系统类加载器有一个方法叫做: getResourceAsStream(这个方法就是从类路径当中加载资源的)

5. mybatis核心配置文件存放的路径也不一定是在类的根路径下, 可以放到其他位置, 但是为了项目的移植性,健壮性, 最好将这个配置文件放到类路径下面.

6. CarMapper.xml文件的路径是固定的吗? 不是固定的.
    <mapper resource="CarMapper.xml"/> resource属性: 这种方式是从类的根路径下查找资源

3. 事务管理机制:

  • 在mybatis-config.xml核心文件中, 可以通过以下路径的配置进行mybatis的事务管理

  • type的属性只有俩个(JDBC/MANAGED), 并且不区分大小写

3.1 JDBC事务管理器:

1. mybatis框架自己管理事务, 自己采用原生的JDBC代码去管理事务
    conn.setAutoCommit(false); -> 开启事务
    ... 业务处理 ...
    conn.commit(); -> 手动提交事务

2. 如果你没有在JDBC代码中执行conn.setAutoCommit(fasle)的话, 默认得autoCommit是true.

3. 使用JDBC事务管理器的话, 底层创建的事务管理器对象: JdbcTransaction对象.

4. 如果写的代码是SqlSession sqlsession = SqlSessionFactory.openSession(true);表示没有开启事务, 因为这种方式不会执行conn.setAutoCommit(false);

5. 在JDBC事务中, 没有执行conn.setAutoCommit(false)那么autoCommit默认就是true, 如果autoCommit是true, 表示没有开启事务, 不需要手动提交

6. SqlSession sqlsession = sqlSessionFactory.openSession(); 如果使用的事务管理器是JDBC的话, 底层实际上调用的是conn.setAutoCommit(false)

7. SqlSession.commit(); 如果使用的是事务管理器是JDBC的话, 底层实际上还是会执行conn.commit();

3.2 MANAGED事务管理器:

1. mybatis不再负责事务的管理了

2. 事务的管理交给其他的容器来负责, 例如: Spring

3. 当前我们单纯的只有mybatis的情况下, 如果配置为MANAGED, 那么事务就是没有人管理的, 没有人管理的事务表示事务根本没有开启

4. 完整版程序:

public static void main(String[] args) {
    SqlSession sqlSession = null;
    try {
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
        // 开启会话, 底层会开启事务
        // jdbc的事务管理器底层会调用 conn.setAutoCommit(false)
        SqlSession = sqlSessionFactory.openSession();
        // 执行sql, 处理业务
        int count = sqlSession.insert("insertCar");
        System.out.println(count);
        // 执行到这里没有发生异常, 提交事务, 终止事务
        sqlSession.commit();
    } catch (Exception e) {
        // 出现异常, 则回滚
        if (sqlSession != null) {
            sqlSession.rollback();
        }
        e.printStackTrace();
    } finally {
        // 关闭会话, 释放资源
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
}

5. 封装成工具类:

public class SqlSessionUtil {
    private SqlSessionUtil() {}

    private static SqlSessionFactory sqlSessionFactory;

    // 类加载时执行
    // SqlSessionUtil工具类在进行第一次加载的时候, 解析mybatis-config.xml文件, 创建SqlSessionFactory对象
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static SqlSession openSession() {
        return sqlSessionFactory.openSession();
    }
}

public static void main(String[] args) {
    SqlSession sqlSession = SqlSessionUtil.openSession();
    int count = sqlSession.insert("insertCar");
    System.out.println(count);
    sqlSession.commit();
    sqlSession.close();
}

猜你喜欢

转载自blog.csdn.net/qq_68993495/article/details/128871433