java ibatis 连接_JAVAORM框架之Mybatis (Ibatis) 详解

Mybatis基础概念

Mybatis是一个持久层框架

7bf0a45dab4c432cbe008a62699213e6.png

它对JDBC操作数据库进行封装,让我们更关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。下面是Mybatis的架构图

9c38a18bb88d874cef77b42740ec6c91.png

Mybatis又是如何解决JDBC中存在的问题呢?

1、创建数据库连接相关操作,存在硬编码

​a)解决方案:通过Mybatis全局配置文件,对数据库连接进行配置

2、statement相关操作,存在硬编码

​a)解决方案:通过Mapper映射文件,对statement相关处理进行配置。

3、频繁开启数据库连接,会降低数据库处理性能。

​a)解决方案:通过Mybatis全局配置文件,配置连接池。

Mybatis开放方式演进

bba98152376e4e7f1cf5e4ca90853154.png

0d6ca2dac43b5cb605351ae0afdfb4f6.png

4c21ac867fec4dafd906b6b13a0855a5.png

Mybatis框架核心要点

关联查询

所谓的关联查询就是一对一和一对多以及多对多的应用,例如下面的例子

e20b767fefc6cf75b630df65e43ed094.png

一对一 : 例如在获取订单的时候需要获取该订单所属的用户信息

解决思路 : 使用ResultMap或者ResultType自定义一个POJO进行结果映射

一对多 : 例如在获取用户信息的时候需要获取该用户的所有订单信息

解决思路 : 自定义一个POJO使用(只能使用)ResultMap进行结果映射

延迟加载(懒加载)

关于延迟加载

MyBatis中的延迟加载,也称为懒加载,是指在进行关联查询时,按照设置延迟规则推迟对关联对象的select查询。延迟加载可以有效的减少数据库压力。

Mybatis的延迟加载,需要通过resultMap标签中的association和collection子标签才能演示成功。

Mybatis的延迟加载,也被称为是嵌套查询,对应的还有嵌套结果的概念,可以参考一对多关联的案例。

注意:MyBatis的延迟加载只是对关联对象的查询有延迟设置,对于主加载对象都是直接执行查询语句的。

延迟加载分类

MyBatis根据对关联对象查询的select语句的执行时机,分为三种类型:直接加载、侵入式加载与深度延迟加载

直接加载: 执行完对主加载对象的select语句,马上执行对关联对象的select查询。

侵入式延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。但当要访问主加载对象的详情时,就会马上执行关联对象的select查询。即对关联对象的查询执行,侵入到了主加载对象的详情访问中。也可以这样理解:将关联对象的详情侵入到了主加载对象的详情中,即将关联对象的详情作为主加载对象的详情的一部分出现了。

深度延迟:执行对主加载对象的查询时,不会执行对关联对象的查询。访问主加载对象的详情时也不会执行关联对象的select查询。只有当真正访问关联对象的详情时,才会执行对关联对象的select查询。

延迟加载策略需要在Mybatis的全局配置文件中,通过标签进行设置。

如何使用

直接加载 通过对全局参数:lazyLoadingEnabled进行设置,默认就是false。

侵入式加载

深度延迟加载

动态SQL

动态SQL的思想:就是使用不同的动态SQL标签去完成SQL字符串的拼接处理。

解决的问题 :

在映射文件中,会编写很多有重叠部分的SQL语句,比如SELECT语句和WHERE语句等这些重叠语句,该如何处理

如果页面传递过来一个参数,但是SQL语句中的条件有多个,此时会发生问题。

主要标签

if标签 where标签 sql片段 foreach标签

Mybatis缓存

Mybatis提供查询缓存,如果缓存中有数据就不用从数据库中获取,用于减轻数据压力,提高系统性能。

Mybatis的查询缓存总共有两级,我们称之为一级缓存和二级缓存,如图:

3bd73065dfe53ad17c8daff9a7bfdd8f.png

• 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

• 二级缓存是Mapper(namespace)级别的缓存。多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

