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程序中, 如果想要修改增删查改的语句, 那么修改的程度就比较大.
- 代码十分冗余
- 给?传值非常的繁琐.
1.4 了解ORM思想:
ORM 对象关系映射, Mybatis就是一个半自动化的ORM框架, 基本上持久层的框架都是遵循ORM思想的.
这意味着, Mybatis可以使得java对象和数据库表中的一条记录相互转变
- O(object) Java虚拟机中的java对象
- R(relational) 关系型数据库
- M(mapping) 映射, 将java对象映射到数据库表中的一行记录, 或者是将数据库表中的一行记录映射成java虚拟机中的一个对象.
1.5 Mybatis框架的特点:
- 支持定制化sql, 存储过程, 基本映射以及高级映射
- 避免了几乎所有的JDBC代码中手动设置参数以及获取结果集
- 支持XML开发, 也支持注解式开发.(大部分都是xml方式开发)
- 将接口和java中的pojo类映射成数据库中的记录
- 体积小, 需要俩个jar包, 俩个配置文件
- 完全做到了sql解耦合
- 提供了基本映射标签
- 提供了高级映射标签
- 提供了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(); }