SSM三大框架: Spring + SpringMVC + MyBatis
框架其实就是对通用代码的封装, 提前写好一堆接口和类, 在做项目的时候直接引入这些常用的借口和类(引入框架), 基于这些现有的接口和类进行开发, 可以大大提高开发效率.
框架一般是以jar包的形式存在的, jar包中有class文件以及各种配置文件等.
JDBC就是在数据访问层(持久层)来编写的
Mybatis在持久层, 属于持久层框架
Mybatis可以理解为增强版的JDBC
Mybatis就是对JDBC的封装, 通过Mybatis来完成CRUD.
不足:
sql语句不应该写死到java程序中, 如果想要修改增删查改的语句, 那么修改的程度就比较大.
代码十分冗余
给?传值非常的繁琐.
ORM 对象关系映射, Mybatis就是一个半自动化的ORM框架, 基本上持久层的框架都是遵循ORM思想的.
这意味着, Mybatis可以使得java对象和数据库表中的一条记录相互转变
O(object) Java虚拟机中的java对象
R(relational) 关系型数据库
M(mapping) 映射, 将java对象映射到数据库表中的一行记录, 或者是将数据库表中的一行记录映射成java虚拟机中的一个对象.
支持定制化sql, 存储过程, 基本映射以及高级映射
避免了几乎所有的JDBC代码中手动设置参数以及获取结果集
支持XML开发, 也支持注解式开发.(大部分都是xml方式开发)
将接口和java中的pojo类映射成数据库中的记录
体积小, 需要俩个jar包, 俩个配置文件
完全做到了sql解耦合
提供了基本映射标签
提供了高级映射标签
提供了XML标签, 支持动态SQL的编写
准备一个数据库:
- id: 主键
- car_num: 汽车编号
- brand: 品牌
- guide_price: 厂家指导价
- produce_time: 生产日期
- car_type: 汽车类型
放到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语句
- 这里的id是这条sql语句的唯一标识
5. 在mytbatis-config.xml文件中指定XxxMapper.xml文件的路径
-
- resource属性会自动从类的根路径下开始查找资源
6. 编写mybatis程序, 使用mybatis的类库, 编写mybatis程序, 连接数据库做CRUD即可
7. 从XML中构建SqlSessionFactory对象
- 在Mybatis中一定有一个重要的对象, 这个对象是: SqlSessionFactory对象
8. mybatis中有俩个主要的配置文件
- mybatis-config.xml, 这就是核心配置文件, 主要配置连接数据库的信息等 (只有一个)
- XxxxMapper.xml, 这个文件是专门用来编写sql语句的配置文件 (一个表一个XxxMapper.xml)
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();
}
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文件的路径是固定的吗? 不是固定的.
resource属性: 这种方式是从类的根路径下查找资源
在mybatis-config.xml核心文件中, 可以通过以下路径的配置进行mybatis的事务管理
type的属性只有俩个(JDBC/MANAGED), 并且不区分大小写
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();
1. mybatis不再负责事务的管理了
2. 事务的管理交给其他的容器来负责, 例如: Spring
3. 当前我们单纯的只有mybatis的情况下, 如果配置为MANAGED, 那么事务就是没有人管理的, 没有人管理的事务表示事务根本没有开启
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();
}
}
}
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();
}