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
## 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读取结果集的操做:  而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):
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语句:
而后修改测试类:
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消息中间件面试专题解析拓展:**  * * * # redis面试专题及答案 * 支持一致性哈希的客户端有哪些? * Redis与其余key-value存储有什么不一样? * Redis的内存占用状况怎么样? * 都有哪些办法能够下降Redis的内存使用状况呢? * 查看Redis使用状况及状态信息用什么命令? * Redis的内存用完了会发生什么? * Redis是单线程的,如何提升多核CPU的利用率?  * * * # **Spring面试专题及答案** * 谈谈你对 Spring 的理解 * Spring 有哪些优势? * Spring 中的设计模式 * 怎样开启注解装配以及经常使用注解 * 简单介绍下 Spring bean 的生命周期 **Spring面试答案解析拓展**  * * * # 高并发多线程面试专题 * 如今有线程 T一、T2 和 T3。你如何确保 T2 线程在 T1 以后执行,而且 T3 线程在 T2 以后执行? * Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优点?若是让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。 * Java 中 wait 和 sleep 方法有什么区别? * 如何在 Java 中实现一个阻塞队列? * 如何在 Java 中编写代码解决生产者消费者问题? * 写一段死锁代码。你在 Java 中如何解决死锁? **高并发多线程面试解析与拓展**  * * * # jvm面试专题与解析 * JVM 由哪些部分组成? * JVM 内存划分? * Java 的内存模型? * 引用的分类? * GC何时开始? **JVM面试专题解析与拓展!** 