ToB企服应用市场:ToB评测及商务社交产业平台

标题: 初始MyBatis ,详细步调运行第一个MyBatis程序,同时对应步调MyBatis底层剖 [打印本页]

作者: 滴水恩情    时间: 2024-6-13 08:53
标题: 初始MyBatis ,详细步调运行第一个MyBatis程序,同时对应步调MyBatis底层剖
1. 初始MyBatis ,详细步调运行第一个MyBatis程序,同时对应步调MyBatis底层剖析

@
目录

每博一文案
  1. 才华果然比金钱更耀眼
复制代码
2. 前沿知识

2.1 框架(framework)

Java当中常见的框架:
框架其实就是对通用代码的封装,被提前写好的一大堆接口和类(供你使用),我们可以在做项目的时候直接引入这些接口和类(引入框架),基于这些现有的接口和类举行开辟,可以大大进步开辟服从。
框架一样平常都是以jar 包的形式存在。(jar 包中有 class 文件以及各种配置文件等。)
SSM三大框架的学习顺序:MyBatis,Spring,SpringMVC 。由于 MyBatis 框架和背面两个 Spring,SpringMVC 比力的独立开来了,可以先学。
关于Spring 框架的内容,大家感爱好的可以移步至:✏️✏️✏️ Spring_ChinaRainbowSea的博客-CSDN博客
2.2 三层架构




关于持久层的框架有如下这些:
更多关于三层架构的内容,大家可以移步至:✏️✏️✏️ MVC 三层架构案例详细解说_mvc三层架构-CSDN博客
2.3 分析 JDBC 的缺点

我们先观察,分析如下代码的
示例1:
  1. // ......
  2. // sql语句写死在java程序中
  3. String sql = "insert into t_user(id,idCard,username,password,birth,gender,email,city,street,zipcode,phone,grade) values(?,?,?,?,?,?,?,?,?,?,?,?)";
  4. PreparedStatement ps = conn.prepareStatement(sql);
  5. // 繁琐的赋值:思考一下,这种有规律的代码能不能通过反射机制来做自动化。
  6. ps.setString(1, "1");
  7. ps.setString(2, "123456789");
  8. ps.setString(3, "zhangsan");
  9. ps.setString(4, "123456");
  10. ps.setString(5, "1980-10-11");
  11. ps.setString(6, "男");
  12. ps.setString(7, "zhangsan@126.com");
  13. ps.setString(8, "北京");
  14. ps.setString(9, "大兴区凉水河二街");
  15. ps.setString(10, "1000000");
  16. ps.setString(11, "16398574152");
  17. ps.setString(12, "A");
  18. // 执行SQL
  19. int count = ps.executeUpdate();
  20. // ......
复制代码
示例2:
  1. // ......
  2. // sql语句写死在java程序中
  3. String sql = "select id,idCard,username,password,birth,gender,email,city,street,zipcode,phone,grade from t_user";
  4. PreparedStatement ps = conn.prepareStatement(sql);
  5. ResultSet rs = ps.executeQuery();
  6. List<User> userList = new ArrayList<>();
  7. // 思考以下循环中的所有代码是否可以使用反射进行自动化封装。
  8. while(rs.next()){
  9.     // 获取数据
  10.     String id = rs.getString("id");
  11.     String idCard = rs.getString("idCard");
  12.     String username = rs.getString("username");
  13.     String password = rs.getString("password");
  14.     String birth = rs.getString("birth");
  15.     String gender = rs.getString("gender");
  16.     String email = rs.getString("email");
  17.     String city = rs.getString("city");
  18.     String street = rs.getString("street");
  19.     String zipcode = rs.getString("zipcode");
  20.     String phone = rs.getString("phone");
  21.     String grade = rs.getString("grade");
  22.     // 创建对象
  23.     User user = new User();
  24.     // 给对象属性赋值
  25.     user.setId(id);
  26.     user.setIdCard(idCard);
  27.     user.setUsername(username);
  28.     user.setPassword(password);
  29.     user.setBirth(birth);
  30.     user.setGender(gender);
  31.     user.setEmail(email);
  32.     user.setCity(city);
  33.     user.setStreet(street);
  34.     user.setZipcode(zipcode);
  35.     user.setPhone(phone);
  36.     user.setGrade(grade);
  37.     // 添加到集合
  38.     userList.add(user);
  39. }
  40. // ......
