官网地址: https://mybatis.org/mybatis-3/zh/index.html
MyBatis 是持久层框架,内部整合了JDBC,以对象的方式操作数据库.
Spring整合mybatis使用的是JDK代理
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.2.0
mysql
mysql-connector-java
org.projectlombok
lombok
application.properties改为application.yml
yml文件 0不解析 如果字母以0开头则引号包裹
#1.配置端口号 注意缩进!!!!!
server:
port: 8090
#2.配置数据源
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jt?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
#yml文件 0不解析 如果字母以0开头则引号包裹
#password: "0123456"
password: root
#3.配置Mybatis
mybatis:
#定义别名包路径(简化UserMapping.xml文件的resultType的写法)
type-aliases-package: com.jt.pojo
#将所有的映射文件全部加载
mapper-locations: classpath:/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
#4.打印Sql com.jt.mapper下的Sql日志
logging:
level:
com.jt.mapper: debug
@Data //lombok需要pom文件添加依赖,安装lombok插件该注解会自动生成很多常用方法
@Accessors(chain = true) //重写了set方法. 可以实现链式加载
@NoArgsConstructer //无参构造函数
@AllArgsConstructor //全参数构造函数
implements Serializable对象序列化作用:
1.保证数据按照正确的格式输出
2.在多线程条件下,共享数据必须序列化生成序列号
属性类型必须是引用类型,且私有化
pojo层,修饰Data类型数据
@JsonFormat(pattern=“yyyy年MM月dd日 HH:mm:ss” , timezone=“GMT+8”)
- @Mapper //将接口交给Mybatis管理,Mybatis再将其交给Spring容器管理Map
JDK代理对象>,作用告诉编译器这是一个负责映射的接口 (映射指的是实体类和表之间的关系) - @MapperScan("包扫描路径")用于主启动类上,使用该注解可以省略重复写@Mapper注解
原则:Mybatis只支持单值传参将多值封装为单值
接收前段参数规则: 单个参数直接传
对象的多字段的可以使用对象封装
对象的单字段的两值可以使用集合HashMap
利用注解@Param("id")将数据封装为Map,在xml文件中使用的就是该注解中的该变量名,否则在写xml文件时,需要通过agr0,agr1...param1,param2....来标注sql语句中使用参数中的第几个参数对象的单字段的多值可以使用Arrays / list集合 / map集合封装
mapper层使用参数的规则:
1. 如果是单个参数,则使用#{key} 获取的参数的值(如果只传递一个参数,则名称任意!Mybatis单值传参时,与下标有关和名称无关)
2. 如果是对象参数,则使用#{属性} 获取的是属性值
3.如果传递的参数是Map, 则使用#{key}
4.如果传递的是Arrays / list集合 / map集合,需要遍历再取值查询返回值: 单个对象使用对象直接接收 多个对象使用List<对象User>
@Mapper //将接口交给Spring容器管理 Map
public interface UserMapper { //根据ID查询数据库 User findUserById(int id); List findUserByNA(User user); //注解:@Param("key") int minAge(值) // 作用:将数据封装为Map List findUserByAge2(@Param("minAge") int minAge, @Param("maxAge") int maxAge); List findListByIn(int[] array); } 关于抽象方法:
- 必须定义在某个接口中,这样的接口通常使用
Mapper
作为名称的后缀,例如AdminMapper
- Mybatis框架底层将通过接口代理模式来实现
- 方法的返回值类型:如果要执行的数据操作是增、删、改类型的,统一使用
int
作为返回值类型,表示“受影响的行数”,也可以使用void
,但是不推荐;如果要执行的是查询操作,返回值类型只需要能够装载所需的数据即可- 方法的名称:自定义,不要重载,建议风格如下:
- 插入数据使用
insert
作为方法名称中的前缀或关键字- 删除数据使用
delete
作为方法名称中的前缀或关键字- 更新数据使用
update
作为方法名称中的前缀或关键字- 查询数据时:
- 如果是统计,使用
count
作为方法名称中的前缀或关键字- 如果是单个数据,使用
get
或find
作为方法名称中的前缀或关键字- 如果是列表,使用
list
作为方法名称中的前缀或关键字- 如果操作数据时有条件,可在以上前缀或关键字右侧添加
by字段名
,例如deleteById
- 方法的参数列表:取决于需要执行的SQL语句中有哪些参数,如果有多个参数,可将这些参数封装到同一个类型中,使用封装的类型作为方法的参数类型
由于mybatis需要操作数据库.编辑Sql语句. 采用xml映射文件维护Sql语句.
在resource的目录中添加mappers文件创建UserMapper.xml
模糊查询 特别注意表名的大小写问题!!!
windows系统中: 不区分大小写Linux系统中: 区分大小写问题
别名包:
在配置文件中指定包路径: 可以自动的实现包路径的拼接
resultType规则:
1. 首先根据别名包匹配.设定..
2. 如果匹配不成功,则按照路径匹配.
xml转译字符: > > < < & &
万能转义:
注意: 新增,删除,修改没有返回值resultType
关于取值操作的说明: #{属性值},${属性值}
1.#号取值采用占位符的方式 更加安全 防止sql注入攻击!!!
2.$符一般的使用场景 以字段为参数时使用.
3.使用#号时,默认会添加一对" "号
insert into ams_admin ( username, password, nickname, avatar, phone, email, description, is_enable, last_login_ip, login_count, gmt_last_login, gmt_create, gmt_modified ) values ( #{username}, #{password}, #{nickname}, #{avatar}, #{phone}, #{email}, #{description}, #{isEnable}, #{lastLoginIp}, #{loginCount}, #{gmtLastLogin}, #{gmtCreate}, #{gmtModified} ) update demo_user set name=#{name} where id = #{id}
动态SQL -- foreach
标签:用于遍历集合或数组类型的参数对象
collection
属性:被遍历的参数对象,当抽象方法的参数只有1个且没有添加@Param
注解时,如果参数是List
类型则此属性值为list
,如果参数是数组类型(包括可变参数)则此属性值为array
;当抽象方法的参数有多个或添加了@Param
注解时,则此属性值为@Param
注解中配置的值item
属性:自定义的名称,表示遍历过程中每个元素的变量名,可在子级使用
#{变量名}
表示数据separator
属性:分隔符号,会自动添加在遍历到的各元素之间
delete from ams_admin where id in ( #{id} )
动态Sql if-where条件:
动态Sql: 根据对象中不为null的属性当作where条件
语法:
1.如果判断成立,则动态拼接条件
条件
2.where标签 去除where后边多余的一个and/or
动态Sql-set条件:
根据对象中不为null的元素,充当set条件. where id=xxx
动态Sql-choose、when、otherwise如果不想使用所有的条件可以使用choose 类似于java中的if-elseif-elseif...else 语法:
update demo_user where id = #{id} name = #{name}, age = #{age}, sex = #{sex}
说明: Sql语句中经常出现重复的数据.如果每次重复的内容都自己手写.则开发的效率低.
id,name,age,sex
说明: 在业务中经常出现该现象. 字段 user_id 属性:userId 属性和字段有驼峰映射规则.但是采用resultType的方式进行映射.则不能正常赋值.
解决方案:
1.resultMap 繁琐.
2.在配置文件中开启驼峰映射规则当表中的字段与POJO中的属性名称不一致时,需要使用resultMap的方式进行映射.
1.resultType : 单表查询&结果集字段与属性一致
2.resultMap: 可以支持 任意类型的映射 万能的结构
编辑Mapper 映射文件
开启驼峰映射规则
mybatis:
#定义别名包
type-aliases-package: com.jt.pojo
#将所有的映射文件全部加载
mapper-locations: classpath:/mappers/*.xml
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
常见关联关系:
1.一对一 一个员工对应一个部门
2.一对多 在多的表中添加
3.多对多 需要中间表进行关联
创建POJO对象
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Emp implements Serializable {
private Integer id;
private String name;
private Integer age;
//关联关系: 一个员工对应一个部门
private Dept dept;
//private Integer deptId;
}
编辑Mapper 映射文件
创建POJO对象
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Dept implements Serializable {
private Integer deptId;
private String deptName;
//关联 一个部门下有多个员工
private List emps;
}
编辑Mapper 映射文件
@Insert("SQL语句") @Update("SQL语句") @Delete("SQL语句") @Select("SQL语句")
利用注解可以根据返回值类型,自动映射
规则1: 注解和映射文件 二选一 映射文件为主导.
规则2: 注解写法一般适用于简单操作.关联查询不适用@Transactional // 业务层需要对增删改操作进行事物的控制
如果程序运行出现运行时异常,则实现事务回滚
//该Mapper主要测试注解开发
@Mapper
public interface UserAnnoMapper {
@Select("select * from demo_user")
List findAll();
@Select("select * from demo_user where id=#{id}")
//@Insert()
//@Update()
//@Delete()
User findUserById(int id);
//#{变量} 会自动查找方法参数列表中的同名变量,如果没有同名变量
//会查找自定义对象类型里面的同名属性并调用get变量的方法
@Insert("insert into myemp values(null,#{name},#{sal},#{job})")
void insert(Emp emp);
}
1.Mybatis 默认条件下一级缓存默认开启的.
2.执行重复操作时,Mybatis一级缓存生效,查询一次数据库.
3.如果查询期间执行更新操作,则一级缓存清空.保证数据都是新的
springBoot整合mybatis之后,使用Mapper.find查询时.springBoot默认会开启多个sqlSession,可以通过添加事务注解@Transactional,springBoot中如果添加了事务注解,则默认采用同一个SqlSessio二级缓存:由同一个sqlSessionFactory,生产的SqlSession 数据共享. 默认开启 + 配置
1. 二级缓存默认开启.
2. 二级缓存需要标记. cache标签且关闭SqlSession3. 多线程条件下如果需要实现数据共享,则要求数据必须序列化!
要求Pojo必须序列化,配置:方案①Mapper层使用@CacheNamespace注解
方案②映射文件中加
由于Mybatis依赖了JDBC的jar包. 但是该jar包文件是启动项. 当主启动类运行时,开始加载主启动项. 但是JDBC需要链接数据库.所以必须有相关的配置信息.但是此时YML文件中没有数据源的配置.所以报错.配置application.yml文件中的数据源连接信息即可
现象及解决说明:
表中的字段名称与对象中的属性名称不一致. 结果:数据不能映射.
如果查询的结果为[ ],数据表中有数据,则有可能是:
1.动态Sql-choose、when、otherwise中,otherwise的条件为空
2.查询条件拼接错误,导致查询条件为空,数据表中该查询字段的值又没有null值,即使有null值,查询的结果跟预期也有差异.可以查看后台打印的sql语句拼接情况,再做修改.