mybatis复习(二)
简介
mybatis是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql语句本身,
而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。
MyBatis工作原理
1.读取配置文件,配置文件配置的是数据库连接的信息
2.加载映射文件(Mapper) 文件里面配置了sql语句
3.构建会话工厂
4.构造会话对象 由会话工厂创建SqlSession对象,该对象包含了执行SQL的所有方法
5.根据sqlSession创建dao(指的是查询的一个接口)接口的代理对像 通过代理对象执行(自己定义的)增删改查方法
MyBatis的核心对象
1.SqlSessionFactory对象线程安全,一旦被创建在整个执行期间都会存在.主要作用就是构建SqlSession,SqlSessionFactory对象是通过
SqlSessionFactoryBuilder读取xml配置文件配置创建的.
2.SqlSession他是应用程序与持久层之间执行交互操作的一个单线程对象,主要作用执行持久化操作,线程不安全使用范围最好在一个方法
或一次请求中,不可以放到一个类的静态字段,使用完后及时关闭.
映射文件的主要元素(xml)
<resultMap id="userMap" type="user" > ----id唯一标识 -----type 表示是封装到哪个实体类 这里是Account类
<id property="id" column="id"></id> -----id表示哪一列是主键
<result property="username" column="username"></result>property是实体类Account类的字段 column是数据库字段
一对一 在pojo中 将一方的对象作为另一方的属性
<association property="user" javaType="user"><!--property表示封装哪个对象,colum表示通过那个字段封装-->
<id property="id" column="id"></id>-----id表示哪一列是主键
<result column="username" property="username"></result>property是实体类Account类的字段 column是数据库字段
</association >
一对多 将多的一方的封装为List<多的一方> 作为一的一方pojo的属性
<collection>
.............
</collection>
</resultMap>
xml方式 映射文件中的属性和sql注入问题
--resultType 属性: 用于指定结果集的类型。
--parameterType 属性 用于指定传入参数的类型。如果为我们要传入的是一个类的对象,所以类型就写类的全
名称。
--如果插入数据时某个字段自增 可以使用keyProperty接收主键返回值,id指的是自增字段
keyProperty="id" useGeneratedKeys="true" 设置主键自僧
模糊查询时 不直接在sql语句中使用% 而是在方法中拼接%
--sql 语句中使用#{}字符: 它代表占位符,相当于原来
jdbc 部分所学的,都是用于执行语句时替换实际的数
据。 具体的数据是由#{}里面的内容决定的。
#{}中内容的写法: 由于数据类型是基本类型,所以此处可以随意写。
--sql语句拼接时不建议使用${} 会引起sql注入, 建议使用 #{} 表示一个占位符号
例如 :模糊查询 select * from user where username like '%${value}%'
正确写法 select * from user where username like concat( '%' ,#{value} ,'%') 使用concat()函数拼接
开启注解 不再写xml
使用注解 不再使用resource而使用class
配置文件
<mappers>
<mapper class="dao.IUserDao"/>
</mappers>
Mybatis 与 JDBC 编程的比较
1.数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。 解决: 在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。
2.Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。 解决: 将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。
3.向sql语句传参数麻烦,因为sql语句的where 条件不一定,可能多也可能少,占位符需要和参数对应。 解决: Mybatis自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的 类型。
4.对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对 象解析比较方便。 解决: Mybatis自动将 sql执行结果映射至 java 对象,通过statement中的resultType 定义输出结果的 类型
实体类和数据库字段不一致
resultMap 标签可以建立查询的列名和实体类的属性名称不一致时建立对应关系。从而实现封装。
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称
动态sql
----<if> 判断语句,用于单条件分支判断 例如
<select id="findByUser" resultType="user" parameterType="user">
select * from user where 1=1
<if test="username!=null and username != '' ">
and username like #{username}
</if>
<if test="address != null">
and address like #{address}
</if>
</select>
----<choose><when><otherwise> 相当于javaz中swit-ch...case...default语句.
例如
select * from user where 1=1
<choose>
<when test="username!=null and username !='' " >
and username like concat('%',#{username},'%')
</when>
<when>.........</when>
<otherwise>
and phone is not null
</otherwise>
</choose>
----为了简化上面 where 1=1 的条件拼装,我们可以采用<where>标签来简化开发。
------SQL 语句:实现 select * from user WHERE id in (41,42,43); 这样的功能
<foreach>标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符
-------<bind> 模糊查询拼接%
关联映射
一对一
<!-- 一对一-->
<mapper namespace="dao.IAccuntDao">
<!--定义封装account和user两个表-->
<resultMap id="Map" type="account"> <!--type 表示是封装到哪个实体类 这里是Account类-->
<id property="ID" column="AID"></id><!--property是实体类Account类的字段 column是数据库字段-->
<result property="UID" column="UID"></result>
<result property="MONEY" column="MONEY"></result>
<!--一对一关系映射,封装user内容-->
<association property="user" javaType="user"><!--property表示封装哪个对象,colum表示通过那个字段封装-->
<id property="id" column="id"></id>
<result column="username" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
</association>
</resultMap>
<!--查询所有账户 同时包含用户名和地址信息 那么包含两张表一个是user表一个是account表-->
<select id="findAllAccount" resultMap="Map">
SELECT u.*,a.ID as aid,a.MONEY from account a, user u WHERE a.UID = u.id;
</select>
</mapper>
一对多
在 多的一方添加一的一方的主键作为外键<collection>标签
用户---订单
<!-- 1对多 -->
<mapper namespace="dao.IUserDao">
<!--定义user的map-->
<resultMap id="userMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<!--配置list集合映射-->
<collection property="accounts" ofType="account"><!--accounts 是User类里面的字段-->
<id column="aid" property="ID"></id>
<result column="UID" property="UID"></result>
<result column="MONEY" property="MONEY"></result>
</collection>
</resultMap>
<!-- 配置查询所有操作( //查询所有用户 同时获取到用户下所有账户信息 一对多)-->
<select id="findAll" resultMap="userMap">
select u.*,a.id as aid ,a.uid,a.money from user u left outer join account a on u.id =a.uid
</select>
<!-- 根据用户id查询用户(一)对应的账户(多)信息 -->
<select id="findById" parameterType="Integer" resultMap="userMap">
select u.*,a.id as aid ,a.uid,a.money from user u ,account a where u.id =a.uid and u.id=#{id};
</select>
</mapper>
多对多 产生中间表,引入两张表的主键作为外键
订单------商品
<!-- 多对多 -->
<mapper namespace="dao.IRoleDao">
<!--定义roleMap 因为使用了map所以实体类 Role类的字段可以和数据库字段不一致-->
<resultMap id="roleMap" type="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="ROLE_NAME"></result>
<result property="roleDesc" column="ROLE_DESC"></result>
<!--封装user-->
<collection property="users" ofType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
</collection>
</resultMap>
<!--查询所有-->
<select id="findAll" resultMap="roleMap">
/*-- 左外连接(多对多 需要中间表)*/
select u.*,r.ID as rid,r.ROLE_NAME,r.ROLE_DESC from role r left outer join user_role ur on r.ID=ur.RID
left outer join user u on u.id = ur.UID;
</select>
</mapper>
延迟加载sql缓存
-----一级缓存
一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就存在。
关闭SqlSession .close 再创建缓存消失
一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除. commit(),close()等方法时,
就会清空一级缓存
---------二级缓存
二级缓存是 mapper 映射级别的缓存,多个 SqlSession
去操作同一个 Mapper 映射的 sql 语句,多个 SqlSession
可以共用二级缓存,二级缓存是跨 SqlSession 的。
注解开发
@Results 注解 代替的是标签<resultMap>
@Result 中 属性介绍: id 是否是主键字段 column
数据库的列名 property 需要装配的属性名 one 需
要使用的@One 注解(@Result(one=@One)
())) many 需要使用的@Many 注解(@Result(many=@many)()))
@One 注解(一对一) 代替了<assocation>标签,
是多表查询的关键,在注解中用来指定子查询返回单一
对象。 @One 注解属性介绍: select 指定用来多表查询的 sqlmapper
@Many 注解(多对一) 代替了<Collection>标
签,是是多表查询的关键,在注解中用来指定子查询返
回对象集合。 注意:聚集元素用来处理“一对多”的
关系。需要指定映射的 Java 实体类的属性,属性的 ja
vaType (一般为 ArrayList
mybatis复习(二)的更多相关文章
- MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致
MyBatis系列二 之 数据库列名于程序实体类中字段名称不一致 情景:当数据库中的列名与我们程序实体类中的字段名称不一致 使用ResultMap节点配置信息 在映射文件中 ...
- MyBatis笔记二:配置
MyBatis笔记二:配置 1.全局配置 1.properites 这个配置主要是引入我们的 properites 配置文件的: <properties resource="db.pr ...
- (原创)mybatis学习二,spring和mybatis的融合
mybatis学习一夯实基础 上文介绍了mybatis的相关知识,这一节主要来介绍mybaits和spring的融合 一,环境搭建 1,jar包下载,下载路径为jar包 2,将包导入到java工程中 ...
- 33、mybatis(二)
第十六章回顾SQL99中的连接查询 1)内连接 2)外连接 3)自连接 第十七章回顾hibernate多表开发 1)一对一 2)一对多 3)多对多 第十八章 mybatis一对一映射[学生与身份证] ...
- MyBatis复习
一.对JDBC的总结 1.数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响数据库性能. 解决方案:使用数据库连接池管理数据库连接. 2.将sql语句硬 ...
- mybatis(二)接口编程 、动态sql 、批量删除 、动态更新、连表查询
原理等不在赘述,这里主要通过代码展现. 在mybatis(一)基础上,新建一个dao包,并在里面编写接口,然后再在xml文件中引入接口路径,其他不变,在运用阶段将比原始方法更节约时间,因为不用再去手动 ...
- MyBatis之二:简单增删改查
这一篇在上一篇的基础上简单讲解如何进行增删改查操作. 一.在mybatis的配置文件conf.xml中注册xml与注解映射 <!-- 注册映射文件 --> <mappers> ...
- Java框架之Mybatis(二)
本文主要介绍 Mybatis(一)之后剩下的内容: 1 mybatis 中 log4j的配置 2 dao层的开发(使用mapper代理的方式) 3 mybatis的配置详解 4 输入输出映射对应的类型 ...
- springboot集成mybatis(二)
上篇文章<springboot集成mybatis(一)>介绍了SpringBoot集成MyBatis注解版.本文还是使用上篇中的案例,咱们换个姿势来一遍^_^ 二.MyBatis配置版(X ...
- spring boot整合mybatis方式二
方式二: pom文件导入maven依赖: <dependency> <groupId>org.springframework.boot</groupId> < ...
随机推荐
- 详解Python中sys模块的功能与应用
本文分享自华为云社区<深入Python:sys模块的功能与应用详解>,作者: 柠檬味拥抱. 在Python的标准库中,sys 模块是一个常用而强大的工具,它提供了与Python解释器交互的 ...
- .NET应用国际化支持-葡萄牙语下如何不区分重音的模糊查询
葡萄牙语,作为一种罗曼语族的语言,其正字法(orthography)并不使用音标系统来标记发音,而是有一套特定的拼写规则.然而,葡萄牙语中确实使用重音符号(acentos)来标记某些元音的重音(str ...
- nginx 和 mysql 安装
先附上大云资料: 安装nginx. 登录弹性云服务器. 执行以下命令,下载对应当前系统版本的nginx包. wget http://nginx.org/packages/centos/7/noarch ...
- vscode vue 组件定位插件 webpack-code-inspector-plugin -- 强烈推荐 Alt+Shift+鼠标左键
作用 alt + shift + 鼠标左键 自动跳转 vscode项目的组件代码 项目地址 https://github.com/zh-lx/code-inspector/blob/main/pack ...
- SQL语句之索引操作
目录 索引 创建索引 CREATE INDEX 语句 CREATE UNIQUE INDEX 语句 索引多个列 删除索引 参考资料 索引 可以在表中创建索引,以便更加快速高效地查询数据. 用户无法看到 ...
- ACER 宏碁 笔记本无法进入 grub 引导 + 安全启动失败(security boot fail ) 解决办法
主要介绍让BIOS首先引导grub的方法 加一点:添加完新的启动选项以后,如果看不到添加的启动项,就先保存重启,再进 BIOS 就可以看到了 我是宏碁的笔记本,装了双系统.之前无意间进了一次 BIOS ...
- 2.4g无线私有协议透传方案特色梳理
为什么? 在2.4G这个频段,的确有待你拥挤,有提供高速上网的wifi,有提供短距离数据和云音乐传输的bt,还要各种xx的东西.在wifi和bt无法覆盖的领域,又出来一个2.4G私有协议传输芯片,这 ...
- python删除指定文件夹下文件和文件夹的方法
前记 python删除指定文件夹下的文件,是一个常用的功能.我找了不少地方,一直没有找到合适的模版,那只好自己倒腾一个比较实用的模版了. 基本模块 这里面会用到几个模块,一个是目录下所有文件的 ...
- spring boot2集成api文档工具swagger-ui(上)
说明 第一步:创建项目 浏览器打开:https://start.spring.io/,生成一个spring boot项目 点击Generate这个按钮,下载项目包文件 第二步:导入开发工具 打开下载目 ...
- 引领汽车营销新趋势,3DCAT实时云渲染助力汽车三维可视化
当前,汽车产业发展正从电动化的上半场,向智能化的下半场迈进.除了车机技术体验的智能化之外,观车体验的智能化也不容忽视. 这是因为,随着数字化.智能化.个性化的趋势,消费者对汽车的需求和期待也越来越高, ...