满满干货!收藏!最全MyBatis中XML映射文件标签分析

useCache="true"
timeout="10000"
fetchSize="256"
statementType="PREPARED"
resultSetType="FORWARD_ONLY"
databaseId="mysql"
resultOrdered="false"
resultSets="xxx,xxx"
lang="">java

## id

必选标签。同一个命名空间里面的惟一标识符,若是须要被外部接口调用,则须要和Mapper接口中的方法名保持一致。

## parameterType

可选标签。参数类的彻底限定名或别名,上面示例中的表示咱们传入的参数是一个String类型(关于别名若是不清楚的能够点击这里)。若是不写这个属性的话,MyBatis在解析xml文件的时候会默认设为unset,而后根据TypeHandler推断出参数类型。若是有多个参数的状况下建议仍是不写这个参数,不然可能会出现参数类型转换错误

## parameterMap

这是一个过时的属性,咱们不作讨论。

## resultType

非必选标签。注意这里的非选是由于resultType和resultMap不能并存,二者能且只能选择一个。主要是用来定义一个返回结果集对象的全限定名或者别名。若是接收参数是一个集合,那么这里定义的就是集合中能够包含的类型,而并非集合自己。 好比示例中的写法,那么对应Mapper接口中,适用于如下两种语句:

LwUser listUserByUserName(@Param("userName") String userName);
List listUserByUserName(@Param("userName") String userName); mysql

## resultMap

非必选标签。注意这里的非选是由于resultType和resultMap不能并存,二者能且只能选择一个。resultMap类型的结果集映射,是MyBatis最强大的特性,在这里咱们不展开,过两天会有一篇单独介绍MyBatis一对一和一对多等复杂查询时候会单独介绍该属性。感兴趣的能够先关注我,留意后面的文章。

## flushCache

可选标签。设置为 true时,任什么时候候只要语句被调用,都会致使本地缓存和二级缓存都会被清空,默认值:false。

## useCache
可选标签。设置为 true时将会致使本条语句的结果被二级缓存,对 select 标签语句默认值为true,对insert,delete,update等语句默认是false。

## timeout

可选标签。这个设置是在抛出异常以前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。

## fetchSize

可选标签。这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为 unset(依赖驱动)。注意这个只是尝试,假如把fetchSize设置为10万,而数据库驱动最高只支持到5w,那么也会只能返回5w数据

## statementType

可选标签。能够选择:STATEMENT,PREPARED 或 CALLABLE 中的一个,这会让 MyBatis 分别使用Statement,PreparedStatement 或 CallableStatement,默认值是PREPARED,也就是使用预编译PreparedStatement 语句。

## resultSetType

可选标签。能够选择如下三种类型中的一个,默认为unset(依赖驱动)。

*   FORWARD_ONLY:只容许游标向前访问

*   SCROLL_SENSITIVE:容许游标双向滚动,但不会及时更新数据,也就是说若是数据库中的数据被修改过,并不会在resultSet中体现出来

*   SCROLL_INSENSITIVE:许游标双向滚动,若是数据库中的数据被修改过,会及时更新到resultSet

上面的解释可能有些人仍是看不明白,咱们先来看一段JDBC读取结果集的操做:

![image](https://upload-images.jianshu.io/upload_images/24613101-eb503a5ee3dac968.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

而MyBatis只是把这些操做封装了,底层实际上仍是这个操做,rs.next()游标向前滚,其实还有一个rs.previous()表示游标能够向后滚。 因此FORWARD_ONLY只容许向前滚,访问过的数据就会释放内存,在某些场景中能够提高性能。 后面那两个都是容许双向滚动,因此即便访问过的数据,内存也不能释放。这两个的区别就是一个对数据敏感,一个对数据不敏感。

*   对数据不敏感 就是说当咱们查询出结果以后,会将整个结果集都缓存在内存中,假若有一条数据还没读取到(还在while循环中)这时候有另一个线程修改了这条数据,那么当咱们后面读取这条数据的时候,仍是读取到修改以前的。

*   对数据敏感 就是说当咱们查询出结果以后,只会缓存一个rowid,而并不会缓存整条数据,假若有一条数据还没读取到(还在while循环中)这时候有另一个线程修改了这条数据,那么当咱们后面读取这条数据的时候,会根据rowid去查询数据,查询到的就是最新的数据。不过须要注意的是,由于delete的时候数据其实还在,只是打了个标记,因此若是一条数据被删除了,是体现不出来的。同理,insert也不影响,由于查询出来的数据不包含insert数据的rowid。

若是对于MySQL的InnoDB引擎的MVCC机制,那么数据确定是不会敏感的,由于其余事务改了当前事务也看不到。

## databaseId

可选标签。

## resultOrdered

可选标签。这个设置仅针对嵌套结果 select 语句适用。若是为 true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的状况。这就使得在获取嵌套的结果集的时候不至于致使内存不够用。默认值: false 。

## resultSets

可选标签。这个设置仅对多结果集的状况适用,它将列出语句执行后返回的结果集并每一个结果集给一个名称,名称是逗号分隔的。

## lang

自定义语言,这个我也没用过,因此就不介绍了

## insert

insert用来映射插入语句。如下就是一个insert标签的所有二级标签:

有一些标签和select语句是重复的就再也不重复介绍,主要来关注一下其余标签。

## useGeneratedKeys

可选标签。配置为true时,MyBatis会使用JDBC的getGeneratedKeys方法来取出由数据库内部生成的主键(好比:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值为false。

## keyProperty

可选标签。惟一标记一个属性,MyBatis会将经过getGeneratedKeys 的返回值或者经过insert 语句的selectKey 子元素设置它的键值,默认值是unset 。若是但愿获得多个生成的列,也能够是逗号分隔的属性名称列表

## keyColumn

经过生成的键值设置表中的列名,这个设置仅在某些数据库(像PostgreSQL)是必须的,当主键列不是表中的第一列的时候须要设置。若是但愿获得多个生成的列,也能够是 逗号分隔的属性名称列表

## 获取自增主键

获取自增主键,能够经过keyProperty来映射 定义一个实体类:

package com.lonelyWolf.mybatis.model;git

public class UserAddress {
private int id;
private String address;面试

public int getId() {
    return id;
}

public void setId(int id) {
    this.id = id;
}

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

}redis

定义一个UserAddressMapper.java接口:

package com.lonelyWolf.mybatis.mapper;sql

import com.lonelyWolf.mybatis.model.UserAddress;
import org.apache.ibatis.annotations.Param;数据库

public interface UserAddressMapper {
int insert(UserAddress userAddress);
}apache

注意:这里参数若是直接只有一个的话能够不使用@Param注解,这样在xml文件中能够直接使用JavaBean内的属性名。若是使用了@Param注解,以下:

int insert(@Param("userAddress") UserAddress userAddress);设计模式

那么xml文件中就可使用#{userAddress.属性名}来获取属性JavaBean内的属性

定义一个UserAddressMapper.xml映射文件(keyProperty="id"表示把主键的值设置到参数UserAddress类中的属性id):
insert into lw_user_address (address) values (#{address})
mybatis-config.xml中要新增mapper映射文件配置:
而后写一个测试类:

package com.lonelyWolf.mybatis;缓存

import com.lonelyWolf.mybatis.mapper.UserAddressMapper;
import com.lonelyWolf.mybatis.model.UserAddress;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;

public class TestMyBatisInsert {
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
//读取mybatis-config配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//建立SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//建立SqlSession对象
SqlSession session = sqlSessionFactory.openSession();

try {
        UserAddress userAddress = new UserAddress();
        userAddress.setAddress("广东深圳");
        UserAddressMapper userAddressMapper = session.getMapper(UserAddressMapper.class);
        int i = userAddressMapper.insert(userAddress);
        session.commit();
        System.out.println("插入成功数:" + i);
        System.out.println("插入数据的主键为:" + userAddress.getId());
    }finally {
        session.close();
    }
}

}

输出结果(成功获取到了插入数据的主键):

插入成功数:1
插入数据的主键为:1

## 经过selectKey获取自定义列

假若有些数据库不支持自增主键,或者说咱们想插入自定义的主键,而又不想在业务代码中编写逻辑,那么就能够经过MyBatis的selectKey来获取。 UserAddressMapper.java中新建一个方法:

int insert2(UserAddress userAddress);

而后在UserAddressMapper.xml中对应新增一个insert2语句:
select uuid() from lw_user_address insert into lw_user_address (address) values (#{address})
而后修改测试类:

try {
UserAddress userAddress = new UserAddress();
UserAddressMapper userAddressMapper = session.getMapper(UserAddressMapper.class);
int i = userAddressMapper.insert2(userAddress);
session.commit();
System.out.println("插入成功数:" + i);
System.out.println("插入数据的address为:" + userAddress.getAddress());
}finally {
session.close();
}

输出结果以下,成功得到了咱们自定义的address:

插入成功数:1
插入数据的address为:097dfc8b-f043-11ea-97c4-00163e12524a

selectKey中的order属性有2个选择:BEFORE和AFTER。

*   BEFORE:表示先执行selectKey的语句,而后将查询到的值设置到JavaBean对应属性上,而后再执行insert语句。

*   AFTER:表示先执行AFTER语句,而后再执行selectKey语句,并将selectKey获得的值设置到JavaBean中的属性。上面示例中若是改为AFTER,那么插入的address就会是空值,可是返回的JavaBean属性内会有值。

PS:selectKey中返回的值只能有一条数据,若是知足条件的数据有多条会报错,因此通常都是用于生成主键,确保惟一,或者在selectKey后面的语句加上条件,确保惟一

## update


### 最后

**给读者们一个小福利,有须要这些资料的朋友们[能够点击我,便可免费](https://gitee.com/vip204888/java-p7)领取资料!**

### ActiveMQ消息中间件面试专题

*   什么是ActiveMQ?
*   ActiveMQ服务器宕机怎么办?
*   丢消息怎么办?
*   持久化消息很是慢怎么办?
*   消息的不均匀消费怎么办?
*   死信队列怎么办?
*   ActiveMQ中的消息重发时间间隔和重发次数吗?

**ActiveMQ消息中间件面试专题解析拓展:**

![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://upload-images.jianshu.io/upload_images/24616006-fa79b1b15dde1ab5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* * *

# redis面试专题及答案

*   支持一致性哈希的客户端有哪些?
*   Redis与其余key-value存储有什么不一样?
*   Redis的内存占用状况怎么样?
*   都有哪些办法能够下降Redis的内存使用状况呢?
*   查看Redis使用状况及状态信息用什么命令?
*   Redis的内存用完了会发生什么?
*   Redis是单线程的,如何提升多核CPU的利用率?

![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://upload-images.jianshu.io/upload_images/24616006-e5ba4e8af4bdfc80.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* * *

# **Spring面试专题及答案**

*   谈谈你对 Spring 的理解
*   Spring 有哪些优势?
*   Spring 中的设计模式
*   怎样开启注解装配以及经常使用注解
*   简单介绍下 Spring bean 的生命周期

**Spring面试答案解析拓展**

![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://upload-images.jianshu.io/upload_images/24616006-a9d4433e066959fe.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* * *

# 高并发多线程面试专题

*   如今有线程 T一、T2 和 T3。你如何确保 T2 线程在 T1 以后执行,而且 T3 线程在 T2 以后执行?
*   Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优点?若是让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
*   Java 中 wait 和 sleep 方法有什么区别?
*   如何在 Java 中实现一个阻塞队列?
*   如何在 Java 中编写代码解决生产者消费者问题?
*   写一段死锁代码。你在 Java 中如何解决死锁?

**高并发多线程面试解析与拓展**

![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://upload-images.jianshu.io/upload_images/24616006-c4541cf1119c4aa8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

* * *

# jvm面试专题与解析

*   JVM 由哪些部分组成?
*   JVM 内存划分?
*   Java 的内存模型?
*   引用的分类?
*   GC何时开始?

**JVM面试专题解析与拓展!**

![BAT面试文档:ActiveMQ+redis+Spring+高并发多线程+JVM](https://upload-images.jianshu.io/upload_images/24616006-95f797046a7bbaaf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
相关文章
相关标签/搜索