Mybatis框架
简介
定义一个Mapper接口,定义一个与接口同名的Mapper.xml,xml文件相当于是Mapper接口的实现。xml文件定义与数据库交互的sql语句。Mapper接口供外部调用。
com.mysql.jdbc.Driver 和 com.mysql.cj.jdbc.Driver 的区别?
com.mysql.jdbc.Driver 是 mysql-connector-java 5中的,
com.mysql.cj.jdbc.Driver 是 mysql-connector-java 6以及以上中的
Java集成Mybatis,搭建环境
XML方式配置
常用标签
- <select>:用于配置select语句
- <insert>用于配置insert语句
- <update>用于配置update语句
- <delete>用于配置delete语句
- <resultMap>:用于配置结果映射集
- <result>:resultMap中的元素,表示列与属性的映射
- <id>:resultMap中的元素,表示id列与属性的映射
- <selectKey>:用于配置返回主键
动态SQL常用标签
1. <if>
if标签用于判断条件是否达成,动态生成sql。它有一个必填的属性test,test内设置一个符合OGNL要求的判断表达式,表达式结果可以是true或false。此外所有的非0值都为true,只有0为false。但推荐使用true和false。若为true,则拼接标签内的sql。若为false,则不拼接。
2. <choose>
<choose>用于实现if...else...的条件判断,它包含<when>和<otherwise>两个标签。一个<choose>至少包含一个<when>,包含0个或一个<otherwise>。<when>标签包含必填的test属性,用于设置判断表达式。
3. <where>
<where>标签的作用:如果该标签有返回值,则插入一个where。如果where后面有and或or,则将它们删除。
<select id="getSysUserByUserNameOrUserEmail" resultMap="SysUserDto">SELECT id, user_name, user_password, user_email, user_info, head_img, create_time FROM sys_user
<where>
<if test="userName!=null and userName!=''">and user_name = #{userName}</if>
<if test="userEmail!=null and userEmail!=''">and user_email=#{userEmail}</if>
</where>
</select>4. <set>
<set>标签的作用:如果该标签有返回值,则插入一个set。如果set后面又字符串已逗号结尾,则将这个逗号删除
5. <trim>
<trim>有4个属性,可以替代<where>和<set>的功能。
prefix:标签有返回值时添加指定的前缀。prefixOverrides:标签返回值包含指定前缀内容时,删除前缀内容。suffix:标签有返回值时添加指定的后缀。suffixOverrides:标签返回值包含指定后缀内容时,删除后缀内容。
6. <foreach>
<foreach>标签用于遍历实现了Iterable接口的对象,分List和Map两种情况。
colletction:必填。指定传入的集合的名称。推荐使用@Param指定参数的名称,然后配置到这个属性。item:迭代对象的变量名,sql中使用。index:迭代对象的索引,sql中使用。List时为索引值,Map时为key。open:整个循环的内容以指定字符开头。close:整个循环的内容以指定字符结尾。separator:每次循环内容间的分隔符
7. <bind>
使用<bind>可以创建一个OGNL表达式,在需要的地方以变量的形式使用。
多数据库支持
在mybatis-config.xml文件中加入<databaseIdProvider>配置,在标签下添加属性设置数据库别名。
- 在mapper映射文件中,使用
databaseId属性标识sql对应的数据库类型,使mybatis动态生成对应的sql语句。 - 或在
<if>标签内使用默认的上下文参数_databaseId判断数据库类型,动态生成sql
OGNL用法
实体类
在java中,基本类型会有默认值,比如某个类包含一个int类型的字段,在类实例化后,该字段默认会赋值为0,无法实现赋值为null。在使用动态sql时,判断字段是否为null,总是会返回true。所以实体类中的字段不要使用基本类型,而是使用包装类。基本类型包括byte、short、int、long、float、double、char。
jdbcType
用于设置传入参数的jdbc类型。类型枚举值为org.apache.ibatis.type.JdbcType。
insert语句获取主键的两种方式
1. useGeneratedKeys="true" keyProperty="id"
- 使用
useGeneratedKeys开启获取数据库主键功能,keyProperty将主键返回到id属性上。 - 这种方式仅适用于有主键自增功能的数据库,如Mysql
2. <selectKey>+select last_insert_id()
使用<selectKey>标签配置获取主键功能。
-- Mysql
<selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">select last_insert_id()</selectKey>
-- Oracle
<selectKey keyColumn="id" resultType="long" keyProperty="id" order="BEFORE">select SQE_ID.nextval from dual</selectKey>keyColumn="id":指定数据库主键列resultType="long":设置返回值类型keyProperty="id":设置java类字段属性order="AFTER":指定排序关系。mysql为AFTER,oracle为BEFORE。mysql先插入行数据后生成主键,oracle先从序列生成主键,再插入行数据。
这种方式适用于有主键自增功能的数据库,也适用于没有主键自增功能的数据库
sql参数与@Param
Mybatis根据接口参数的位置为我们自定义了传入sql语句的参数的名称。如接口中定义了两位参数,则Mybatis为我们自定义参数名称为Available parameters are [arg1, arg0, param1, param2],在sql语句中我们通过#{arg0}来使用参数。
List<SysUserDto> getSysUserByIdAndUserName(Long id, String userName);一般情况下,为了更清晰反映接口参数与sql参数的关系,推荐使用@Param注解接口参数并提供名称,自定义sql参数的名称。
注解方式配置
- @Insert
- @Update
- @Select
- @Delete
- @Options
- @Result
- @SelectKey
- @SelectProvider
- @InsertProvider
- @UpdateProvider
- @DeleteProvider
代码生成器
MBG-MyBatis Generator、
- generatorConfiguration标签:mgn配置文件的根标签
- properties标签:generatorConfiguration标签的子标签,用于读取外部配置文件。在xml中使用${property}的形式引用属性。可选配置。
- classPathEntry:指定类路径。或指定rootClass属性配置类所在的包。可选配置。
- context:必须配置。指定生成一组对象的环境。例如要连接的数据库,要生成对象的类型和要处理的数据库中的表。
context包含的标签
- property:可配置0个或多个,用于设置一些基础的属性,比如分隔符、文件编码等。
- plugin:可配置0个或多个,用于配置mbg插件。
- commenGenerator:可配置0个或1个,用于配置实体类注释内容。
- jdbcConnection:配置1个,配置jdbc连接配置
- javaTypeResolver:可配置0个或1个,用于配置类型解析器,用于jdbc类型与java类型间的映射。
- javaModelGenerator:配置1个,用于配置实体类生成规则。
- sqlMapGenerator:可配置0个或1个,用于配置xml文件生成规则。
- javaClientGenerator:可配置0个或1个,用于配置mapper接口生成规则。
- table:配置1个或多个,用于指定需要自动生成代码的数据库表。
MBG的使用
- 引入依赖
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.1</version>
</dependency>- 编写生成器配置文件,添加文件到resource目录下。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="MysqlContext" targetRuntime="MyBatis3Simple" defaultModelType="flat">
<property name="beginningDelimiter" value="'"/>
<property name="endingDelimiter" value="'"/>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/mybatis"
userId="mybatis" password="123456"></jdbcConnection>
<!--实体类\dao层-->
<javaModelGenerator targetPackage="com.chenzhuowen.mybatisgeneratorstudy.dao"
targetProject="mybatis-generator-study\src\main\java"></javaModelGenerator>
<!--xml映射文件-->
<sqlMapGenerator targetPackage="mapper\"
targetProject="mybatis-generator-study\src\main\resources"></sqlMapGenerator>
<!--mapper接口-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.chenzhuowen.mybatisgeneratorstudy.mapper"
targetProject="mybatis-generator-study\src\main\java"></javaClientGenerator>
<table tableName="%" schema="mybatis" catalog="mybatis">
</table> </context></generatorConfiguration>- java程序读取配置文件,运行代码生成器,根据配置文件生成代码。
public class Generator {
public static void main(String[] args) throws XMLParserException, IOException, InvalidConfigurationException, SQLException, InterruptedException {
InputStream is = Generator.class.getResourceAsStream("/generatorConfig.xml");
List<String> warnings = new ArrayList<String>();
ConfigurationParser configurationParser = new ConfigurationParser(warnings);
Configuration configuration = configurationParser.parseConfiguration(is);
is.close();
DefaultShellCallback defaultShellCallback = new DefaultShellCallback(true);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(configuration, defaultShellCallback, warnings);
myBatisGenerator.generate(null);
for (String warning : warnings
) {
System.out.println(warning);
}
}
}高级查询
一对一
映射方式:
- 使用别名将查询结果映射到嵌套对象的属性。
- 使用<resultMap>映射标签,将查询结果与嵌套对象的属性映射。<resultMap>支持继承,使用extends属性指定要继承的resutlMap的id值。支持使用全限定名引用其他映射文件中的<resultMap>。
- 使用<association>实现一对一映射。
<association>的使用场景分以下两种情况:
执行一次sql查询所有信息(关联的嵌套结果映射)
这种情况下如果表关联关系比较多,会造成sql编写比较复杂,但是简便。适合sql查询效率本身就较高的情况。包括以下属性:
- property:关联的属性名称
- columnPrefix:使用列前缀模式模式关联时,设置列名前缀。在子标签中配置result的colum时,可以省略前缀。
- javaType:属性对应的java实体类
- resultMap:可以直接使用现有的resultMap,而不需要再配置result子标签。
执行多次sql,将查询结果组合成对象(关联的嵌套查询)
通过多个简单sql的查询结果转换成我们需要的对象。适合sql关联关系非常复杂,对性能有高要求的场景。包括以下属性:
- select:映射查询的id
- column:列名,将主查询中的列的结果作为嵌套查询的参数,配置方式为
colunm={prop1=col1,prop2=col2} - fetchType:数据加载方式,分为lazy(延迟加载)和eager(提前加载)。当配置为lazy时,关联查询sql只会在通过主对象获取关联信息时执行sql。
一对多
<collection>
属性、前缀、类型、重复判断、多层嵌套、集合的嵌套结果映射、集合的嵌套查询
执行一次sql查询所有信息(集合的嵌套结果映射)
使用以下属性定义:
- property:关联的集合的属性名称
- columnPrefix:定义匹配的列的前缀
- ofType:集合关联的java类型。使用ofType,需要添加id、result子标签映射对象属性与结果列。
- resultMap:引用resultMap。使用ofType和resultMap不可同时使用。
执行多次sql,将查询结果组合成对象(集合的嵌套查询)
使用以下属性定义:
- select:映射查询的id
- column:列名,将主查询中的列的结果作为嵌套查询的参数,配置方式为
colunm={prop1=col1,prop2=col2} - fetchType:数据加载方式,分为lazy(延迟加载)和eager(提前加载)。当配置为lazy时,关联查询sql只会在通过主对象获取关联信息时执行sql。
<resultMap id="SysUserDto" type="com.chenzhuowen.mybatisstudy.dto.SysUserDto">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="userPassword" column="user_password"/>
<result property="userEmail" column="user_email"/>
<result property="userInfo" column="user_info"/>
<result property="headImg" column="head_img"/>
<result property="createTime" column="create_time"/>
<collection property="sysRoleDtoList" column="{userId=id}" fetchType="lazy"
select="com.chenzhuowen.mybatisstudy.mapper.SysRoleMapper.selectUserRoleByUserId"
/>
</resultMap>鉴别器<discriminator>
鉴别器可以根据查询结果列的不同的值,使用不同的映射集合。
包含以下属性:
- <column>:该属性用于设置要进行比较值的列
- <javaType>:该属性用于指定列的类型,保证使用相同的java类型比较值
<discriminator>可以有一个或多个<case>标签,<case>标签包含以下属性:
- <value>:指定column用来匹配的值
- <resultMap>:当列的值与value匹配时,配置使用的resultMap。resultMap优先级比resultType高。
- <resultType>:当列的值与value匹配时,配置使用的resultMap
存储过程
使用<select>标签,属性statementType设置为CALLABLE,实现存储过程的调用。
配置resultMap可将存储过程中的返回值映射到java对象。
存储过程的参数按如下设置:
#{id,mode=IN,jdbcType=BIGINT,javaType=java.lang.Interger}- 入参时
mode=IN,出参为mode=OUT,入出参为mode=INOUT。 - 出参时必须设置jdbcType。若使用LocalDateTime,还需要将javaType置为
javaType=java.time.LocalDateTime。
存储过程对应的java接口的方法的参数可以传入一个变量并用@Param注解、javabean或map集合。
缓存
Mybatis拥有两级缓存,一级缓存由Mybatis控制,二级缓存可以由用户去控制。
一级缓存
Mybatis的一级缓存存在于sqlSession的生命周期中。
在同一个sqlSession中执行查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对象中。当Map缓存对象中已经存在相同的键值,则会返回缓存中的结果。
若不想在select中启用一级缓存,可以在select标签中添加flushCache="true"属性。配置后,每次查询前会清空当前的一级缓存。
需要注意的时,任何的INSERT、UPDATE、DELETE语句,都会清空当前的一级缓存。
二级缓存
Mybatis的二级缓存存在于SqlSessionFactory的生命周期中,且和命名空间绑定。
配置二级缓存
Mybatis的全局配置settings中由一个参数cacheEnabled,这个参数是二级缓存的全局开关,默认为true,初始状态为开启。如果把这个参数设置为false,即使后面有二级缓存的配置,也不会生效。我们也可以在mybatis-config.xml文件中显式配置它。
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>Mapper.xml中配置二级缓存
Mybatis的二级缓存是和命名空间绑定,即需要配置在Mapper.xml映射文件中。
在xml文件中添加<cache/>元素即可。添加之后会有以下默认效果:
- 映射文件中的所有SELECT语句将会被缓存
- INSERT、UPDATE、DELETE语句会刷新缓存
- 缓存使用LRU算法回收缓存
- 缓存不会以任何时间顺序来刷新
- 缓存集合可以存储1024个引用
- 缓存会被视为可读/可写的,每次调用会通过序列化返回一个副本。
二级缓存有以下属性可以调整:
- eviction:配置回收策略,包括LRU、FIFO、SOFT、WEAK
- flushInterval:刷新间隔,单位为毫米
- size:引用数目
- readonly:是否只读。默认为false。false时表示可读可写,会通过序列化返回缓存对象的拷贝。true表示只读,返回同一个对象,若对对象修改,会不安全。
xml例子:
<mapper namespace="com.chenzhuowen.mybatisstudy.mapper.SysUserMapper">
<cache eviction="FIFO"
flushInterval="6000"
readOnly="false"
size="512"/>
</mapper>注解例子:
@CacheNamespace(eviction = FifoCache.class,
flushInterval = 6000L,
size = 512,
readWrite = true)
public interface SysUserMapper {
//接口方法
}xml文件和java接口,不能同时配置缓存配置。可以使用<cache-ref>或@CahcheNamespaceRef参照缓存配置。
Mybatis保存查询结果到二级缓存的时机
使用二级缓存时,当调用close方法关闭SqlSession时,SqlSession才会保存查询数据到二级缓存中,在这之后二级缓存才有缓存数据。
缓存总结
一级缓存,Mybatis默认启用,有效时间在SqlSession的生命周期内,调用查询后Mybatis就把查询结果缓存到缓存集合中,执行相同的调用,会返回相同的对象实例。
二级缓存,需要在映射文件中配置,配置后开启,有效时间在SqlSessionFactory生命周期内,执行SqlSession的close()方法时将缓存保存到缓存集合中。根据readonly的值采用不用的缓存保存和获取机制,默认为false。当false时,保存和获取查询结果的副本。当为true时,保存和获取查询结果对象的引用。
Mybatis集成第三方缓存
集成EhCache缓存
EhCache是一个纯java进程内的缓存框架,具有快速、精干等特点。
使用步骤
- 在Maven中引入依赖
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.3</version>
</dependency>- 在resources目录下添加EhCache.xml配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://www.ehcache.org/ehcache.xsd"
updateCheck="false" monitoring="autodetect"
dynamicConfig="true">
<diskStore path="./cache"/>
<!-- 默认的cache配置-->
<defaultCache maxElementsInMemory="3000"
eternal="false"
copyOnRead="true"
copyOnWrite="true"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="true"
diskPersistent="true"
/>
<!-- 对name指定的mapper文件有效的缓存配置-->
<cache name="com.chenzhuowen.mybatisstudy.mapper.SysUserMapper"
maxElementsInMemory="3000"
eternal="false"
copyOnRead="false"
copyOnWrite="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
overflowToDisk="true"
diskPersistent="true"
/>
</ehcache>copyOnRead、copyOnWrite属性与readOnly属性的功能相似。当设置为true时,表示使用可读写缓存,返回缓存对象的副本。当设置为false时,表示使用只读缓存,返回缓存对象的引用。 3. 修改mapper.xml文件中的cache标签的type属性,指向EhCache缓存。
<cache
type="org.mybatis.caches.ehcache.EhcacheCache"/>当配置type属性为使用Ehcache时,cache标签的其实属性都不会起到任何作用,针对缓存的配置都在ehcache.xml中进行。
集成Redis缓存
Redis是一个高性能的基于内存的key-value数据库。
使用步骤
- 在Maven中引入依赖
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-redis</artifactId>
<version>1.0.0-beta2</version>
</dependency>- 在resources目录下新增redis.properties文件。
host=127.0.0.1
port=6379
connectionTimeout=5000
soTimeout=5000
password=123456
database=0
clientName=- 修改mapper.xml文件中的cache标签的type属性,指向redis缓存。
<cache type="org.mybatis.caches.redis.RedisCache"/>RedisCache在保存缓存数据和获取缓存数据时,使用java的序列化和反序列化,因此需要保证缓存对象实现了Serializable接口。
在redis中保存的是一个以mapper命名空间为key的hash。hash的filed是执行的查询方法与参数,value是查询的结果。
脏数据
什么情况下会出现脏数据?
一个命名空间中的查询语句关联了多个不同的表,其查询结果只会缓存在这个命名空间下。如果有在其他命名空间中修改了某个表中的数据,因为命名空间不同,不会对命名空间刷新缓存。这时重新执行查询,会使用缓存中数据,而不是数据库中最新的数据。
插件开发
Mybatis允许拦截的接口及方法
- Executor(update、query、flushStatements、commit、rollback、getTransaction、close、isClosed)
- ParameterHandler(getParameterObject、setParameters)
- ResultSetHandler(handleResultSets、handleCursorResultSets、handleOutputParameters)
- StatementHandler(Prepare、parameterize、batch、update、query)
Mybatis拦截器
Interceptor接口
Mybatis提供了接口Interceptor(org.apache.ibatis.plugin.Interceptor)实现拦截器功能。
public interface Interceptor {
Object intercept(Invocation invocation) throws Throwable;
default Object plugin(Object target) {
return Plugin.wrap(target, this);
}
default void setProperties(Properties properties) {
// NOP
}
}Mybatis使用动态代理机制实现拦截器功能。若有多个拦截器时,会遍历所有拦截器,并层层代理。
- intercept()方法是主要实现自定义拦截器功能的方法,入参invoation可以获得很多有用信息,如:调用对象、调用方法、入参等。调用invocation.proceed()将执行被拦截对象真正的方法。
- setProperties()方法主要用于获取从mybats-config.xml文件中设置的属性。
- plugin()方法会自动判断拦截器的签名和被拦截对象的接口是否匹配,固定写法。
拦截器签名
拦截器签名用于指定拦截器要拦截的对象和方法,使用@Intercepts注解拦截器实现类。@Intercepts注解中的属性时一个一个@Signature注解数组。@Signature注解指定要拦截的接口、接口的方法、接口的参数类型。
@Intercepts({@Signature(type = Executor.class,
method = "query",
args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
public class MyInterceptor implements Interceptor {
//实现Interceptor的方法
}如上签名例子表示这个拦截器将会拦截Executor类的带有MappedStatement类和Object类参数的update()方法。
将拦截器配置到mybatis-config.xml文件中
实现了自定义拦截器后还需要向mybatis注册
<plugins>
<plugin interceptor="com.chenzhuowen.mybatisstudy.interceptor.MyInterceptor">
<property name="prop1" value="value1"/>
<property name="prop2" value="value2"/>
</plugin></plugins>- interceptor:该属性指定拦截器实现类的全限定名称
- property:该标签用于配置参数,在接口的setProperty()方法中可以获取参数值。
Spring集成Mybatis
参照Spring项目搭建手册搭建Spring项目,然后进行Mybatis的集成。
1. 添加Spring和Mybatis依赖
<!--提供jdbc连接驱动-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<!--事务-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<!--spring对mybatis支持-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!--mybatis核心-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.11</version>
</dependency>
<!--mysql jdbc驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>2. 在Spring配置文件applicationContext.xml中配置Mybatis信息
2.1 配置mybatis数据源
在applicaitonContext中配置mybatis数据源连接池bean,将连接池注册到容器中,这个是必须设置的。
<!--mybatis核心包下的类-->
<bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="mybatis_test"/>
<property name="password" value="123456"/>
</bean>2.2 配置SqlSessionFactoryBean
在applicaitonContext中配置SqlSessionFactoryBean
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="mybatis-config.xml"/>
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations">
<array>
<value>classpath:mapper/*.xml</value>
</array>
</property>
</bean>- SqlSessionFactoryBean是SqlSessionFactory的工厂类。
- 属性configLocation指定了mybatis的配置文件路径。
- 属性dataSource使用引用,引用mybatis连接池bean。
- 属性mapperLocations是一个数组,指定mapper.xml映射文件路径。
2.3 添加mybatis配置文件mybatis-config.xml
在src/main/resource下添加mybatis配置文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--这里指定使用Log4j输出mybatis日志。如果需要日志功能,还需要参照前面日志部分内容,添加相关依赖以及日志配置文件-->
<setting name="logImpl" value="Log4j"/>
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>2.4 配置MapperScannerConfigurer
在application中配置MapperScannerConfigurer,用于扫描并注册Mapper接口到容器中,使用时可以直接注入接口。
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.chenzhuowen.springstudy.mapper"/>
<property name="annotationClass" value="org.apache.ibatis.annotations.Mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>- basePackage:用于配置基本的包路径。如有多个,可使用分号或逗号分隔。
- annotationClass:用于过滤被扫描的接口,只有包含该注解的接口才会被扫描。
到此Spring集成Mybatis就完成了,剩下的工作就是编写mapper.xml、添加mapper接口以及通过mvc使用他们。
Spring boot集成Mybatis
1. 添加相关依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>- 在Springboot配置文件application.properties中添加数据库信息
##配置数据源
spring.datasource.url=jdbc:mysql://43.136.117.138:3306/mybatis
spring.datasource.username=mybatis
spring.datasource.password=123456- 在Springboot配置文件applicaiton.properties中添加mybatis配置
##配置mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
mybatis.config-location=classpath:mybatis.xml- 使用@Mapper注解Mapper接口,或使用@MapperScan注解扫描指定包下的Mapper接口。
到此Springboot集成Mybatis就完成了,剩下的工作就是编写mapper.xml、添加mapper接口以及通过mvc使用他们。
基于数据库的开发流程
- 定义数据库表。
- 定义java实体类。
- 定义mapper接口,定义好需要的接口方法。
- 根据接口方法,编写mapper.xml文件。
- 定义test文件,测试mapper。
- 定义service,service中注入mapper,调用mapper。
- 定义controller,controller中注入service,调用service。
分页插件PageHelper
SpringBoot项目使用方式
- 引入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version>
</dependency>- 在Mapper接口方法调用前,调用PageHelper的静态方法。
@Override
public List<Country> selectAllPage(int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
//或用offsetPage
//PageHelper.offsetPage(0,2);
List<Country> countries = countryMapper.selectAll();
return countries;
}PageHelper提供了两种分页方式:startPage和offsetPage,区别如下:
PageHelper.startPage(int pageNum, int pageSize):PageHelper.startPage(1, 10);表示查询第一页,每页10条记录。PageHelper.offsetPage(int offset, int limit):PageHelper.offsetPage(0, 10);表示查询第一页,每页10条记录。