复制代码
JDBC的不足点:
SQL语句写牢在了Java程序当中了,不灵活,改SQL的话,就要改Java代码,违反了开闭原则OCP。
给 ? 占位符传值是繁琐的,不能自动化
将效果集封装成Java对象也是比力繁琐的,不能自动化
关于这些自动化的问题,以及OCP开闭原则,运用下面我们正在学习的MyBatis 可以得到一个很好的办理方案。
关于JDBC的更多详细内容,大家可以移步至:✏️✏️✏️ JDBC_ChinaRainbowSea的博客-CSDN博客
3. 初始了解MyBatis

MyBatis 本质上就是对JDBC的封装,通过MyBatis完成CRUD。
MyBatis 在三层架构中负责持久层,属于持久层框架。
MyBatis的发展历程:这里【引用百度百科

打开MyBatis 代码可以看到它的包结构中包罗:ibatis

ORM :对象关系映射。
O (object) :Java虚拟机中的Java对象。
R(Relational):关系型数据库
M(Mapping):将Java虚拟机中的Java对象映射到数据库表中一行记录,或是将数据库表中一行记录映射成Java虚拟机中的一个Java对象。
ORM示图:


MyBatis 框架就是一个ORM框架。
MyBatis可以干啥?
java 对象 < ------ > 数据库表中的一条记录

  1. 像User 这样在图中,有特殊的称呼:
  2. 有的人把它叫做:pojo(普通Java类)
  3. 有的叫做: JavaBean (咖啡豆)
  4. 有的叫做: domain(领域模型)
复制代码
MyBatis 是一个半自动化的ORM,由于MyBatis 框架中SQL语句是必要程序员自己写的。
Hibernate 框架是一个全自动化的ORM 使用Hibenrnate 框架的时候,不必要程序员手动编写SQL语句,SQL语句可以自动生成,所以Hibernate 是一个完全的全自动化的ORM框架。
这里我们的主题是 MyBatis 。
MyBatis 框架特点:
4. MyBatis第一个入门程序

4.1 MyBatis下载



将框架以及框架的源码都下载下来,下载框架后解压,打开mybatis目录

4.2  MyBatis入门程序开辟步调

起首我们先准备好数据库信息
准备数据库表:汽车表t_car,字段包罗:
id:主键(自增)【bigint】
car_num:汽车编号【varchar】
brand:品牌【varchar】
guide_price:厂家指导价【decimal范例,专门为财务数据准备的范例】
produce_time:生产时间【char,年月日即可,10个长度,'2022-10-11'】
car_type:汽车范例(燃油车、电车、氢能源)【varchar】
  1. DROP TABLE IF EXISTS `t_car`;
  2. CREATE TABLE `t_car`  (
  3.   `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键,和业务没有关系,自增',
  4.   `car_num` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '汽车编号',
  5.   `brand` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '汽车品牌',
  6.   `guide_price` decimal(10, 2) NULL DEFAULT NULL COMMENT '厂商指导价格',
  7.   `produce_time` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '生产日期',
  8.   `car_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '汽车类型,燃油车,氢能源',
  9.   PRIMARY KEY (`id`) USING BTREE
  10. ) ENGINE = InnoDB AUTO_INCREMENT = 33 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = Dynamic;
复制代码
  1. INSERT INTO `t_car` VALUES (1, '1001', '宝马520Li', 10.00, '2020-10-11', '燃油车');
  2. INSERT INTO `t_car` VALUES (2, '1002', '奔驰E300L', 55.00, '2020-11-11', '新能源');
  3. INSERT INTO `t_car` VALUES (5, '1003', '丰田霸道', 30.00, '2000-10-11', '燃油车');
复制代码


创建Project:建议创建Empty Project,设置Java版本以及编译版本等。




创建Module:平凡的Maven Java模块
第一步:通过maven 在 pom.xml 文件当中引入相关依赖。
mybatis依赖 ,mysql依赖
  1. <dependency>
  2.   <groupId>org.mybatis</groupId>
  3.   <artifactId>mybatis</artifactId>
  4.   <version>3.5.10</version>
  5. </dependency>
  6. <dependency>
  7.   <groupId>mysql</groupId>
  8.   <artifactId>mysql-connector-java</artifactId>
  9.   <version>8.0.30</version>
  10. </dependency>
