Mybatis学习

Mybatis用于提高持久层数据处理效率,支持自定义SQL,用于简化数据库操作

Mybatis前身是ibatis,Mybatis对ibatis进行了封装和优化

原本使用Dao定义接口规定方法,用DaoImpl实现类进行方法的具体实现,做数据库操作

使用Mybatis后,使用Mapper定义接口规定方法,使用Mapper.xml实现接口对应方法的sql语句

持久层框架对比

c21a32d68182443094508df2f9483d82.png

Mybatis使用流程

首先导入依赖,准备实体类

1.写好mapper接口(方法不能重载)

2.Mybatis使用xml方式固定在特定标签内书写sql语句,没有java代码,要有约束

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE mapper

        PUBLIC "-//mybatis.prg//DTD Mapper 3.0//EN

        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="mapper对应接口的全限定符">

声明标签写sql语句,分别是select,insert,update,delete,每个标签对应接口的一个方法

        <select id="方法名" resultType="返回值类型全限定符">

                sql

        </selsct>

</mapper>

3.要将mybatis配置数据库连接信息xml文件

4b85e1c76304437cb5a77b3c9e75cd05.png

4.创建类调用mybatis提供的api进行方法的调用(进行数据库操作)

4.1读取外部配置文件InputStream ips=Resources.getResourceAsStream("配置数据库xml文件");

4.2创建sqlSessionFactory(全局保存),SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);

4.3根据sqlSessionFactory创建sqlSession(为每次业务创建一个,用完就释放)SqlSession sqlSession= sqlSessionFactory.openSession();(自动开启事务,但不会自动提交,括号里加true表示会自动提交)(在Spring5以后,每个方法前会自动调用@BeforeEach方法,可以将创建sqlSession的方法放在其中,并且设置sqlSession为private全局变量)

4.4获取接口的代理对象,通过代理对象的方法,查找mapper接口的方法xxxMapper mapper = sqlSession.getMapper(接口类)

xxx xxx=mapper.方法名(参数)

4.5提交事务释放资源(通过@AfterEach注解方法,设置每个方法执行完成后自动执行该方法即可,不用每次都编写)

sqlSession.commit();

sqlSession.close();

mybatis-Config.xml配置属性

设置settings

改变mybatis运行时行为

其中有setting标签,通过name和value进行设置

环境environments

可以配置多个环境,但每个Factory只能选择一种环境

environments的default表示哪个环境生效

environment下标签:

事务管理器transaction

type="JDBC(自动开启事务,需要自己提交事务)或MANAGED(不会自动开启事务)"

数据源datasource

type="UNPOOLED每次请求打开或关闭连接,POOLED利用mybatis维护一个连接池,JNDI

mappers用来配置映射文件位置,最终缓存到sqlSessionFactory中

Mapper.xml配置

取值符号#和$

emp_id=#{key}首先新建emp_id,然后赋值

emp_id=${key}字符串拼接emp_id=和id值

推荐使用#,防止注入攻击。但是#左侧新建的必须是静态的列名,无法动态管理,不能替代容器名(标签,列名,sql关键字)

数据输入

简单类型:单值类型,单个数据类型

传入单个简单类型的key随便写,一般情况下推荐使用#{参数名}

复杂类型:多值类型,对象,map,list等

传入单个实体对象,key=#{属性名}

传入多个简单类型,方法一:使用@param指定接口方法中的参数名称(相当于给定了id),在xml文件中使用#{参数名}即可

方法二:不指定情况下,参数按顺序分别为arg0,arg1...,也可以用param1,param2...

传入map类型,key=#{map的key}

数据输出

默认返回值为int,可以用int和long接收输出

主要设置查询返回值输出接收

