MyBatis知识点总结(一)
前言:本篇主要记录在MyBatis学习过程中的主要知识点。
1.mybatis环境的搭建,通过maven可以快速的进行环境的搭建。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!--文件版本--> 2 <properties> 3 <mybatis.version>3.4.5</mybatis.version> 4 <junit.version>4.12</junit.version> 5 <mysql-driver.version>5.1.38</mysql-driver.version> 6 <log4j.version>1.2.17</log4j.version> 7 <slf4j.version>1.7.25</slf4j.version> 8 <mbg.version>1.3.6</mbg.version> 9 </properties> 10 11 <dependencies> 12 <dependency> 13 <groupId>org.mybatis</groupId> 14 <artifactId>mybatis</artifactId> 15 <version>${mybatis.version}</version> 16 </dependency> 17 18 <dependency> 19 <groupId>mysql</groupId> 20 <artifactId>mysql-connector-java</artifactId> 21 <version>${mysql-driver.version}</version> 22 </dependency> 23 24 <dependency> 25 <groupId>junit</groupId> 26 <artifactId>junit</artifactId> 27 <version>${junit.version}</version> 28 </dependency> 29 30 <dependency> 31 <groupId>log4j</groupId> 32 <artifactId>log4j</artifactId> 33 <version>${log4j.version}</version> 34 </dependency> 35 36 <dependency> 37 <groupId>org.slf4j</groupId> 38 <artifactId>slf4j-log4j12</artifactId> 39 <version>${slf4j.version}</version> 40 </dependency> 41 42 </dependencies> 43 44 <build> 45 <!--通过如下配置,解决找不到xml的异常--> 46 <resources> 47 <resource> 48 <directory>src/main/java</directory> 49 <includes> 50 <include>**/*.xml</include> 51 </includes> 52 <filtering>true</filtering> 53 </resource> 54 <resource> 55 <directory>src/main/resources</directory> 56 <includes> 57 <include>**/*.xml</include> 58 <include>**/*.properties</include> 59 </includes> 60 </resource> 61 </resources> 62 <plugins> 63 <plugin> 64 <!--Mybatis-generator插件,用于自动生成Mapper和POJO--> 65 <groupId>org.mybatis.generator</groupId> 66 <artifactId>mybatis-generator-maven-plugin</artifactId> 67 <version>${mbg.version}</version> 68 <configuration> 69 <!--配置文件的位置,注意文件路径的写法--> 70 <configurationFile>src/main/resources/mybatis-generator-config.xml</configurationFile> 71 <verbose>true</verbose> 72 <overwrite>true</overwrite> 73 </configuration> 74 <executions> 75 <execution> 76 <id>Generate MyBatis Artifacts</id> 77 <goals> 78 <goal>generate</goal> 79 </goals> 80 </execution> 81 </executions> 82 <dependencies> 83 <dependency> 84 <groupId>org.mybatis.generator</groupId> 85 <artifactId>mybatis-generator-core</artifactId> 86 <version>${mbg.version}</version> 87 </dependency> 88 </dependencies> 89 </plugin> 90 </plugins> 91 </build>
2.mybatis核心配置文件
mybatis的核心配置文件,位置与名称都不固定。
需要注意的是mybatis的核心配置文件的标签是有顺序的,如果顺序不对,会产生错误提示,可根据具体提示进行标签位置的调整。
mybatis核心配置文件主要配置如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 4 "http://mybatis.org/dtd/mybatis-3-config.dtd"> 5 <configuration> 6 <!--mybatis的标签是有顺序的,顺序不正确,会报错--> 7 <!--使用properties标签来引入外部properties配置文件的内容 8 resource:引入类路径下的资源 9 url:引入网络或者磁盘上的资源 10 --> 11 <properties resource="DataBaseConfig/db.properties"/> 12 13 <!--为了防止Oracle中插入null值报错,可以将jdbcTypeForNull,设置为NULL,mysql中是支持NULL和OTHER的--> 14 <settings> 15 <setting name="jdbcTypeForNull" value="NULL"/> 16 <!--以下两个属性配置后进行延迟加载--> 17 <setting name="lazyLoadingEnabled" value="true"/> 18 <setting name="aggressiveLazyLoading" value="false"/> 19 <setting name="cacheEnabled" value="true"/><!--开启二级缓存--> 20 </settings> 21 22 <!--别名处理器:typeAliases可以为java类型起别名--> 23 <typeAliases> 24 <!--别名不区分大小写--> 25 <!--type:指实体类的全类名;默认别名为类名小写 26 alias:新的名称--> 27 <!--typeAlias为单独一个实体类起别名 --> 28 <!--<typeAlias type="com.mybatisstudy.domain.User"/>--> 29 <!--package批量起别名 30 为某个包下的所有实体类对象起别名 31 name:指定包名,为包下及其子包下的实体类对象都起一个别名,默认类名的小写--> 32 <!--使用@Alias注解为冲突的类名,重新起一个别名,但是类名重复一般不存在--> 33 <package name="com.mybatisstudy.domain"/> 34 </typeAliases> 35 <!--与spring整合和,environments将被废除,由spring进行管理--> 36 <!--environments可以配置多种环境,必须有transactionManager和dataSource 37 可以通过environments的default属性,来快速的切换环境,所有可以配置多种环境--> 38 <environments default="development"> 39 <environment id="development"> 40 <!--使用jdbc管理事务,type有JDBC和MANAGED--> 41 <transactionManager type="JDBC"/> 42 <dataSource type="POOLED"> 43 <property name="driver" value="${jdbc.driver}"/> 44 <property name="url" value="${jdbc.url}"/> 45 <property name="username" value="${jdbc.username}"/> 46 <property name="password" value="${jdbc.password}"/> 47 </dataSource> 48 </environment> 49 </environments> 50 51 <!--databaseIdProvider:支持多数据库厂商--> 52 <databaseIdProvider type="DB_VENDOR"> 53 <!--为不同数据库起一个别名--> 54 <property name="MySQL" value="mysql"/> 55 </databaseIdProvider> 56 <!--mapper.xml文件一定要注册到全局配置文件中--> 57 <mappers> 58 <!--<mapper resource="com/mybatisstudy/sqlmap/UserMapper.xml"/>--> 59 60 <!--<mapper resource="com/mybatisstudy/sqlmap/UserMapper.xml"/>--> 61 <!--<mapper class="com.mybatisstudy.mapper.UserMapperAnotation"/>--> 62 <!--批量注册,sql映射文件和接口必须在同一包下,并且必须同名,但可通过小技巧进行转换--> 63 <package name="com.mybatisstudy.mapper"/> 64 </mappers> 65 </configuration>
3.关于sql映射文件
由于我们采用mapper接口式的编程,所以sql映射文件与mapper接口类的名称要相同,并且sql映射文件中namespace的值为对应mapper接口的全类名形式。
4.关于mybatis中的参数处理
对于mapper接口中单个参数,mybatis不会做特殊处理。可以通过#{参数名}进行取值操作。
对于mapper接口中的多个参数,mybatis会做特殊处理。多个参数会被mybatis封装成一个map,#{}就是从map中进行取值。
key的形式为:param1、param2......paramN的形式。
value:就是说要传入的值。
但是这种方式的可读性极差,因此可以采用命名参数的形式,通过@Param注解明确指定map中的key值。
如果多个参数正好是业务逻辑的数据模型,则可直接传入POJO,通过#{属性名}进行取值。
特别注意,如果参数为Collection(List,Set)类型或者是数组,mybatis也会特殊处理,mybatis也会把list或者数组封装在map中。
如果参数为Collection则map中的key为Collection(collection)。
如果参数为List,则map中的key可以直接使用list。
如果参数为数组,则map中的key为array。
5.关于mybatis的返回值和实体类字段与数据库字段不一致的问题
当mapper接口中某函数的返回值类型为List时,在其对应sql语句的resultType上直接写List集合的中元素的类型即可。
使用resultMap(自定义结果集映射规则),解决数据库字段和实体类属性不一致的情况。注意:resultMap和resultType只能二选一。
6.mybatis中的缓存机制
mybatis中默认定义了两级缓存,默认情况下一级缓存(本地缓存)开启。
一级缓存:在与数据库同一次会话期间的数据会放到一级缓存中,以后如果需要查询相同的数据,直接从缓存中取,不需要到数据中进行查询。
注意:一级缓存为sqlSession级别的缓存,一直都是开启的,不能关闭。
一级缓存失效的四种情况:
1)sqlSession不同,缓存失效。
2)sqlSession相同,查询条件不同,缓存失效,因为缓存中可能还没有相关数据。
3)sqlSession相同,在两次查询期间,执行了增删改操作,缓存失效。
4)sqlSession相同,但是手动清空了一级缓存,缓存失效。
二级缓存(全局缓存)需要进行配置,二级缓存是基于namespace级别的,一个namespace对应一个二级缓存。
二级缓存工作机制:
1)一个会话,查询一条数据,该数据会放在当前会话的一级缓存中。
2)如果当前会话关闭,对应的一级缓存会被保存到二级缓存中,新的会话查询信息,就可以参照二级缓存。
3)不同namespace查询出的数据会放在自己对应的缓存中。
注意:查出的数据都会默认放在一级缓存中,只有会话提交或关闭后,一级缓存的数据才会被转移到二级缓存中。
by Shawn Chen,2018.3.14日,晚。