MyBatis 接口绑定方案及多参数传递、动态 SQL、ThreadLocal、缓存
一.MyBatis 接口绑定方案及多参数传递
- 作用:实现创建一个接口后把mapper.xml由mybatis 生成接口的实现
类,通过调用接口对象就可以获取 mapper.xml 中编写的 sql. - 后面 mybatis 和 spring 整合时使用的是这个方案.
- 实现步骤:
3.1 创建一个接口
3.1.1 接口包名和接口名与 mapper.xml 中namespace相同
3.1.2 接口中方法名和 mapper.xml 标签的 id 属性相同
3.2 在 mybatis.xml 中使用进行扫描接口和 mapper.xml - 代码实现步骤:
4.1 在 mybatis.xml 中<mappers>
下使用<package>
<mappers>
<package name="com.bjsxt.mapper"/>
</mappers>
4.2 在 com.bjsxt.mapper 下新建接口
public interface LogMapper {List<Log> selAll();
}
4.3 在 com.bjsxt.mapper 新建一个 LogMapper.xml
4.3.1 namespace 必须和接口全限定路径(包名+类名)一致
4.3.2 id 值必须和接口中方法名相同
4.3.3 如果接口中方法为多个参数,可以省略 parameterType
<mapper namespace="com.bjsxt.mapper.LogMapper">
<select id="selAll" resultType="log">
select * from log
</select>
</mapper>
- 多参数实现办法
5.1 在接口中声明方法
List<Log> selByAccInAccout(String accin,String accout);
5.2 在 mapper.xml 中添加
5.2.1 #{}中使用 0,1,2 或 param1,param2
<!-- 当多参数时,不需要写 parameterType -->
<select id="selByAccInAccout" resultType="log" >
select * from log where accin=#{0} and accout=#{1}
</select>
- 可以使用注解方式
6.1 在接口中声明方法
/**
* mybatis 把参数转换为 map 了,其中@Param("key") 参数内
容就是 map 的 value
* @param accin123
* @param accout3454235
* @return
*/
List<Log> selByAccInAccout(@Param("accin") String
accin123,@Param("accout") String accout3454235);
6.2 在 mapper.xml 中添加
6.2.1 #{} 里面写@Param(“内容”)参数中内容
<!-- 当多参数时,不需要写 parameterType -->
<select id="selByAccInAccout" resultType="log" >
select * from log where accin=#{accin} and
accout=#{accout}
</select>
Test.java
InputStream is = Resources.getResourceAsStream("mybatis.xml");SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);SqlSession session = factory.openSession();/** 接口,为什么能实例化?* * 需要给接口一个实例化对象.* * 使用的JDK的动态代理设计模式.* 面向接口的代理设计模式(必须有接口)* */
// LogMapper logMapper = session.getMapper(LogMapper.class);
// List<Log> list = logMapper.selAll();
// for (Log log : list) {// System.out.println(log);
// }// LogMapper logMapper=new LogMapper(); 错误,接口不能实列化LogMapper logMapper = session.getMapper(LogMapper.class);List<Log> list = logMapper.selByAccInAccout("3", "1");for (Log log : list) {System.out.println(log);}session.close();System.out.println("程序执行结束");
二.动态 SQL
- 根据不同的条件需要执行不同的 SQL 命令.称为动态 SQL
- MyBatis 中动态 SQL 在 mapper.xml 中添加逻辑判断等.
- If 使用
<!-- 当id或name其中一个不正确时相当于 select * from test where id=#{id} and name=#{name} 当id=null或''时相当于:select * from test name=#{name} //name=null或''一样 --><select id="selByIdName" parameterType="com.xmm.demo.pojo.Website"resultType="com.xmm.demo.pojo.Website">select * from test where 1=1 <!-- OGNL 表达式,直接写 key 或对象的属性.不需要添加任 何特字符号 --><if test="id!=null and id!=''"> and id=#{id}</if><if test="name!=null and name!=''"> and name=#{name} </if></select>
<where>
4.1 当编写 where 标签时,如果内容中第一个是 and 去掉第一个and
4.2 如果<where>
中有内容会生成 where 关键字,如果没有内容不生成 where 关键字
4.3 使用示例
4.3.1 比直接使用<if>
少写 where 1=1
<!-- 当id和name都正确时相当于:select * from test WHERE id=? and name=? 当id或name有一个不正确时相当于 select * from test where id=#{id} and name=#{name} 当id=null或''时相当于:select * from test name=#{name} //name=null或''一样 --><select id="selByIdName" parameterType="com.xmm.demo.pojo.Website"resultType="com.xmm.demo.pojo.Website">select * from test<where><if test="id!=null and id!=''">and id=#{id}</if><if test="name!=null and name!=''">and name=#{name}</if></where></select>
<choose> <when> <otherwise>
5.1 只有有一个成立,其他都不执行.
5.2 代码示例
5.2.1 如果 accin 和 accout 都不是 null 或不是””生成的 sql 中只有 where accin=?
<!-- 当name和alias都正确时相当于:select * from test WHERE name=? 当name正确,alias错误时相当于:select * from test where name=#{name} 当name错误,alias正确时相当于: select * from test where name=#{name}同上 当name为null或""时相当于:select * from test WHERE alias=? --><select id="selByNameAlias" parameterType="com.xmm.demo.pojo.Website"resultType="com.xmm.demo.pojo.Website">select * from test<where><choose><when test="name!=null and name!=''">and name=#{name}</when><when test="alias!=null and alias!=''">and alias=#{alias}</when></choose></where></select>
<set>
用在修改 SQL 中 set 从句
6.1 作用:去掉最后一个逗号
6.2 作用:如果<set>
里面有内容生成 set 关键字,没有就不生成
6.3 示例
6.3.1 id=#{id} 目的防止<set>
中没有内容,mybatis 不生成 set 关
键字,如果修改中没有 set 从句 SQL 语法错误.
<!-- 当name和alias都不为null或""时(都有值)相当于:update test SET id=?, name=?, alias=? where id=? 当name为null或""时而alias有值时相当于:update test SET id=?, alias=? where id=? 当name有值而alias为null或""时相当于:update test SET id=?, name=? where id=? 当name和alias都为null或""时相当于: update test SET id=? where id=? --><update id="updByNameAlias" parameterType="com.xmm.demo.pojo.Website">update test<set>id=#{id},<if test="name!=null and name!=''"> name=#{name},</if><if test="alias!=null and alias!=''"> alias=#{alias}, </if></set>where id=#{id}</update>
- Trim
7.1 prefix 在前面添加内容
7.2 prefixOverrides 去掉前面内容
7.3 suffix 在后面添加内容
7.4 suffixOverrieds 去掉后面内容
7.5 执行顺序去掉内容后添加内容
7.6 代码示例
<!-- 相当于: update test set name=? where alias=? --><update id="updByNameAlias" parameterType="com.xmm.demo.pojo.Website">update test<trim prefix="set" suffixOverrides=",">name=#{name},</trim>where alias=#{alias}</update>
<bind>
8.1 作用:给参数重新赋值
8.2 场景:
8.2.1 模糊查询
8.2.2 在原内容前或后添加内容
8.3 示例
<!-- 相当于: select * from test where name like ?; --><select id="getByName" resultType="com.xmm.demo.pojo.Website"parameterType="String"><bind name="name1" value="'%'+name1+'%'" />select * from test where name like #{name1};</select>
<foreach>
标签
9.1 循环参数内容,还具备在内容的前后添加内容,还具备添加分
隔符功能.
9.2 适用场景:in 查询中.批量新增中(mybatis 中 foreach 效率比较低)
9.2.1 如果希望批量新增,SQL 命令
insert into log VALUES
(default,1,2,3),(default,2,3,4),(default,3,4,5)
9.2.2 openSession()必须指定
9.2.2.1 底层 JDBC 的 PreparedStatement.addBatch();
factory.openSession(ExecutorType.BATCH);
9.3 示例
9.3.1 collectino=”” 要遍历的集合
9.3.2 item 迭代变量, #{迭代变量名}获取内容
9.3.3 open 循环后左侧添加的内容
9.3.4 close 循环后右侧添加的内容
9.3.5 separator 每次循环时,元素之间的分隔符
<!-- 相当于: select * from test where id in ( ? , ? , ? , ? ) --><select id="selIn" parameterType="list" resultType="com.xmm.demo.pojo.Website">select * from test where id in<foreach collection="list" item="abc" open="(" close=")"separator=",">#{abc}</foreach></select>
<sql> 和<include>
10.1 某些 SQL 片段如果希望复用,可以使用<sql>
定义这个片段
<!-- 相当于:select id,name,alias from test where id=? --><sql id="mysql">id,name,alias</sql><select id="getById" parameterType="int" resultType="com.xmm.demo.pojo.Website">select<include refid="mysql"></include>from test where id=#{id1}</select>
三 ThreadLocal
- 线程容器,给线程绑定一个 Object 内容,后只要线程不变,可以随时
取出.
1.1 改变线程,无法取出内容. - 语法示例
final ThreadLocal<String> threadLocal = new
ThreadLocal<>();
threadLocal.set("测试");
new Thread(){public void run() {String result = threadLocal.get();
System.out.println("结果:"+result);
};
}.start();
四.缓存
应用程序和数据库交互的过程是一个相对比较耗时的过程
缓存存在的意义:让应用程序减少对数据库的访问,提升程序运行效率
MyBatis 中默认 SqlSession 缓存开启
3.1 同一个 SqlSession 对象调用同一个<select>
时,只有第一次访问数据库,第一次之后把查询结果缓存到 SqlSession 缓存区(内存)中
3.2 缓存的是 statement 对象.(简单记忆必须是用一个<select>)
3.2.1 在 myabtis 时一个<select>
对应一个 statement 对象
3.3 有效范围必须是同一个 SqlSession 对象缓存流程
4.1 步骤一: 先去缓存区中找是否存在 statement
4.2 步骤二:返回结果
4.3 步骤三:如果没有缓存 statement 对象,去数据库获取数据
4.4 步骤四:数据库返回查询结果
4.5 步骤五:把查询结果放到对应的缓存区中
SqlSessionFactory 缓存
5.1 又叫:二级缓存
5.2 有效范围:同一个 factory 内哪个 SqlSession 都可以获取
5.3 什么时候使用二级缓存:
5.3.1 当数据频繁被使用,很少被修改
5.4 使用二级缓存步骤
5.4.1 在 mapper.xml 中添加
5.4.2 如果不写 readOnly=”true”需要把实体类序列化(对象转字符)
<cache readOnly="true"></cache>
5.5 当 SqlSession 对象 close()时或 commit()时会把 SqlSession 缓存
的数据刷(flush)到 SqlSessionFactory 缓存区中
MyBatis 接口绑定方案及多参数传递、动态 SQL、ThreadLocal、缓存相关推荐
- 【Mybatis 之应用篇】 4_动态SQL、缓存
文章目录 Mybatis 十二.动态SQL 1.IF 2.choose(when,otherwise) 3.where,set 4.SQL片段 5.Foreach 十三.缓存 (了解) 1.简介 2. ...
- 《MyBatis技术原理与实战》之动态SQL
Mybatis有两种方式配置SQL 方式一:使用XML文件配置 方式二:在注解中配置SQL 通常,使用第一种方式,这里也只阐述第一种方式中SQL的用法 Mybatis动态的SQL常用的几个元素 元素 ...
- Mybatis的CRUD之XML方式以及动态SQL
MyBatis 接口代理方式实现 Dao 层 传统方式实现 Dao 层,我们既要写接口,还要写实现类.而 MyBatis 框架可以帮助我们省略编写 Dao 层接口实现类的步骤.程序员只需要编写接口,由 ...
- Mybatis动态sql和缓存
1.动态sql[重点] 1.右键点击File–>New–>Module,如图所示: 2.选择Java,并点击Next.如图所示: 3.填写项目名称,点击Finish.如图所示: 4.在se ...
- MyBatis的一对和多对对和动态SQL
一对多关联: MyBatis中使用collection标签来解决一对一的关联查询, collection标签可用的属性如下:property:指的是集合属性的值ofType:指的是集合中元素的类型co ...
- Mybatis_狂神(XML和注解,配置,lombok,动态sql,缓存等)
狂神说Mybatis视频链接: B站视频 Mybatis官方文档: Mybatis官方文档 MyBatis 1.简介 1.1 什么是Mybatis MyBatis 是一款优秀的持久层框架; 持久层即d ...
- Mybatis持久层框架 | 动态SQL、缓存
- 利用MyBatis的动态SQL特性抽象统一SQL查询接口
1. SQL查询的统一抽象 MyBatis制动动态SQL的构造,利用动态SQL和自定义的参数Bean抽象,可以将绝大部分SQL查询抽象为一个统一接口,查询参数使用一个自定义bean继承Map,使用映射 ...
- Mybatis系列全解(八):Mybatis的9大动态SQL标签你知道几个?提前致女神!
封面:洛小汐 作者:潘潘 2021年,仰望天空,脚踏实地. 这算是春节后首篇 Mybatis 文了~ 跨了个年感觉写了有半个世纪 - 借着女神节 ヾ(◍°∇°◍)ノ゙ 提前祝男神女神们越靓越富越嗨森! ...
最新文章
- doc es 中type_ES系列07:match_phrase与match_phrase_prefix query
- 最大调用堆栈大小超出错误
- php foreach 修改数组,php如何使用foreach修改数组
- 用Curl测试POST
- linux安装mysql启动失败的原因_爱在linux系统安装mysql启动失败如何处理?
- linux判断改行符_Linux判断符如何使用?
- excel取整函数_查询函数Choose、Lookup、Hlookup、Vlookup应用技巧解读
- 使用argparse解析命令行参数
- 安利10个让你爽到爆的IDEA必备插件,终获offer
- 用IntelliJ IDEA 配置安卓开发环境
- 锐捷客户端linux登录密码忘记,锐捷S3760忘记密码的恢复方法
- SN1SLD16 华为SDH全新原包装2xSTM-16光接口板
- SHINE与Phoenix合并,专注推进核聚变技术
- 恒生电子2019校园招聘笔试题
- 整形美容的消费者心理分析
- android wear刷机,1分钟搞定刷机 百度DuWear手表系统公测版上线
- 新星计划·能够 120% 提升博文美感的表情包,你们确定不心动吗?
- 计算机导论的平时分多少,学霸养成 | 大一期末考试经验第二弹,千万别错过!...
- 嵌入式linux+程序构架,从头开始构建一个嵌入式 Linux 发行版
- 中小型软件开发项目管理