一级缓存原理图

b6640eb64153b29fb47b2c00e030cafd.png

第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息,将查询到的用户信息存储到一级缓存中。

如果中间sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。

第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。

二级缓存原理图

a22839d49da08148fe2281cb70f58534.png

1. 第一次调用mapper下的SQL去查询用户信息。查询到的信息会存到该mapper对应的二级缓存区域内。

2. 第二次调用相同namespace下的mapper映射文件中相同的SQL去查询用户信息。会去对应的二级缓存内取结果。

3. 如果调用相同namespace下的mapper映射文件中的增删改SQL,并执行了commit操作。此时会清空该namespace下的二级缓存。

如何开启二级缓存(默认关闭)

在核心配置文件SqlMapConfig.xml中加入以下内容(开启二级缓存总开关):

在UserMapper映射文件中,加入以下内容,开启二级缓存:

说明 : 由于二级缓存的数据不一定都是存储到内存中,它的存储介质多种多样,比如说存储到文件系统中,所以需要给缓存的对象执行序列化。如果该类存在父类,那么父类也要实现序列化。(既查询结果对象要实现序列化接口)

Mybatis逆向工程

由于Mybatis是半自动化的ORM框架,所以仍然有很多事情需要我们去做

例如 : 编写与数据库表对应的实体,编写Mapper接口,编写Mapper配置文件

所谓的Mybatis逆向工程仅仅是一个项目所以只需要在下面配置中填写好自己数据库的相关信息,运行main方法既可以为我们生成POJO类,Mapper接口,Mapper配置文件

/p>

PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"

"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root" password="root">

targetProject=".\src">

targetProject=".\src">

targetPackage="com.kkb.ms.mapper" targetProject=".\src">

注意 :每次执行逆向工程代码之前,先删除原来已经生成的mapper xml文件再进行生成。mapper.xml文件的内容不是被覆盖而是进行内容追加,会导致mybatis解析失败。po类及mapper.java文件的内容是直接覆盖没有此问题。

PageHelper分页插件

如果你也在用Mybatis,建议尝试该分页插件,这个一定是最方便使用的分页插件。

使用方法如下

首先增加依赖

com.github.pagehelper

pagehelper

5.1.6

配置PageHelper

• Mybatis全局配置文件

• Spring配置文件

helperDialect=mysql

在项目中使用PageHelper

//获取第1页,10条内容,默认查询总数count

PageHelper.startPage(1, 10);

List list = countryMapper.selectAll();

//用PageInfo对结果进行包装

PageInfo page = new PageInfo(list);

//测试PageInfo全部属性

//PageInfo包含了非常全面的分页属性

assertEquals(1, page.getPageNum());

assertEquals(10, page.getPageSize());

注意事项

1. 需要分页的查询语句,必须是处于PageHelper.startPage(1, 10);后面的第一条语句。

2. 如果查询语句是使用resultMap进行的嵌套结果映射,则无法使用PageHelper进行分页。

Mybatis插件介绍

注解开发

使用注解开发,我们不再需要XML配置文件

常用注解说明

增删改查-静态SQL

@Insert:相当于标签,实现新增

@Update: 相当于标签,实现更新

@Delete: 相当于标签,实现删除

@Select: 相当于标签,实现查询

@SelectKey:相当于标签,实现主键返回

增删改查-动态SQL

@InsertProvider: 相当于标签,实现新增

@UpdateProvider: 相当于标签,实现更新

@DeleteProvider: 相当于标签,实现删除

@SelectProvider: 相当于标签,实现查询

多表关联

• @Results: 相当于标签,需要和@Result注解一起使用。

• @Result: 相当于和标签,实现结果集中某一列的数据映射

* column 数据库的列名

* property 需要装配的属性名

* one需要使用的@One 注解(@Result(one=@One()))

* many需要使用的@Many 注解(@Result(many=@many()))

• @One: 相当于标签,实现一对一关系映射

• @Many:相当于标签,实现一对多关系映射