复制代码
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.     <modelVersion>4.0.0</modelVersion>
  6.     <groupId>com.ranbowsea</groupId>
  7.     <artifactId>mybatis-001-introduction</artifactId>
  8.     <version>1.0-SNAPSHOT</version>
  9.     <packaging>jar</packaging>
  10.     <properties>
  11.         <maven.compiler.source>17</maven.compiler.source>
  12.         <maven.compiler.target>17</maven.compiler.target>
  13.     </properties>
  14.     <dependencies>
  15.         
  16.         <dependency>
  17.             <groupId>org.mybatis</groupId>
  18.             <artifactId>mybatis</artifactId>
  19.             <version>3.5.10</version>
  20.         </dependency>
  21.         
  22.         
  23.         <dependency>
  24.             <groupId>mysql</groupId>
  25.             <artifactId>mysql-connector-java</artifactId>
  26.             <version>8.0.30</version>
  27.         </dependency>
  28.     </dependencies>
  29. </project>
复制代码
第二步:在 resources 根(类)目录下新建 mybatis-config.xml(文件名随意)配置文件(可以参考mybatis手册拷贝 (https://mybatis.net.cn/getting-started.html))
注意:
关于这两点的注意事项,该文章的背面,会详细说明。请继续看下去。

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3.         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6.     <environments default="development">
  7.         <environment id="development">
  8.             <transactionManager type="JDBC"/>
  9.             <dataSource type="POOLED">
  10.                 <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
  11.                 <property name="url" value="jdbc:mysql://localhost:3306/powernode"/>
  12.                 <property name="username" value="root"/>
  13.                 <property name="password" value="root"/>
  14.             </dataSource>
  15.         </environment>
  16.     </environments>
  17.     <mappers>
  18.         
  19.         <mapper resource=""/>
  20.     </mappers>
  21. </configuration>
复制代码
第三步:编写XxxMapper.xml 文件
在这个配置文件当编写SQL语句。
这个文件名也不是固定的,放的位置也不是固定的,我们这里给它起个名字,叫做:CarMapper.xml (mapper 英文单词是“映射”的意思),把它临时放到类的根路径下。
在resources根目录下新建CarMapper.xml配置文件(可以参考mybatis手册拷贝)

同时我们在此中编写一条SQL语句,一条insert 插入的SQL语句。
注意编写的是 insert 插入的SQL语句所以,在该 xml 文件中用, 标签举行定义编写。如下:

而在 标签当中,必要定义一个 id 属性的值,该
  1. insert语句,id是这个条SQL语句的唯一标识,这个id就代表了这条SQL语句
复制代码

  1.         <insert id="insertCar">
  2.                 insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
  3.                 values (null,'1003','丰田霸道',30.0,'2000-10-11','燃油车')
  4.         </insert>
  5. // 因为我们的 id 是主键,自增的,所以可以不赋值。为 null ,让其进行一个自增的效果。
复制代码
由于我们的 id 是主键,自增的,所以可以不赋值。为 null ,让其举行一个自增的效果。
注意1:sql语句末了结尾可以不写“;”
注意2:CarMapper.xml文件的名字不是固定的。可以使用其它名字。
注意3:CarMapper.xml文件的位置也是随意的。这里选择放在resources根下,相当于放到了类的根路径下。
注意4:将CarMapper.xml文件路径配置到mybatis-config.xml:
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3.                 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.                 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="fas">
  6.         <insert id="insertCar">
  7.                 insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
  8.                 values (null,'1003','丰田霸道',30.0,'2000-10-11','燃油车')
  9.         </insert>
  10. </mapper>
复制代码
第四步: 在mybatis-config.xml 文件中指定XxxMapper.xml 文件的路径
就是将我们上面配置的 XxxMapper.xml(这里是 CarMapper.xml) 的SQL语句的映射文件创建好,将该文件所在位置的路径,填入到  当中,让MyBatis 框架可以顺利的找到它,并执行此中的SQL语句。注意:resource 属性会自动从类的根路径下开始查找资源。
  1. [/code]注意:resource 属性会自动从类的根路径下开始查找资源。
  2. [/indent][align=center][img]https://img2024.cnblogs.com/blog/3084824/202405/3084824-20240524211254082-1644292152.png[/img][/align]
  3. [code]<?xml version="1.0" encoding="UTF-8" ?>
  4. <!DOCTYPE configuration
  5.         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  6.         "http://mybatis.org/dtd/mybatis-3-config.dtd">
  7. <configuration>
  8.     <environments default="development">
  9.         <environment id="development">
  10.             <transactionManager type="JDBC"/>
  11.             <dataSource type="POOLED">
  12.                 <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
  13.                 <property name="url" value="jdbc:mysql://localhost:3306/powernode"/>
  14.                 <property name="username" value="root"/>
  15.                 <property name="password" value="root"/>
  16.             </dataSource>
  17.         </environment>
  18.     </environments>
  19.     <mappers>
  20.         
  21.         <mapper resource=""/>
  22.     </mappers>
  23. </configuration>
复制代码
第五步: 编写MyBatis 测试程序(使用MyBatis的类库,编写myBatis 程序,该数据库,做增删改查就行了)
起首我们必要知道,在MyBatis 当中,负责执行SQL语句的是哪个对象,同时又该怎样获取到该对象。
负责执行 SQL语句的对象是: SqlSession

SqlSession 是专门来执行 SQL语句的,是一个Java程序和数据库之间的一次会话

想要获取到 SqlSession 对象,就必要先获取SqlSessionFactory 对象,通过SqlSessionFactory 工厂的openSession( ) 方法,来生产 SqlSession 对象。


那怎么湖获取SqlSessionFactory 对象
通过SqlSessionFactoryBuilder 对象的 build( ) 方法,来获取一个SqlSessionFactory 对象。


总结:
MyBatis的核心对象包罗:
SqlSessionFactoryBuilder
SqlSessionFactory
SqlSession
SqlSessionFactoryBuilder-->SqlSessionFactory-->SqlSession
注意事项:
  1. int count = sqlSession.insert("insertCar"); // 这个"insertCar"必须是sql的id
复制代码
该insert(id) 就是,我们上面 CarMapper.xml SQL映射文件当中编写的 SQL 语句(这里是  标签当中的 id 的属性值,保持同等)

同时必要:
执行 sqlSession.commit();  提交数据给数据库(和JDBC是一样的); 提交(mybatis默认采用的事务管理器是JDBC,默认是不提交的,必要手动提交。)
以及执行: sqlSession.close(); 关闭资源,注意:仅仅是关闭资源,并不会提交数据的。
  1. // 5. 提交(mybatis默认采用的事务管理器是JDBC,默认是不提交的,需要手动提交。)
  2. sqlSession.commit();
  3. // 6. 关闭资源(只关闭是不会提交的)
  4. sqlSession.close();
复制代码

完整执行代码:
  1. import org.apache.ibatis.io.Resources;
  2. import org.apache.ibatis.session.SqlSession;
  3. import org.apache.ibatis.session.SqlSessionFactory;
  4. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  5. import java.io.FileInputStream;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. public class MyBatisIntroductionTest {
  9.     public static void main(String[] args) {
  10.         // 1. 创建SqlSessionFactoryBuilder对象
  11.         SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
  12.         // 2. 创建SqlSessionFactory对象
  13.         InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatis-config.xml");
  14.         SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
  15.         // 3. 创建SqlSession对象
  16.         SqlSession sqlSession = sqlSessionFactory.openSession();
  17.         // 4. 执行sql
  18.         int count = sqlSession.insert("insertCar"); // 这个"insertCar"必须是sql的id
  19.         System.out.println("插入几条数据:" + count);
  20.         // 5. 提交(mybatis默认采用的事务管理器是JDBC,默认是不提交的,需要手动提交。)
  21.         sqlSession.commit();
  22.         // 6. 关闭资源(只关闭是不会提交的)
  23.         sqlSession.close();
  24.     }
  25. }
复制代码
运行效果:


MyBatis 第一个入门程序小总结:
第一: 在MyBatis中一定是有一个很重要的对象,这个对象是:SqlSessionFactory对象
第二: SqlSessionFactory 对象的创建必要 xml
xml 是什么?它是一个配置文件
MyBatis中有两个主要的配置文件:
t_user 表,一样平常会对应一个UserMapper.xml
t_student 表,一样平常会对应一个StudentMapper.xml
4.3 MyBatis 的第一个入门程序的细节问题




小本领:以后凡是遇到 resource 这个单词,大部分情况下,这种加载资源的方式就是从(resource)类路径下开始检索加载的。
例如: 下面三种获取 IO流文件的,检索方式都是从类路径下开始的。
  1. InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
  2. InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatis-config.xml");
  3. InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");  // 使用类加载器
复制代码
采用从 (resource)类路径 加载文件的优点:
  1. 采用这种方式,从类的路径当种加载资源,项目的移植性很强,项目从Windwos移植到Linux,没有路径上的问题
复制代码
而下面这个是:从体系的绝对路径开始加载的
  1. InputStream stream = new FileInputStream("E:\\mybatis-config.xml");
复制代码
采用体系的绝对路径加载文件资源的缺点:
  1. 可移植性差,程序不够健壮,可能移植到其他的操作系统当中,导致以上路径无效,比如Linux,因为Linux系统是没有所谓的D盘,C盘之类的说法。所以想要移植到Linux当中运行的话,还需要修改Java代码才行。这样就违背了OCP原则了。
复制代码
5. 关于MyBatis核心配置文件的名字和路径详解

MyBatis 的核心配置文件就是,我们上述的名为 mybatis-config.xml 的配置文件。

已经验证过了,mybatis 核心配置文件的名字,不一定是:mybatis-config.xml 。mybatis 核心配置文件存放的路径,也不一定是类的根路径,可以放到其他的位置,但是为了项目的移植性。健壮性,最好将这个配置文件放到类路径下面。
同理的对应的 SQL 映射文件 XxxMapper.xml 文件的路径也可以不放在根(类)路径下,不过如果 SQL 映射文件 XxxMapper.xml 文件是根据 体系的绝对路径 来的话,必要用  标签。如下:

重点:注意的是,无论是 MyBatis 的核心配置文件,还是对应的 SQL 映射文件 XxxMapper.xml 文件,如果文件寄义目录的话,一定要带上目录才行如下:


源码解析:MyBatis 工具类的:InputStream is = Resources.getResourceAsStream("mybatis-config.xml")  的底层调用的机制。


  1. > InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml")
  2. > ClassLoader.getSystemClassLoader() 获取系统的类加载器。
  3. > 系统类加载器有一个方法叫做:getResourceAsSteam
  4. > 它就是从类路径当中加载资源的
  5. > 通过源代码分析发现:
  6. >   InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
  7. >   底层的源代码其实现就是:
  8. > InputStream is = ClasLoader.getSystemClassLoader().getResourceAsStream("mybatis-config.xml");
  9. >
复制代码
6. 关于 mybatis 的事务管理机制(深度剖析)

关于 mybatis 的事务管理机制:
在mybatis-config.xml 文件中,可以通过以下的配置举行 mybatis 的事务处理。
通过:** ** 标签举行设置即可。

type 的属性值包罗两个:
type 背面的值,只有以上两个值可以选择,不区分巨细写。
在mybatis 中提供了两种事务管理机制。
MyBatis 框架自己管理事务,自己采用原生的JDBC 代码去管理事务
  1. > conn.setAutoCommit(false);开启事务,false 是默认的,可以不用写
  2. > ...业务处理...
  3. > conn.commit(); 手动提交事务
复制代码
使用JDBC事务管理器的话,底层创建的事务管理器对象,jdbcTransaction对象。
  1. 如果你编写的代码是下面的代码:
  2.   SqlSession sqlSession = sqlSessionFactory.openSession(true);
  3.   表示没有开启事务,因为这种方式压根不会执行,com.setAutoCommit(false)
  4.   在JDBC事务中,没有执行com.setAutoCommit(false);那么autoCommit就是true.
  5.   如果autoCommit 是 true ,就表示没有开启事务,只要执行任意一条DML语句就提交了一次
复制代码
我们可以举行一个 Debug 调试,举行一个检查
这里我们用默认的 false ,也可以不填,都是 false
  1.   SqlSession sqlSession = sqlSessionFactory.openSession();
  2.   SqlSession sqlSession = sqlSessionFactory.openSession(false);
复制代码





下面我们设置为:true



<strong>在  JDBC事务管理器 下,SqlSession sqlSession = sqlSessionFactory.openSession( 不填,或者 false); 表示开启事务了(必要自己手动提交,sqlSession.commit()
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4