Mybatis
1 Mybatis概述
jdbc 问题
数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
Sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java代码。
使用 preparedStatement 向占有位符号传参数存在硬编码,因为 sql 语句的 where 条件不一定,可能多也可能少,修改 sql 还要修改代码,系统不易维护。
对结果集解析存在硬编码(查询列名),sql 变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成 pojo 对象解析比较方便
2 什么是mybatis
MyBatis 是一款优秀的持久层框架,它支持 SQL、存储过程以及高级映射。
如 JDBC中 我们需要有繁琐的流程,和设置参数,并且获取结果集的时候也需要循环遍历,并且手动封装到实体类对象中。
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。
MyBatis 可以使用 简单的 XML 或注解来配置和映射 接口和 Java 的 实体类。
MyBatis 有两种用法,一个是注解,一个是XML,各有千秋
注解 : 使用注解的话,方便一些,不需要有XML配置文件,可能看上去会好看一些,但是需要代码和SQL在一起
XML : 把SQL语句放到XML文件中,java代码中会感觉干净一些,并且,使用XML形式 写一些复杂的SQL语句会比较方便,也能统一管理,有其他同事接手工作的时候,或者其他同事优化数据库查询的时候,位置好找,修改便捷,不容易出错
所以一般常用的就是XML,可以做到sql分离
有时候也是混用,简单的就用注解,复杂的就用XML
3 使用场景 :
MyBatis就是负责操作数据库的,所以当我们需要操作数据库的时候,就可以使用mybatis。
4 MyBatis与Hibernate的区别
MyBatis :
1 入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当完美。
2 可以进行更为细致的SQL优化,可以减少查询字段。
3 缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
4 二级缓存机制不佳
整体 : 小巧、方便、高效、简单、直接(SQL操作)、半自动
Hibernate :
1 功能强大,数据库无关性好,对象关系(O/R)映射能力强,如果你对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽。
2 有更好的二级缓存机制,可以使用第三方缓存
3 缺点就是学习门槛不低,要精通门槛更高,而且怎么设计对象关系(O/R)映射,在性能和对象模型之间如何权衡取得平衡,以及怎样用好Hibernate方面需要你的经验和能力都很强才行
形象举例 :
mybatis:机械工具,使用方便,拿来就用,但工作还是要自己来作,不过工具是活的,怎么使用,由我决定。
hibernate:智能机器人,但研发它(学习、熟练度)的成本很高,工作都可以拜托给他了,但仅限于它能做的事。
5 配置文件
引入依赖
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
创建配置文件
在resource目录下创建mybatis-config.xml
<typeAlias type="com.tledu.zrz.model.User" alias="User"/>
<typeAlias type="com.tledu.zrz.model.Address" alias="Address"/>
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
创建jdbc.properties配置数据库
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=UTF-8
username=xxxx
password=xxxx
创建数据库操作的xml文件
<?xml version="1.0" encoding="UTF-8" ?> insert into t_user (username,password,nickname,type) values (#{username},#{password},#{nickname},#{type}) 如果想把xml文件放到java目录中,则需要在maven的build中配置资源路径 ... ... src/main/java **/*.properties **/*.xml false src/main/resources ... ...Mapper三种形式
常用的三种mapper
sqlSession执行对应语句,就是我们上面测试的那种
使用注解(简单sql)
利用接口代理(常用)
使用注解
注解方式不需要User.xml
需要再对应的接口上添加对应的注解语句
mybatis-config.xml中添加映射配置
在dao层接口上直接添加sql注解
public interface IUserMapper {
@Select("select * from t_user where id = #{id}")
User getById(int id);
}
利用接口代理(常用)
需要xml
接口中不需要添加注解
mybatis-config.xml中添加映射配置
创建User.xml
<insert id="add" parameterType="User" >
<!-- 这里的#username 就等于是用 ? 的方式,等方法调用的时候,会传递一个参数,就会自动映射到username的属性上 -->
insert into t_user (username,password,nickname) values (#{username},#{password},#{nickname})
</insert>
<select id="getList" resultType="User">
select * from t_user
</select>
<select id="getById" parameterType="int" resultType="User">
select * from t_user where id = #{id}
</select>
在mubatis-config.xml中配置
#和$的区别
#{}表示一个占位符号
通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,
#{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。
可以自动对值添加 ’ ’ 单引号
表
示
拼
接
s
q
l
串
通
过
{}表示拼接 sql 串 通过
表示拼接sql串通过{}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换,
可
以
接
收
简
单
类
型
值
或
p
o
j
o
属
性
值
,
如
果
p
a
r
a
m
e
t
e
r
T
y
p
e
传
输
单
个
简
单
类
型
值
,
{}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,
可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,{}括号中只能是 value。
比如order by id 这种的,以id排序 那么这个id 是没有单引号的,就是简单的SQL拼接,所以我们应该使用${} 而不是#{}
多个参数
当我涉及到多个参数传参的时候,这个时候,我们直接使用变量名会发现控制台有错误提示
Parameter ‘XXX’ not found. Available parameters are [arg1, arg0, param1, param2]
这一行报错的意思是XXX变量没有生命,我们可以用的变量名为arg1,arg0,param1,param2
当我们有多个变量的时候,我们就需要通过arg0,arg1来获取对应的变量了
内置api别名
resultType
resultType 属性可以指定结果集的类型,它支持基本类型和实体类类型。
需要注意的是,它和 parameterType 一样,如果注册过类型别名的,可以直接使用别名。没有注册过的必须
使用全限定类名。
同时,当是实体类名称是,还有一个要求,实体类中的属性名称必须和查询语句中的列名保持一致,否则无法实现封装。
resultMap
在声明返回值类型为实体类型之后,实体中的属性必须和查询语句中的属性对应上,但是我们在开发的过程中也难免会遇到无法对应的情况。比如说我们在进行数据库设计的时候,多个单词往往是用_连接,但是在实体类中的属性往往采用小驼峰的方式命名。这就导致字段名无法对应上,这个时候我们就需要配置resultMap来解决这个问题了。
通过resultMap,我们可以指定查询结果字段和实体属性字段的映射关系。
mybatis-config.xml 配置文件
创建db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/erp16?useUnicode=true&characterEncoding=UTF-8
username=root
password=root
typeAliases属性
mapper属性
Mappers是我们所说的映射器,用于通过mybatis配置文件去找到对应的mapper文件,关于这个属性有三种用法。
Resource
使用相对于类路径的资源如:
class
使用 mapper 接口类路径
如:
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
package
注册指定包下的所有 mapper 接口
如:
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中,并且这里如果希望能够扫描到包下面的xml文件的话,需要在maven中进行配置。