1.全局配置文件
1.1.properties引入外部配置文件
- 作用:引入properties配置文件的内容
- 该节点中有两个属性
- resource :引入类路径下的资源
- url : 引入网络路径或者磁盘路径下的资源
示例
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>
<!-- 文件如果在某个包下就这样写 xxx/xxx/database.properties -->
<properties resource="database.properties"/>
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理-->
<transactionManager type="JDBC"/>
<!-- 数据库连接池-->
<dataSource type="POOLED">
<!-- ${properties 文件中的key} -->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
</configuration>
database.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/smbms?serverTimezone=UTC&
username=root
password=root
1.2.settings运行时行为设置
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。但是其大部分默认配置是不需要进行更改的,具体有哪些可以到官方文档查看settings
我们举一个个常用的setting
设置名 | 描述 | 默认 |
---|---|---|
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 | false |
logImpl
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
1.3.typeAliases别名
类型别名是为 Java 类型设置一个短的名字。 它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。例如:
<typeAliases>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
</typeAliases>
当这样配置时,Blog
可以用在任何使用 domain.blog.Blog
的地方。
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
每一个在包 domain.blog
中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author
的别名为 author
;若有注解,则别名为其注解值。见下面的例子:
@Alias("author")
public class Author {
...
}
注意:一些为常见的 Java 类型内建的相应的类型别名。它们都是不区分大小写的。
1.4. environments运行环境
- environments :环境们,mybatis可以配置多种环境,default指定使用某种环境,可以达到快速切换环境
- environment:配置一个具体的环境信息,必须有以下两个元素,id代表当前环境唯一标识
- dataSource:数据源,
- type :其有三种取值UNPOOLED | POOLED | JNDI
- 自定义数据源:实现DataSourceFactory接口即可,这个时候type的指就是自定义数据源的全类名
- transactionManager:事务管理器,
- type属性:其有两种取值 JDBC | MANAGED,其实这是两个别名,在org.apache.ibatis.session.Configuration类中,设置了大量的别名
- dataSource:数据源,
- environment:配置一个具体的环境信息,必须有以下两个元素,id代表当前环境唯一标识
1.5.mappers_sql映射注册
作用:将sql映射注册到全局配置中
- mappers
- mapper 注册一个sql映射
- resource 引用类路径下的sql映射文件
- url 引用网络路径或者磁盘路径下的sql映射文件
- file:///liao/mappers/UserMapper.xml
- class 使用注解开发时指定持久化层接口的全限定类名,没有映射文件
- 还有一种情况,你的映射文件和你的接口同名而且在同一包下,也可
- package
- name :包名 -批量注册
- 接口与映射文件必须同名且在同一个包内,才可生效,不满足的将主持失败
- name :包名 -批量注册
- mapper 注册一个sql映射
2.SQL映射文件
2.1.参数处理
2.1.1单个参数
如果仅仅是简单的一个单值传入,那么#{}表达式里面随便写什么都可以,只有一个参数,mybatis不会做特殊处理,就一个萝卜也就一个坑,没得选你传个什么参数,我都直接丢进#{}占位符就行了,没有任何逻辑,所有#{}表达式里随便写什么都没问题,但是建议要写有含义的名称
2.1.2多个参数
多个参数时,我们能想到的一定是,形参名是什么我们照样把它放在#{}中,但显然不行,现在是两个萝卜两个坑了,mybatis怎么知道你的萝卜要放那个坑呢,最终会抛出异常:
org.apache.ibatis.binding.BindingException:Parameter ‘XX’ not found. Available parameters are [1 , 0 , param1,param2]
多个参数时,mybatis会做特殊处理,多个参数会被封装成一个map,而#{}就是从map中获取指定key的值,它的key也是有规则的:param1 …paramN;value就是我们传入的值所有我们可以 #{param1}这么取值,写#{0}啊#{1}也行这是参数的索引从0开始
2.1.2.1.命名参数
这么取值虽然可行,但是看着不那么优雅是吧,其实还有解决方案:
命名参数:明确指定封装参数时map的key:@Param(“xxx”)
int updatePwd(@Param("id") Integer id, @Param("userPassword") String pwd);
这个时候我们直接#{id},#{userPassword}即可取出对应参数值
注意:即使我们给参数指定了命名,但是param1…paramN仍然有效
2.1.2.2.POJO
如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo
#{属性名},就能取出传入的pojo的属性值
2.1.2.3.Map
如果多个参数不是业务模型中的数据,没有对应的pojo,不经常使用,为了方便我们也可以传入map,因为它最终都会把多个参数封装成一个map,所有我们可以直接传入一个map,这样key值就是我们自己定义
2.1.2.4.(Transfer Object)TO
如果多个参数不是业务模型中的数据,但是经常要使用,推荐来编写一个TO(Transfer Object)数据传输对象,比如分页对象Page
2.1.3.单个javaBean
单个javaBean取值就用属性名称取值即可 #{属性名},这个时候使用#{param1}就不可取了,将会抛出异常
org.apache.ibatis.refiection.ReflectionException:There is no getter for property named 'param1' in 'class xxx.xxx.xxx'
这就说明mybatis是通过javaBean属性的get方法来取得值的
2.1.4.Map
就是按照key的名称取值
2.1.5.多个javaBean
可以使用param1.属性名…paramN.属性名
可以使用参数命名注解@param(""),就使用指定的名字.属性名
2.1.6.Collection
如果是Collection类型或者是数组,也会特殊处理,也是把传入的list或者数组封装在map中,如果是List 那么可以使用key(list)、数组(array);你用param1也取不出,即使是单个参数也不行
2.2.使用resultMap实现高级映射
2.2.1.resultMap的基本配置项
-
属性
- id:resultMap的唯一标识
- type:表示该resultMap的映射结果类型(通常是java实体类)
-
子节点
-
id:一般对应数据库中该行的主键id,设置此项可以提升Mybatis性能
-
result:映射到javaBean的某个"简单类型"属性,如基础数据类型、包装类等
子节点id和result均可实现最基本的结果集映射,将列映射到简单数据类型的属性。这两者唯一不同的是:在比较对象实例时id将作为结果集的标识属性。这有助于提高总体性能,特别是应用缓存和嵌套结果映射的时候。而若要实现高级结果映射,就需要使用下面两个配置项:association和 collection
-
2.2.2.association(一对一)
简介:association映射到javaBean的某个"复杂类型"属性,比如javaBean类,即javaBean内部嵌套一个复杂数据类型(javaBean)属性,这种情况就属于复杂类型的关联。但是需要注意:association只能处理一对一的关联关系
示例:一个user(用户)对应一个role(角色)[一般用户是可以拥有多个角色的,这里只是演示],就用它俩来演示一下,只是演示一下就不要在意实体类属性的完整性了
数据表:
- User表
- id int
- userName varchar
- userPassword varchar
- roleId int
- Role表
- id int
- roleName varchar
定义User实体类
package cn.liao.pojo;
import lombok.Data;
/**
* @author liao
* @describe User表实体类
*/
@Data
public class User {
/**
* id
*/
private Integer id;
/**
* 用户姓名
*/
private String userName;
/**
* 用户密码
*/
private String userPassword;
/**
* 角色
*/
private Role role;
定义角色实体类
package cn.liao.pojo;
import lombok.Data;
import java.util.Date;
/**
* @author liao
* @describe 角色表对于实体类
*/
@Data
public class Role {
/**
* id
*/
private Integer id;
/**
* 角色名称
*/
private String roleName;
/**
* 对应userId
*/
private Integer userId;
}
使用子查询
定义接口
public interface RoleMapper {
Role findRoleByUserId(Integer userId);
}
public interface UserMapper {
user