1. Mybatis 连接池与事务深入
1.1 Mybatis 的连接池技术
在 Mybatis 的 SqlMapConfig.xml 配置文件中,通过<dataSource type="pooled">
来实现 Mybatis 中连接池的配置。
1.1.1 Mybatis 连接池的分类
在 Mybatis 中我们将它的数据源 dataSource 分为以下几类:
- UNPOOLED:不使用连接池的数据源
- POOLED:使用连接池的数据源
- JNDI:使用 JNDI 实现的数据源
在这三种数据源中,我们一般采用的是 POOLED 数据源(很多时候我们所说的数据源就是为了更好的管理数据库连接,也就是我们所说的连接池技术)。
1.1.2 Mybatis 中数据源的配置
1 | <!-- 配置数据源(连接池)信息 --> |
MyBatis 在初始化时,根据<dataSource>
的 type 属性来创建相应类型的的数据源 DataSource。
1.1.3 Mybatis 中 DataSource 的存取
MyBatis 是通过工厂模式来创建数据源 DataSource 对象的, MyBatis 定义了抽象的工厂接口:org.apache.ibatis.datasource.DataSourceFactory,通过其 getDataSource()方法返回数据源DataSource。
MyBatis 创建了 DataSource 实例后,会将其放到 Configuration 对象内的 Environment 对象中, 供以后使用。
1.1.4 Mybatis 中连接的获取过程分析
当我们需要创建 SqlSession 对象并需要执行 SQL 语句时,这时候 MyBatis 才会去调用 dataSource 对象来创建java.sql.Connection对象。也就是说,java.sql.Connection对象的创建一直延迟到执行SQL语句的时候。当我们用完了就再立即将数据库连接归还到连接池中。
1.2 Mybatis 的事务控制
1.2.1 JDBC 中事务的回顾
在 JDBC 中我们可以将事务的提交改为自动方式,通过 setAutoCommit()方法就可以调整。
1.2.2 Mybatis 中事务提交方式
Mybatis 中事务的提交方式,本质上就是调用 JDBC 的 setAutoCommit()来实现事务控制。
1 |
|
控制台输出的结果:
Connection 的整个变化过程,通过分析我们能够发现之前的 CUD 操作过程中,我们都要手动进行事务的提交,原因是 setAutoCommit()方法,在执行时它的值被设置为 false 了,所以我们在 CUD 操作中,必须通过sqlSession.commit()方法来执行提交操作。
1.2.3 Mybatis 自动提交事务的设置
1 | //4.创建 SqlSession 对象 |
所对应的 DefaultSqlSessionFactory 类的源代码:
2. Mybatis 的动态 SQL 语句
2.1 <if>
标签
1 | <!-- 根据条件查询 --> |
2.2 <where>
标签
为了简化上面 where 1=1 的条件拼装,我们可以采用<where>
标签来简化开发。
1 | <select id="findUserByCondition" resultMap="userMap" parameterType="user"> |
2.3 <foreach>
标签
2.3.1 需求
传入多个 id 查询用户信息,用下边两个 sql 实现:
1 | SELECT * FROM USERS WHERE username LIKE '%张%' AND (id =10 OR id =89 OR id=16) |
这样我们在进行范围查询时,就要将一个集合中的值,作为参数动态添加进来。
2.3.2 在 QueryVo 中加入一个 List 集合用于封装参数
1 | /** |
2.3.3 映射配置
1 | <!-- 根据queryvo中的Id集合实现查询用户列表 --> |
2.4 简化编写的 SQL 片段
Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。
2.4.1 定义代码片段
1 | <!-- 了解的内容:抽取重复的sql语句--> |
2.4.2 引用代码片段
1 | <!--配置查询所有--> |
3. Mybatis 多表查询之一对多
用户为User 表,账户为Account表。一个用户(User)可以有多个账户(Account)。
3.1 一对一查询( 多对一)
查询所有账户信息,关联查询下单用户信息。
3.1.1 方式一
3.1.1.1 定义账户信息的实体类
1 | public class Account implements Serializable { |
3.1.1.2 编写 Sql 语句
1 | select a.*, u.username, u.address |
3.1.1.3 定义 AccountUser 类
为了能够封装上面 SQL 语句的查询结果,定义 AccountUser 类中要包含账户信息同时还要包含用户信息,所以我们要在定义 AccountUser 类时可以继承 User 类。
1 | /** |
3.1.1.4 映射配置
1 | <!--查询所有账户同时包含用户名和地址信息--> |
定义专门的 po 类作为输出类型,其中定义了 sql 查询结果集所有的字段。此方法较为简单,企业中使用普遍。
3.1.2 方式二
使用 resultMap,定义专门的 resultMap 用于映射一对一查询结果。
通过面向对象的(has a)关系可以得知,我们可以在 Account 类中加入一个 User 类的对象来代表这个账户是哪个用户的。
3.1.2.1 修改 Account 类
在 Account 类中加入 User 类的对象作为 Account 类的一个属性。
1 | /** |
3.1.2.2 映射配置
1 | <!-- 定义封装account和user的resultMap --> |
3.2 一对多查询
查询所有用户信息及用户关联的账户信息。
3.2.1 编写 SQL 语句
1 | SELECT u.*, |
3.2.2 User类加入 List<Account>
1 | /** |
3.2.3 映射配置
1 | <!-- 定义User的resultMap--> |
4. Mybatis 多表查询之多对多
多对多关系其实是双向的一对多关系。一个用户可以有多个角色,一个角色可以赋予多个用户。
4.1 实现 Role 到 User 多对多
实现查询所有角色并且加载它所分配的用户信息。
4.1.1 编写 SQL 语句
1 | select u.*, r.id as rid, r.role_name, r.role_desc |
4.1.2 编写角色实体类
1 | /** |
4.1.3 映射配置
1 | <!--定义role表的ResultMap--> |
4.2 实现 User 到 Role 的多对多
4.2.1 编写 SQL 语句
1 | select u.*, r.id as rid, r.role_name, r.role_desc |
4.2.2 编写用户实体类
1 | /** |
4.2.3 映射配置
1 | <!-- 定义User的resultMap--> |
5. JNDI数据源
JNDI:Java Naming and Directory Interface。是SUN公司推出的一套规范,属于JavaEE技术之一。目的是模仿windows系统中的注册表。在服务器中注册数据源
5.1 创建Maven的war工程并导入坐标
1 | <groupId>com.wgy</groupId> |
5.2 在webapp文件下创建META-INF目录
5.3 在META-INF目录中建立一个名为context.xml的配置文件
1 |
|
5.4 修改SqlMapConfig.xml中的配置
1 | <!--配置环境--> |
-------------本文结束感谢您的阅读-------------
本文标题: MyBatis(三)
本文链接: https://wgy1993.gitee.io/archives/f1b11122.html
版权声明: 本作品采用 CC BY-NC-SA 4.0 进行许可。转载请注明出处!
