MyBatis学习笔记

MyBatis主配置文件

1. Properties

可以通过resource属性指定properties配置文件,而后,在配置文件中可以通过${}的方式访问properties里的数据

2. Settings

可以通过setting标签来设置属性。
例:
下面的配置可以将数据库中的下划线式命名法映射到POJO类的驼峰命名法。


---------------------------------------------------------------------------------------
效果:
last_name ===> lastName
3. typeAliases

可以通过配置来给类的的全类名取别名
配置别名的两种方式:

  1. 通过typeAlias标签:

alias标签可以省略,若没设置alias属性的话,则别名默认为类名

  1. 通过package标签:

指定包名里的所有类都会被设置默认别名,可能出现的问题是,如果指定包里存在着全类名不同但类名相同的类,使用别名时会出现冲突
此时可以使用@Alias注解来为需要的类配置新的别名,从而解决冲突

PS:别名不区分大小写
PS2:mybatis内置别名

别名 类型
_byte byte
_short short
_int int
_integer int
_long long
_float float
_double double
_boolean boolean
string String
byte Byte
short Short
int Integer
integer Integer
long Long
float Float
double Double
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
map Map
typeHandler

类型处理器:将数据库的数据类型与Java的数据类型一一对应,mybatis3.4以后就自带处理了,这里就不多学了。

plugins

插件

environments

环境标签,可以通过environment来配置一个具体的环境。在存在多个不同的环境时,可以通过environments的default属性来指定所使用的环境。
environment标签中,有两个标签
transactionManager:事务管理器
    type:事务管理器的类型
可选值有JDBC(JdbcTransactionFactory)和MANAGED(ManagedTransactionFactory)
实际上这两个都是实现了TransactionFactory接口的类,通过实现TransactionFactory接口,也可以做到自定义事务管理器,此时type指定为类的全类名。

dataSource:数据源
    type:数据源类型
可选值有UNPOOLED(UnpooledDataSourceFactory),POOLED(PooledDataSourceFactory),JNDI(JndiDataSourceFactory)。实质上是实现了DataSourceFactory接口的类。


        
            
            
                
                
                
                
            
        
        
            
            
        
    
databaseIdProvider

作用:为sql语句选择使用的数据库,实现了多厂商支持
type:获得各数据库厂商的标识,例如MySQL,Oracle,SQL Server
property子标签可以给这些标识加上别名,然后在编写sql语句的时候就可以在属性指定databaseId这一属性。

    
        
        
        
    
=======================================================
用例:
    
mappers

作用:将写好的sql映射文件注册到mybatis配置文件。
注册映射文件的方法:

  1. 通过mapper标签:
  • resource:类路径
  • url:网络路径或磁盘路径
  • class:对应接口的路径
    PS:使用class属性时,必须要有与接口对应的sql映射文件,而且必须和接口放在同一目录下。
  1. 通过package标签:
    name:指定包名,批量注册指定包里的所有接口
  2. 不写映射文件,直接通过注解完成sql语句。

PS:如果通过mapper标签的class属性或者通过package标签来注册,同时又想实现接口和映射文件分离,那么可以通过在项目的资源目录resouces下创建和接口相同的包名,用来存放映射文件。这样做的原理是,这两个目录所指向的其实是同一个目录。

映射文件

增删改
  1. mybatis允许增删改定义以下返回值
    int,long,boolean(基础类型、包装类)
  2. 可以不写parameterType
    但是写了可以限制传入的参数。
  3. 如果使用无参的openSession(),增删改操作时,需要手动提交。
  4. 获取自增主键的值
    插入命令时,可以通过将useGeneratedKeys的值设为true,并且用keyProperty来指定用来返回主键值的JavaBean的一个属性。
参数处理
  1. 当传入一个参数时,mybatis不会对参数进行处理。
    因此不管#{}里面填的是什么,都能取到唯一的参数

  2. 当传入多个参数时,mybatis会将参数封装成map,如果不指定key的话,则map默认的key值为param1.....paramN,value值则为传入的参数值。
    因此取值的时候可以通过#{默认的key值}或者#{索引}来找到对应的值。
    但是也可以通过@param("设定的key")来给map设定key值。
    用例:

User seleceByIdAndName(@Param("userId") int id, @Param("lastName") String name);
  1. 如果传入的多个参数正好是业务逻辑的模型,可以将这些参数封装成一个POJO对象传入

  2. 如果传入的多个参数不是业务逻辑的模型,且使用频率不高时,可以构造一个map

  3. 如果传入的多个参数不是业务逻辑的模型,但是使用频率很高时,可以编写TO(Transfer Object)数据传输对象。
    Page {
    int page;
    int index;
    }

  4. 当传入的是Collection、List或者Array数组时:
    Collection使用collection
    List使用list、collection
    Array使用array
    这几个并不能使用通用的param1等

mybatis封装参数的过程。
  • 判断参数的数量,如果为参数为0直接返回。
#{}和${}的区别

两者都是用来获取map中的值或者是POJO类中的属性。
#{}采用预编译的方式,将里面的值设置到sql语句中,类似于PreparedStatement。
${}采用字符串拼接的方式,将里面的值与sql语句进行拼接,有安全问题。

如果遇到原生JDBC都不支持占位符的情况下
比如分表,表名,排序。

select * from ${year}_salary;
select * from ${table_name};

这种情况下只能只用${}

通常情况下#{}比${}要安全,能用#{}的情况下选择用#{}

#{}在取值的时候还能加上其他参数,这里暂时先不学了。

返回值处理

通过resultType来指定返回值的类型

  1. 返回值是List
    此时resultType应该指定的是List中元素的类型,mybatis会把每一条记录封装成user对象,然后返回集合。
  2. 返回类型为Map
    此时resultType是map,mybatis把记录拆成键值的方式封装在map里
  3. 返回类型是Map
    此时resultType应指定为User,因为mybatis是要将记录封装在User对象中,但是如果只指定了resultType,在运行时会报错,报错信息为:
Expected one result (or null) to be returned by selectOne(), but found: 2

需要返回的参数超出了mybatis能返回的数量,这时可以通过@MapKey来给接口中的方法打上注解,可以将JavaBean中的一个属性设定为另一个参数。

自定义返回类型

resultMap:不能和resultType同时使用,自定义封装规则

  • type:指定自定义规则的JavaBean
  • id:该resultMap的唯一标识符
    子标签:
  • :添加主键的映射
  • :添加其他字段的映射
    用column属性指定数据库中的字段,property属性指定JavaBean中的成员。
    id也可以用result替代,但是id的优化优于result
    字段与JavaBean中成员名相同的,可以不进行映射。

当一个类中包含其他类的引用时,使用级联属性封装结果集

JavaBean(省略成员方法):
======================================
public class User {
    private Integer userId;
    private String lastName;
    private String sex;
    private Integer age;
    private Class aClass;
}
public class Class {
    private int id;
    private String className;
}
映射文件:
======================================

  
  
  


这里将d_id字段的值交给了aClass的id属性,class_name交给了className属性。

当一个类中包含其他类的引用时,使用Association封装结果集
JavaBean同上,映射文件改为:


    
    
    
    
    
        
        
    


association:

  • property中的是JavaBean中被选为Association的属性,这里是aClass
  • javaType中的是该属性的Java类型。

这里不把其他字段映射的话,获取不到值

使用association进行分步查询
步骤:

  1. 通过传入的userId值来获得user的详细信息
  2. 通过user信息中d_id来查询班级信息
  3. 将班级信息封装给user的aClass属性

    
    
    


association中:

  • select属性指定了要执行的查询语句
  • column指定了执行语句所需的参数

分布查询的延迟加载:
仅当关联的属性被使用时,才执行分步的查询语句。
通过在mybatis配置文件中配置lazyLoadingEnabled和aggressiveLazyLoading属性。

该项设为true时,启动延迟加载

该项设为true时,在延迟加载时,一次性加载所有的属性,否则,只加载需要的属性。