输出单个简单类型,将resultType设置为类的全限定符号或别名,如java.lang.String,也可以写简称string。基本数据类型别名为_int等,其他数据类型开头小写即可。给自己设定的类起别名可以在config.xml文件中通过<typeAliases alias=别名 type=类全限定符 />设置。也可以通过指定<package name=包名 />配置包,无注解情况下会使用bean首字母小写的非限定类名作为别名,有注解@Alias(只在批量注解下生效)则别名为注解值

输出单个实体类对象,将resultType设置为类的全限定符号或别名,要求sql语句中别名和属性名一直,这样才能进行属性映射,但是可以在setting中开启驼峰命名自动映射,开启后不需要起别名,满足条件的自动映射

输出map数据类型,没有实体类接值时,可以使用map列名为key,结果放入map中

输出list类型,返回集合类型resultType不需要设置为list,只需要指定集合的泛型即可,如string,因为ibatis中select有selectone和selectlist,分别对应查询单个和查询集合,selectone底层仍然调用selectlist,只需要指定泛型即可

输出自增长主键值,useGeneratedKeys=true表示想要获取自增长主键值,keyColumn=主键列字段,keyProperty=接值的属性

输出非自增长主键值,需要自己维护主键值,可以在使用时创建String id =UUID.randomUUID().toString().replaceALL("-",""),也可以在代理中创建,在代理中使用selectKey标签中间书写创建主键sql语句,order=BEFORE或AFTER,表示在插入之前或之后创建,resultType=返回值类型,keyProperty=查询结果赋给的属性值

列名和属性名不一致问题

方法一:在sql语句中查询时起别名

方法二:在setting中开启驼峰式映射

方法三:使用resultMap自定义映射

resultType按照规则自动映射,按照是否开启驼峰式映射,自动映射属性和别名,只能映射一层结构,深层次对象结构无法映射,多表查询结果无法映射

resultMap可以定义深层映射和多表映射关系

在select标签中,resultType和resultMap二选一即可

使用自定义映射要在前面自己设置resultMap标签,设置id和type(类的全限定符或别名,集合只写泛型),标签中使用如id标签(column=列名,property=属性名)定义映射关系

ibatis

只需要在xml文件中写sql语句,不用写接口,namespace没有要求,随意声明字符串即可,内部使用crud标签声明sql语句,标签id也可以随便写

只需要将mapper放入xml环境配置文件中即可

数据库操作区别在于4.4处不需要调用接口,直接使用sqlSession的crud方法即可,方法有两个参数,参数一是字符串,表示sql语句标签id或namespace.id。参数二是对象,执行sql语句传入的参数

ibatis中select有selectone和selectlist,分别对应查询单个和查询集合,selectone底层仍然调用selectlist

缺点:直接写标签id容易出错;参数需要整合,只能传入一个;返回值返回object,需要自己指定

ibatis实质上在mapperxml文件中写sql语句,在mybatis config xml文件中配置mapper xml文件和数据库信息,使用时创建sqlSessionFactory缓存数据库信息,将标签id作为key,sql语句为value,通过factory创建多个sqlsession,执行sql提供的增删改查方法,也是通过keyid从factory中获取sql语句,然后对传入参数执行

mybatis对ibatis优化

通过接口创建多个方法,通过getMapper为factory生成代理对象,代理对象内部获取类全限定符,获取方法名并拼接成字符串,再调用ibatis方法

mybatis要求namespace等于类全限定符,id等于方法名

增删改查练习

1.准备数据库

2.实体类准备(@Data注解自动添加get,set,toString方法)

3.在java目录下指定路径,新建定义Mapper接口

4.在resources文件下mappers文件中配置Mapper.xml

5.配置mybatis-config.xml文件

6.使用方法

多表映射

1.多表查询的sql语句需要编写连接查询2.需要自己设计存储数据的实体类,承接多表查询结果3.需要自己定义结果集映射

一对一查询只需要属性中包含对方对象即可

一对多查询只需要属性中包含对方对象集合即可

当发生多表查询时才需要设计和修改实体类,否则不提前设计

无论多少张表联查,实体类设计都只考虑两两关系