• @One和@Many注解的属性:

* select 属性:代表将要执行的 sql 语句

* fetchType 属性:代表加载方式,一般如果要延迟加载都设置为 LAZY 的值

• 使用格式:

1. @Results({@Result(),@Result()})或@Results(@Result())

2. @Result(column=" ",property="",one=@One(select=""))

辅助注解

@Options:相当于标签属性的设置

@Param:如果你的映射器的方法需要多个参数,这个注解可以被应用于映射器的方法参数来给每个参数一个名字。

其他注解

@CacheNamespace:相当于标签,实现二级缓存。

属性:implemetation,eviction,flushInterval,size,readWrite,blocking和properties

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
// JBuilder API Decompiler stub source generated from class file // 2010-1-15 // -- implementation of methods is not available package com.ibatis.common.jdbc; // Imports import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Savepoint; import java.sql.Statement; import java.util.Map; public class SimplePooledConnection implements InvocationHandler { // Fields private static final String CLOSE = "close"; private static final Class[] IFACES; private int hashCode; private SimpleDataSource dataSource; private Connection realConnection; private Connection proxyConnection; private long checkoutTimestamp; private long createdTimestamp; private long lastUsedTimestamp; private int connectionTypeCode; private boolean valid; // Constructors public SimplePooledConnection(Connection connection, SimpleDataSource dataSource) { } // Methods public void invalidate() { } public boolean isValid() { return false;} public Connection getRealConnection() { return null;} public Connection getProxyConnection() { return null;} public int getRealHashCode() { return 0;} public int getConnectionTypeCode() { return 0;} public void setConnectionTypeCode(int connectionTypeCode) { } public long getCreatedTimestamp() { return 0L;} public void setCreatedTimestamp(long createdTimestamp) { } public long getLastUsedTimestamp() { return 0L;} public void setLastUsedTimestamp(long lastUsedTimestamp) { } public long getTimeElapsedSinceLastUse() { return 0L;} public long getAge() { return 0L;} public long getCheckoutTimestamp() { return 0L;} public void setCheckoutTimestamp(long timestamp) { } public long getCheckoutTime() { return 0L;} private Connection getValidConnection() { return null;} public int hashCode() { return 0;} public boolean equals(Object obj) { return false;} public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return null;} public Statement createStatement() throws SQLException { return null;} public PreparedStatement prepareStatement(String sql) throws SQLException { return null;} public CallableStatement prepareCall(String sql) throws SQLException { return null;} public String nativeSQL(String sql) throws SQLException { return null;} public void setAutoCommit(boolean autoCommit) throws SQLException { } public boolean getAutoCommit() throws SQLException { return false;} public void commit() throws SQLException { } public void rollback() throws SQLException { } public void close() throws SQLException { } public boolean isClosed() throws SQLException { return false;} public DatabaseMetaData getMetaData() throws SQLException { return null;} public void setReadOnly(boolean readOnly) throws SQLException { } public boolean isReadOnly() throws SQLException { return false;} public void setCatalog(String catalog) throws SQLException { } public String getCatalog() throws SQLException { return null;} public void setTransactionIsolation(int level) throws SQLException { } public int getTransactionIsolation() throws SQLException { return 0;} public SQLWarning getWarnings() throws SQLException { return null;} public void clearWarnings() throws SQLException { } public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { return null;} public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return null;} public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { return null;} public Map getTypeMap() throws SQLException { return null;} public void setTypeMap(Map map) throws SQLException { } public void setHoldability(int holdability) throws SQLException { } public int getHoldability() throws SQLException { return 0;} public Savepoint setSavepoint() throws SQLException { return null;} public Savepoint setSavepoint(String name) throws SQLException { return null;} public void rollback(Savepoint savepoint) throws SQLException { } public void releaseSavepoint(Savepoint savepoint) throws SQLException { } public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return null;} public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return null;} public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { return null;} public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { return null;} public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { return null;} public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { return null;} }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值