返回值中包含集合
返回值中包含集合的时候,使用collection标签来对记录进行封装。

  • property:封装成的属性
  • ofType:分装成的Java类型
    collection内的配置与以往相同。

    
    
    
        
        
        
        
    


包含集合的分步查询
步骤:

  1. 用班级id获取到班级的信息
  2. 再用班级id在用户表里查找用户。

    
    
    
    



  • fetchType:加载方式:延迟加载或立即加载
    PS:当collection里的column要传递多个参数时,可以使用{key1=value1,key2=value2}的方式书写


注:这里第一次看视频教程的时候,视频上用的collection,但是我自己敲的时候不小心敲成association,但是也成功查询到了结果,因此目前有点分不清association和collection了。

动态SQL

if标签的使用


与jstl表达式类似,不过OGNL里test支持的元素更多。
当满足test属性里的条件时,对应的sql语句片段被拼接

select * from tb_user
where


    user_id = #{userId}



    and last_name like #{lastName}


    and sex = #{sex}


    and age = #{age}

常用的字符转义符

字符 十进制 转义字符
" " "
& & &
< < <
> > >
不断开空格(non-breaking space)    
where标签

去掉拼接后字符串前多余的and或者or


PS:

  • where标签会自动在拼接体前面加上where
  • where标签不能去除后面重复的and或or
trim标签
  • prefix:前缀,在拼接体前面加上的前缀
  • prefixOverrides:前缀覆盖,去掉拼接体前面多余的字符串
  • suffix:后缀,在拼接体后面加上的后缀
  • suffixOverrides:后缀覆盖,去掉拼接体后面多余的字符串
select * from tb_user

    
        user_id = #{userId} and
    
    
        last_name like #{lastName} and
    
    
        sex = #{sex} and
    
    
        age = #{age}
    

choose标签

当满足某一分支的时候选择对应的sql语句,类似于switch-case语句,按顺序判断

select * from tb_user

    
        
            user_id = #{userId}
        
        
            last_name like #{lastName}
        
        
            sex = #{sex}
        
        
            age = #{age}
        
        
        
        
    

set标签

用于更新字段,当用if标签判断需要拼接的字符串时,可能出现多余的",",这个时候可以用set标签来取出多余的","。


    update tb_user
    
        
            last_name = #{lastName},
        
        
            sex = #{sex},
        
        
            age = #{age}
        
    
    
        user_id = #{userId}
    

foreach标签

通过遍历可以把集合里的元素生成一个字符串

  • collection:用来选中传来的集合参数
  • item:表示集合中每个元素
  • separator:用来分个每个元素的符号
  • open:在集合生成的字符串前面添加的字符串
  • close:在集合生成的字符串后面添加的字符串
  • index:表示遍历过程中,集合的索引(遍历map时,表示key值)

使用foreach标签插入多条记录

  1. 通过mysql语句支持 insert into table_name values(),(),()的特点,用foreach标签拼接出来插入多条记录的单sql语句。

    insert into tb_user(last_name, sex, age) values
    
        (#{user.lastName}, #{user.sex}, #{user.age})
    

  1. 通过foreach拼接处多条用分号分个的insert语句

    
        insert into tb_user(last_name, sex, age)
            values(#{user.lastName}, #{user.sex}, #{user.age})
    

PS:这个方法不限于insert语句,也可以用于其他语句,但是使用这个方法必须在数据库连接url的属性后添加allowMultiQueries=true。

两个内置对象
  1. _parameter
    表示传入sql语句的参数,多个参数时,这些参数会被封装成map,此时_parameter指代的就是这个map
  2. _databaseId
    表示当前数据库的id,可以通过这个对象判断当前使用的数据库

bind标签

可以将OGNL表达式的值绑定到一个变量


sql标签
  1. sql:抽取sql片段,以便后面重用
  2. include:引入sql标签声明的sql片段。
  3. include还可以通过property子标签设置自定义属性,可以在sql标签里通过${}直接使用。

    
        insert into tb_user(
        
        )
        values(#{user.lastName}, #{user.sex}, #{user.age})
    


    last_name, sex, age

你可能感兴趣的:(MyBatis学习笔记)