查询时只需要关注本次查询相关的属性

resultMap自定义映射

对单个表中的属性映射时候,在前面设置resultMap标签,设置id(对应增删改查标签中的resultMap名)和type(类的全限定符或别名,集合只写泛型),标签中使用如id标签(主键)result标签(其他属性)(column=列名,property=属性名)定义映射关系

对单个表连接其他表的对一的对象属性赋值时,使用<association property=属性名 javaType=类的全限定符或别名>,标签中使用如id标签(主键)result标签(其他属性)(column=列名,property=属性名)定义映射关系

对对单个表连接其他表的对多的对象属性赋值时,使用<collection property=集合属性名 ofType=集合泛型类型>,标签中使用如id标签(主键)result标签(其他属性)(column=列名,property=属性名)定义映射关系,只赋值需要查询的属性,不要产生循环查询

setting中设置name=autoMappingBehavior,value=FULL表示有无嵌套都会自动映射result标签的属性和列,NONE表示不会自动映射,PATICAL表示仅映射单层result

动态语句

where和if标签

在Mapper增删改查标签中使用,<where>标签包在if标签外面,当有if为真时自动添加where,同时可以去掉多余的连接符and和or

<if test="key比较符号 值"> 执行条件</if>,可以在引号中使用and或or。大于小于等于建议使用转义符号

set标签

在update中set标签使用方法等同where,自动去掉多余逗号,自动添加set关键字,但是至少保证有一个if满足,否则语法本身报错

trim标签

<trim prefix=动态添加前缀 suffix动态添加后缀 prefixOverrides=动态去掉多余前缀 suffixOverrides=动态去掉多余后缀>,可以使用|分割多个值,可以替代set和where

choose when otherwise标签

满足when条件则选择,所有when都不满足则走otherwise

otherwise要保证sql语句不会报错

foreach标签

该标签可以写在sql语句中,用于遍历数据

collection=ids或arg0或list

open=遍历前要追加的字符串

close=遍历结束添加的字符串

separator=每次遍历分隔符,最后一次不添加

item获取每个遍历项,如id,在foreach标签中写#{id}即可

插入一个元素的多个属性时,item为元素名,属性名为元素名.属性名

修改数据时,对整体update语句进行遍历,item为元素名,属性名为元素名.属性名,一个标签涉及多语句执行,需要在xml配置文件中的url后面加?allowMultiQueries=true

sql标签

抽取重复的sql片段

抽取时使用<sql id=片段名>片段<sql>

引用时使用<include refid=片段名 />

高级扩展

批量扫描Mapper

mybatis-config中直接按包扫描mapper,需要mapper.xml文件和mapper接口命名相同

最终打包的位置要一致,都是指定的包地址下

方案一:将接口与mapperxml文件放在一个包中,并在pom.xml中配置(不推荐)

方案二:在resources文件夹创建相同的文件夹结构,创建多层时用/分割,不用.

插件和分页插件PageHelper

如果要使用分页插件PageHelper,就不用在sql语句中添加limit,不要使用;结尾,

不能将两条查询装在同一个分页区

pagehelper使用

1.pom.xml中导入依赖

2.在config.xml中配置分页插件

3.在实际查询前使用PageHelper.startPage(页码,页size)

4.将查询数据封装到一个PageInfo的分页实体类中PageInfo<查询实体类> pageInfo =new PageInfo<>(list)

5.查询结果List<查询实体类> list=pageInfo.getList()获取当前分页数据

getPages获取总页数

getTotal获取总条数

getPageNum获取当前页码

getPageSize获取页容量

ORM框架

Object-Relational Mapping对象关系映射

将对象和关系数据库概念进行映射,可以通过方法调用进行数据库操作

逆向工程指期待半自动orm向全自动orm迈进

逆向工程只能生成单表的增删改查,多表仍需要自己写

逆向工程使用mybatisX插件连接数据库并生成对应的java对象以及增删改查方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值