- 第一部分&第二部分
- 第三部分 Mybatis
- 第1章 初识MyBatis框架
- 1. 框架的优势
- 2. 传统JDBC的劣势
- 3. Mybatic介绍
- 4. Mybatis环境搭建
- 4.1 创建工程
- 4.2 引入相关依赖
- 4.3 数据库准备
- 4.4 编写数据库连接信息配置文件
- 4.5 编写核心配置文件和映射文件
- 5. ==Mybatis工作原理==
- 第2章 MyBatis的核心配置
- 1. Mybatis的核心对象
- 1.1 SqlSessionFactoryBuilder对象
- 1. 2 SqlSessionFactory对象
- 1.3 SqlSession对象
- 2. MyBatis核心配置文件
- 2.1 Mybatis核心配置文件中的主要元素
- 2.2 < properties >元素
- 2.3 < settings >元素
- 2.4 < typeAliases >元素
- 2.5 < environments >元素
- 2.6 < mappers >元素
- 3. MyBatis映射文件
- 3.1 MyBatis映射文件中的常用元素
- 3.2 namespace属性
- 3.3 < select >元素
- 3.3.1 < select >常用属性
- 3.4 < insert >元素
- 3.5 < update >元素
- 3.6 < delete >元素
- 3.6.1 < delete >元素的属性
- 3.7 < sql >元素
- 3.8 < resultMap >元素
- 第3章 动态SQL
- 1. 常用元素
- 2. < if >元素
- 3. < choose >、< when >、< otherwise >元素
- 4. < where > 元素
- 5. < trim >元素
- 6. < set >元素
- 7. < foreach > 元素
- 第4章 MyBatis的关联映射和缓存机制
- 1. Java对象如何描述事物之间的关系
- 2. 一对一查询
- 2.1 < association >元素
- 3. 一对多查询
- 4. 多对多查询
- 5. MyBatis缓存机制
- 5.1 一级缓存
- 5.2 二级缓存
- 第5章 MyBatis的注解开发
- 1. 基于注解的单表增删改查
- 1.1 @Select注解
- 1.2 @Insert注解
- 1.3 @Update注解
- 1.4 @Delete注解
- 1.5 @Param注解
- 2. 基于注解的关联查询
- 2.1 一对一查询
- 2.2 一对多查询
- 2.3 多对多查询
- 第四部分 Spring
JavaEE复习资料(1)_FZU_软工_2022
第三部分 Mybatis 第1章 初识MyBatis框架 1. 框架的优势相比于使用JSP+Servlet技术进行软件开发,使用框架有以下优势:
- 如事务处理、安全性、数据流控制等都可以交给框架处理,程序员只需要集中精力完成系统的业务逻辑设计,降低了开发难度。
- 提高代码规范性和可维护性:当多人协同进行开发时,代码的规范性和可维护性就变得非常重要。成熟的框架都有严格的代码规范,能保证团队整体的开发风格统一。
- 提高软件性能:使用框架进行软件开发,可以减少程序中的冗余代码。例如,使用Spring框架开发时,通过Spring的IOC特性,可以将对象之间的依赖关系交给Spring控制,方便解耦,简化开发;使用MyBatis框架开发时,MyBatis提供了XML标签,支持动态的SQL,开发人员无需在类中编写大量的SQL语句,只需要在配置文件中进行配置即可。
JDBC是Java程序实现数据访问的基础,JDBC的劣势主要有以下几个方面:
- 数据库连接创建、释放频繁会造成系统资源浪费,从而影响系统性能。
- SQL语句在代码中硬编码,造成代码不易维护。在实际应用的开发中,SQL变化的可能性较大。在传统JDBC编程中,SQL变动需要改变Java代码,违反了开闭原则。
- 用PreparedStatement向占有位符号传参数存在硬编码,因为SQL语句的where条件不一定,可能多也可能少,修改SQL需要修改代码,造成系统不易维护。
- JDBC对结果集解析存在硬编码(查询列名),SQL变化导致解析代码变化,造成系统不易维护。
MyBatis是一个支持普通SQL查询、存储过程以及高级映射的持久层框架,它消除了几乎所有的JDBC代码和参数的手动设置以及对结果集的检索,使用简单的XML或注解进行配置和原始映射,将接口和Java的POJO映射成数据库中的记录,使得Java开发人员可以使用面向对象的编程思想来操作数据库。
MyBatis框架是一个ORM(Object/Relation Mapping,即对象关系映射)框架。所谓的ORM就是一种为了解决面向对象与关系型数据库中数据类型不匹配的技术,它通过描述Java对象与数据库表之间的映射关系,自动将Java应用程序中的对象持久化到关系型数据库的表中。ORM框架的工作原理可以通过一张图来展示:
针对JDBC编程的劣势,MyBatis提供了以下解决方案,具体如下:
- 数据库连接创建、释放频繁会造成系统资源浪费,从而影响系统性能。
解决方案:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。 - SQL语句在代码中硬编码,造成代码不易维护。在实际应用的开发中,SQL变化的可能较大。在传统JDBC编程中,SQL变动需要改变Java代码,违反了开闭原则。
解决方案:MyBatis将SQL语句配置在MyBatis的映射文件中,实现了与Java代码的分离。 - 使用preparedStatement向占有位符号传参数存在硬编码,因为SQL语句的where条件不一定,可能多也可能少,修改SQL需要修改代码,造成系统不易维护。
解决方案:MyBatis自动将Java对象映射至SQL语句,通过Statement中的parameterType定义输入参数的类型。 - JDBC对结果集解析存在硬编码(查询列名),SQL变化导致解析代码变化,造成系统不易维护。
解决方案:MyBatis自动将SQL执行结果映射至Java对象,通过Statement中的resultType定义输出结果的类型。
使用MyBatis框架进行数据库开发之前,需要先搭建MyBatis环境,MyBatis环境搭建主要有如下基本步骤。
4.1 创建工程创建Maven工程。
4.2 引入相关依赖在项目的pom.xml文件中导入MySQL驱动包、Junit测试包、MyBatis的核心包等相关依赖。
4.3 数据库准备创建数据库,编写几条测试数据。
4.4 编写数据库连接信息配置文件mysql.driver = com.mysql.cj.jdbc.Driver mysql.url = jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false mysql.username = root mysql.password = root4.5 编写核心配置文件和映射文件
在项目的src/main/resources目录下创建MyBatis的核心配置文件,该文件主要用于项目的环境配置,如数据库连接相关配置等。核心配置文件可以随意命名,但通常将其命名为mybatis-config.xml。
5. Mybatis工作原理
- MyBatis 读取核心配置文件 mybatis-config.xml 。mybatis-config.xml 核心配置文件主要配置了 MyBatis 的运行环境等信息。
- 加载映射文件 Mapper.xml。Mapper.xml 文件配置了操作数据库的 SQL 语句,需要在 mybatis-config.xml 中加载才能执行。mybatis-config.xml 可以加载多个映射文件,每个映射文件对应数据库中的一张表。
- 构造会话工厂。通过 MyBatis 的环境等配置信息构建会话工厂SqlSessionFactory,用于创建 SqlSession。
- 创建会话对象。由会话工厂 SqlSessionFactory 创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。
- 创建执行器。会话对象本身不能直接操作数据库,MyBatis 底层定义了一个 Executor 接口用于操作数据库,执行器会 根据 SqlSession 传递的参数动态的生成需要执行的 SQL 语句,同时负责查询缓存的维护。
- 封装 SQL 信息。SqlSession 内部通过执行器 Executor 操作数据库,执行器将待处理的 SQL 信息封装到MappedStatement 对象中,MappedStatement 对象中存储了要映射的 SQL 语句的 id、参数等。Mapper.xml 文件中一个 SQL 语句对应一个 MappedStatement 对象,SQL 语句的 id 即是 MappedStatement 的 id。Executor 执行器会在执行 SQL 语句之前,通过 MappedStatement 对象将输入的参数映射到 SQL 语句中。
- 操作数据库。根据动态生成的 SQL 操作数据库。
- 输出结果映射。执行 SQL 语句之后,通过 MappedStatement 对象将输出结果映射至 Java 对象中。
// 使用MyBatis提供的Resources类加载MyBatis的配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
// 构建SqlSessionFactory工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 构建会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
1.1 SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder.build(Reader reader,String environment,Properties properties)
上述build()方法中,参数Reader是字符流,它封装了XML文件形式的配置信息;参数environment和参数properties为可选参数。其中,参数environment决定将要加载的环境,包括数据源和事务管理器;参数properties决定将要加载的properties文件。
SqlSessionFactory对象是线程安全的,它一旦被创建,在整个应用程序执行期间都会存在。如果我们多次创建同一个数据库的SqlSessionFactory对象,那么该数据库的资源将很容易被耗尽。通常每一个数据库都只创建一个SqlSessionFactory对象,所以在构建SqlSessionFactory对象时,建议使用单例模式。
1. 2 SqlSessionFactory对象SqlSessionFactory的openSession()方法:
参数execType有三个可选值:
- ExecutorType.SIMPLE:表示为每条语句创建一条新的预处理语句。
- ExecutorType.REUSE:表示会复用预处理语句。
- ExecutorType.BATCH:表示会批量执行所有更新语句。
参数autoCommit可设置是否开启自动提交事务
参数connection可提供自定义连接。
1.3 SqlSession对象每一个线程都应该有一个自己的SqlSession对象,并且该对象不能共享。SqlSession对象是线程不安全的,因此其使用范围最好在一次请求或一个方法中,绝不能将其放在类的静态字段、对象字段或任何类型的管理范围(如Servlet的HttpSession)中使用。SqlSession对象使用完之后,要及时的关闭,SqlSession对象通常放在finally块中关闭。
2. MyBatis核心配置文件 2.1 Mybatis核心配置文件中的主要元素
在MyBatis核心配置文件mybatis-config.xml中使用
2.3 < settings >元素
2.4 < typeAliases >元素...
核心配置文件若要引用一个POJO实体类,需要输入POJO实体类的全限定类名,而全限定类名比较冗长,如果直接输入,很容易拼写错误。这时可以使用
- 在
元素下,使用多个 元素为每一个全限定类逐个配置别名。
- 通过自动扫描包的形式自定义别名。
除了可以使用
MyBatis可以配置多套运行环境,如开发环境、测试环境、生产环境等,我们可以灵活选择不同的配置,从而将SQL映射到不同运行环境的数据库中。不同的运行环境可以通过
MyBatis的运行环境信息包括事务管理器和数据源。在MyBatis的核心配置文件中,MyBatis通过
例如:
2.6 < mappers >元素...
在MyBatis的核心配置文件中,
- 使用类路径引入
- 使用本地文件路径引入
- 使用接口类引入
- 使用包名引入
3. MyBatis映射文件 3.1 MyBatis映射文件中的常用元素 3.2 namespace属性
有两个作用:
- 用于区分不同的mapper,全局唯一。
- 绑定DAO接口,即面向接口编程。当namespace绑定某一接口之后,可以不用写该接口的实现类,MyBatis会通过接口的全限定名查找到对应的mapper配置来执行SQL语句,因此namespace的命名必须跟接口同名。
在不同的映射文件中,
3.3.1 < select >常用属性 3.4 < insert >元素select * from users where id = #{id}
insert into users values(#{uid},#{uname},#{uage})
很多时候,执行插入操作后,需要获取插入成功的数据生成的主键值,不同类型数据库获取主键值的方式不同,主要有对支持主键自动增长的数据库获取主键值和不支持主键自动增长的数据库获取主键值的方式。
- 使用支持主键自动增长的数据库获取主键值
如果使用的数据库支持主键自动增长(如MySQL和SQL Server),那么可以通过keyProperty属性指定POJO类的某个属性接收主键返回值(通常会设置到id属性上),然后将useGeneratedKeys的属性值设置为true。
insert into users values(#{uid},#{uname},#{uage})
- 使用不支持主键自动增长的数据库获取主键值
使用MyBatis提供的元素来自定义主键。
3.6 < delete >元素update users set uname=#{uname}, uage=#{uage} where uid=#{uid}
3.6.1 < delete >元素的属性 3.7 < sql >元素delete from users where uid=#{uid}
3.8 < resultMap >元素AND id = #{id} AND address LIKE concat('%',#{keyword},'%') SELECT * FROM _order WHERe 1=1
第3章 动态SQL 1. 常用元素 2. < if >元素AND id = #{id} AND address LIKE concat('%',#{keyword},'%') SELECT * FROM _order WHERe 1=1
可以理解为满足test中的条件,才会执行
3. < choose >、< when >、< otherwise >元素AND id = #{id}
可以理解为switch(),只执行子情况的其中一种。
4. < where > 元素and username like concat('%',#{username}, '%') and jobs= #{jobs} and phone is not null
为了防止出现 WHERe AND 的SQL语句错误出现。
5. < trim >元素select * from t_customer and username like concat('%',#{username}, '%') and jobs= #{jobs}
6. < set >元素select * from t_customer and username like concat('%',#{username}, '%') and jobs= #{jobs}
在映射文件中使用
当在
7. < foreach > 元素update t_customer where id=#{id} username=#{username}, jobs=#{jobs}, phone=#{phone},
collection属性的取值:
- List类型,若入参为单参数且参数类型是一个List,collection属性值为list。
- 数组类型,若入参为单参数且参数类型是一个数组,collection属性值为array。
- Map类型,若传入参数为多参数,就需要把参数封装为一个Map进行处理,collection属性值为Map。
第4章 MyBatis的关联映射和缓存机制 1. Java对象如何描述事物之间的关系select * from t_customer where id in #{id}
数据表之间的关系实质上描述的是数据之间的关系,除了数据表,在Java中,还可以通过对象来描述数据之间的关系。通过Java对象描述数据之间的关系,其实就是使对象的属性与另一个对象的属性相互关联。
在MyBatis中,通过元素来处理一对一关联关系。元素提供了一系列属性用于维护数据表之间的关系。
2.1 < association >元素
元素是
- 嵌套查询方式
嵌套查询是指通过执行另外一条SQL映射语句来返回预期的复杂类型。
- 嵌套结果方式
嵌套结果是使用嵌套结果映射来处理重复的联合结果的子集。
3. 一对多查询
在MyBatis中,通过
- 嵌套查询方式
- 嵌套结果方式
4. 多对多查询
拆分为两次一对多,按照一对多的思路写。
5. MyBatis缓存机制 5.1 一级缓存MyBatis的一级缓存是SqlSession级别的缓存。如果同一个SqlSession对象多次执行完全相同的SQL语句时,在第一次执行完成后,MyBatis会将查询结果写入到一级缓存中,此后,如果程序没有执行插入、更新、删除操作,当第二次执行相同的查询语句时,MyBatis会直接读取一级缓存中的数据,而不用再去数据库查询,从而提高了数据库的查询效率。
当程序对数据库执行了插入、更新、删除操作,MyBatis会清空一级缓存中的内容以防止程序误读。
5.2 二级缓存相同的Mapper类,相同的SQL语句,如果SqlSession不同,则两个SqlSession查询数据库时,会查询数据库两次,这样也会降低数据库的查询效率。为了解决这个问题,就需要用到MyBatis的二级缓存。MyBatis的二级缓存是Mapper级别的缓存,与一级缓存相比,二级缓存的范围更大,多个SqlSession可以共用二级缓存,并且二级缓存可以自定义缓存资源。
在MyBatis中,一个Mapper.xml文件通常称为一个Mapper,MyBatis以namespace区分Mapper,如果多个SqlSession对象使用同一个Mapper的相同查询语句去操作数据库,在第一个SqlSession对象执行完后,MyBatis会将查询结果写入二级缓存,此后,如果程序没有执行插入、更新、删除操作,当第二个SqlSession对象执行相同的查询语句时,MyBatis会直接读取二级缓存中的数据。
与MyBatis的一级缓存不同的是,MyBatis的二级缓存需要手动开启,开启二级缓存通常要完成以下两个步骤。
- 使用二级缓存前,需要在MyBatis的核心配置mybatis-config.xml文件中通过
元素开启二级缓存的全局配置。
- 开启当前Mapper的namespace下的二级缓存,可以通过MyBatis映射文件中的元素来完成。
我们可以看到 mapper.xml 文件中就这么一个空标签
public interface WorkerMapper {
@Select("select * from tb_worker where id = #{id}")
Worker selectWorker(int id);
}
在核心配置文件mybatis-config.xml中的元素下引入WorkerMapper接口,将WorkerMapper.java接口加载到核心配置文件中。
1.2 @Insert注解
@Insert("insert into tb_worker values(#{name},#{age},#{sex},#{worker_id})")
int insertWorker(Worker worker);
1.3 @Update注解
@Update("update tb_worker set name = #{name},age = #{age} where id = #{id}")
int updateWorker(Worker worker);
1.4 @Delete注解
@Delete("delete from tb_worker where id = #{id}")
int deleteWorker(int id);
1.5 @Param注解
@Select("select * from tb_worker where id = #{param01} and name = #{param02}")
Worker selectWorkerByIdAndName(@Param("param01") int id, @Param("param02") String name);
2. 基于注解的关联查询
2.1 一对一查询
public interface PersonMapper {
@Select("select * from tb_person where id=#{id}")
@Results({@Result(column="cid",property="card",
one=@One(select="com.example.dao.IdCardMapper.selectIdCardById"))})
Person selectPersonById(int id);
}
- property属性用来指定关联属性,这里为card。
- column属性用来指定关联的数据库表中的字段,这里为cid。
- one属性用来指定数据表之间属于哪种关联关系,通过@One注解表明数据表之间是一对一关联关系。
public interface UsersMapper {
@Select("select * from tb_user where id=#{id} ")
@Results({@Result(id = true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "address",property = "address"),
@Result(column = "id",property = "ordersList",
many = @Many(select = "com.example.dao.OrdersMapper.selectOrdersByUserId"))})
Users selectUserById(int id);
}
2.3 多对多查询
拆分为两次一对多,按照一对多的思路写。
第四部分 Spring


