【MyBatis 基础】


【MyBatis 框架简介】
MyBatis 是用于访问数据库的技术
MyBatis 封装了对象和数据表记录之间的映射工作
使用 MyBatis 时,需要指定 SQL,
其它诸如,获取连接、执行 SQL 、释放连接等操作,都由 MyBatis 完成 。
【什么是 MyBatis】
1、MyBatis 原本是 apache 的一个 开源项目 iBatis ,
2010 年,该项目由 apache software foundation 迁移到了 google code ,
并且改名为 MyBatis ;
2、MyBatis 是支持普通 SQL ,存储过程 ,和高级映射的优秀持久层框架。
MyBatis 封装了几乎所有的 JDBC 代码和参数的手工设置,以及结果集的检索。
3、MyBatis 使用简单的 XML 或注解做配置和定义映射关系,
将 Java 的 POJOs(Plain Old Java Objects),
映射成数据库中的记录。
【MyBatis 体系结构】/【MyBatis 映射过程的实现】
MyBatis 体系结构主要有以下几个关键部分:
1、加载配置
配置有两种形式:
a、XML 配置文件
b、Java 代码的注解
MyBatis 将 SQL 的配置信息,
加载成一个个 MappedStatement 对象,
并将其存储在内存中。
SQL 的配置信息包括:
a、传入参数映射配置
b、执行的 SQL 语句
c、结果映射配置
2、SQL 解析
当 API 接口层,接收到调用请求时(调用 dao 即 mapper 接口中的抽象方法),
会接收传入 的 SQL ID (就是 DAO 接口的抽象方法名)
和传入的参数对象(DAO 接口抽象方法中的参数)
(该对象可以是:Map、JavaBean 或者基本数据类型),
MyBatis 会根据 SQL 的 ID 找到对应的 MappedStatement 对象,
然后根据传入参数对象,对 MappedStatement 进行解析,
解析后可以得到最终要执行的 SQL 语句和参数。
3、SQL 执行
将最终得到的 SQL 和参数,在数据库中执行,得到操作数据库的结果。
4、结果映射
将操作数据库的结果,按照映射的配置进行转换,
可以转换成 HashMap、JavaBean 或者基本数据类型,
并将最终结果返回。
【MyBatis 体系结构图的理解】
数据输入 -> (MyBatis-->DB) -> 数据输出
MyBatis 在使用时,可以接收 Java 对象、Map 、简单类型的数据,
接着对数据库操作,
最后还可以返回 Java 对象、Map 、简单类型的结果。
例如:
查询整条记录 -> 返回 Java 对象
查询部分字段 -> 返回 Map
查询记录数 -> 返回 int 
------------------------------------------
插入操作:
输入 Emp 对象 -> MyBatis -> DB -> 输出 int
查询操作:
输入 empNo -> MyBatis -> DB -> 输出 Emp 对象
【MyBatis 配置文件】
MyBatis 的 XML 配置文件包含以下 2 种类型:
1) SqlMapConfig.xml (仅1个)
主配置文件,用于指定数据库连接参数和框架参数。
示例:
<configuration>
<environments default="environment"> 
<environment id="environment"> 
<transactionManager type="JDBC"/>
<dataSource>
<property name="driver" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@localhost:tarena10g" />
<property name="username" value="demo" />
<property name="password" value="demo" />
</dataSource>
</environment> 
</environments> 
</configuration>
2) SqlMap.xml (一个表一个)
映射定义库文件,用于定义 SQL 语句和映射信息。
如:EmpMap.xml/DeptMap.xml
示例:
<mapper>
<insert id="addDept" parameterType="Dept">
insert into DEPT(DEPTNO,DNAME,LOC)
values(#{deptNo},#{dName},{loc})
</insert>
<select id="findAll1" resultMap="deptMap">
select DEPTNO,DNAME,LOC from DEPT
</select>
<resultMap id="deptMap" type="org.tarena.entity.Dept1">
<result property="no" column="DEPTNO" />
<result property="name" column="DNAME" />
<result property="loc" column="LOC" />
</reusltMap>
</mapper>
【MyBatis 框架 API 简介】
在使用 MyBatis 框架时,主要涉及以下几个 API :
SqlSessionFactoryBuilder
该对象负责根据 MyBatis 配置文件 SqlMapConfig.xml
构建 SqlSessionFactory 实例。
SqlSessionFactory
每一个 MyBatis 的应用程序都以一个 SqlSessionFactory 对象为核心。
该对象负责创建 SqlSession 对象实例。
SqlSession 
该对象包含了所有执行 SQL 操作的方法,用于执行已映射的 SQL 语句。
【MyBatis 基础应用】
【搭建 MyBatis 技术环境】
在使用 MyBatis 之前,需要将 MyBatis 框架添加到工程项目中。
主要步骤如下:
为工程添加 MyBatis 开发包和数据库驱动包 。
在 src 下,添加 MyBatis 配置文件 SqlMapConfig.xml 。
修改 SqlMapConfig.xml ,指定数据库连接参数。
利用 MyBatis API 编程,获取 SqlSession 实例。
【获取 SqlSession 对象】
【#案例】
/MyBatis/src/org/tarena/test/SqlSessionTest.java
示例:
// 【警告】:不能加斜杠"/SqlMapConfig.xml" 
String conf = "SqlMapConfig.xml";
Reader reader = Resources.getResourceAsReader(conf);

// 创建 SessionFactory 对象
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
SqlSessionFactory ssf = ssfb.build(reader);

// 创建 SqlSession 
SqlSession sqlSession = ssf.openSession();

// 关闭 SqlSession 
sqlSession.close();
【MyBatis 使用步骤】
DEPT 表
DEPTNO NUMBER(2) 部门编号
DNAME VARCHAR2() 部门名称
LOC VARCHAR2() 部门所在地(location)
建表语句 - 【#详见】:
/MyBatis/WebRoot/WEB-INF/db/dept.sql
1.引入 MyBatis 开发包和数据库驱动包
2.在 src 下添加 SqlMapConfig.xml 主配置,指定数据库连接参数
3.获取 SqlSession 对象
-----对 DEPT 表操作-----
4.编写 Dept 实体类
5.编写 DeptMap.xml 配置文件(SQL 操作语句)
    (注意:在 SqlMapConfig.xml 中定义 DeptMap.xml)
6.利用 SqlSession 对象的方法操作

select * from dept limit 0,5 (mysql)
select *  from
(select * from dept order by deptno)
where rownum<=${limit};
【利用 SqlSession 实现 CRUD 操作】
【#详见】【#案例】
/MyBatis/src/org/tarena/test/MyBatisDMLTest.java
/MyBatis/src/org/tarena/entity/DeptMap.xml
【利用 MyBatis 实现分页查询】
在使用 SqlSession 的 selectList() 方法时,
指定一个 RowBounds 分页参数,即可查询指定范围的记录。
1、RowBounds(offset,limit) 构造器
RowBounds bounds = RowBounds(offset,limit);
- offset: 指定抓取记录的起始行,从 0 开始 。
- limit: 指定抓取记录的数量
2、selectList() 使用方法
sqlSession.selectList(SQL 的 ID, 查询条件参数, RowBounds 对象);
【提示】:
MyBatis 分页是基于内存的分页,原理是:
查询出所有记录,
再基于 JDBC 的 absolute() 和 next() 方法,
定位获取部分记录。
所以,在遇到大量数据情况下,不推荐使用 MyBatis 自带分页功能,否则易造成内存溢出。
需要开发者指定分页查询的 SQL 语句,或对 MyBatis 进行扩展使用。
【假分页】
原理很简单:
不是真正的在数据库里进行过滤,而是从数据库查询之后,
返回全部结果,并以集合形式保存在内存中,
分页实际上只是对该集合进行操作。
优点是兼容所有 JDBC 数据库,缺点是这种方法不适用于大批量数据。
MyBatis 自带的分页功能,就属于 “假分页” 。
【返回 Map 类型查询结果】
SqlMap.xml 映射定义
<select id="findDept" parameterType="int" resultType="java.util.HashMap">
select DEPTNO,DNAME from DEPT where DEPTNO=#{no}
</select>
SqlSession 的用法
SqlSession session = sf.openSession();
Map map = (Map)session.selectOne("findDept",10);
【使用 Mapper 映射器】
【#案例】:
/MyBatis/src/org/tarena/mapper/DeptMapper.java
/MyBatis/src/org/tarena/test/MapperTest.java
Mapper 映射器,是开发者创建绑定映射语句的接口,
映射器接口的实例可以从 SqlSession 中获得。
示例:
SqlSession session = sqlSessionFactory.openSession();
try{
DeptMapper mapper = session.getMapper(DeptMapper.class);
// do work
}finally{
session.close();
}
小结:
Mapper 映射器绑定了 Sql 操作之后,
将动态地生成以下案例中的,SqlSession 对象的 "增删改查" 操作,
【#案例】/MyBatis/src/org/tarena/test/MyBatisDMLTest.java
如:
sqlSession.insert ...
sqlSession.update ...
sqlSession.delete ...
sqlSession.selectOne ...
sqlSession.selectList ...
【ResultMap 映射定义】
在 SqlMap.xml 定义 <select> 操作时,
若 “查询结果” 的字段名,与 Java POJO 属性不一致,
则有 2 种解决办法:
方法1、采用 ResultMap 映射定义
使用 <resultMap> 元素,显示指定映射关系。
示例:
<!-- select 标签的 resultMap 属性值,与 resultMap 标签的 id 属性值一致。-->
<select id="findAll1" resultMap="deptMap">
select DEPTNO,DNAME,LOC from DEPT
</select>

<resultMap id="deptMap" type="org.tarena.entity.Dept">
<result property="no" column="DEPTNO" />
<result property="name" column="DNAME" />
<result property="loc" column="LOC" />
</resultMap>
方法2、可以在 sql 语句中,采用别名,使查询结果字段的别名与实体类属性一致(忽略大小写)即可。


ORM 
- Object Relation Mapping 
- 对象关系映射 
- Java 对象与关系型数据库之间的映射
大数据
非关系型数据库,如:NoSql 数据库。


----------------------------------
【MyBatis 映射文件中的 "#" 与 "$" 的区别】
通过 parameterType 属性,结合 "#{}" 或 "${}" 表达式,可以给 SQL 语句传值。
"#{}" :
传进来的值必定是字符串类型,而且会在 sql 中生成 "?" ,
形成预编译语句,可以防止 SQL 注入。
"${}" :
传进来的值的类型与它原来的类型一致。
不能防止 SQL 注入。
尽量使用 "#{}" 来传值。
【MyBatis 模糊查询的几种方式】
【#案例】
/NETCTOSS_SpringMVC_MyBatis_Restful/src/org/tarena/netctoss/entity/AccountMap.xml
1. sql 中字符串拼接
  SELECT * FROM tableName WHERE name LIKE CONCAT(CONCAT('%', #{text}), '%');
2. 使用 ${...} 代替 #{...}
  SELECT * FROM tableName WHERE name LIKE '%${text}%'; 
3. 程序中拼接
Java
// or String searchText = "%" + text + "%";
String searchText = new StringBuilder("%").append(text).append("%").toString();
parameterMap.put("text", searchText);
SqlMap.xml
  SELECT * FROM tableName WHERE name LIKE #{text};
异常:
java.lang.IllegalArgumentException: modify is ambiguous in Mapped Statements collection (try using the full name including the namespace, or rename one of the entries)
at org.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:466)
at org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:349)
at org.apache.ibatis.binding.MapperMethod.setupCommandType(MapperMethod.java:137)
at org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:46)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:34)
at $Proxy10.modify(Unknown Source)

抛出这个异常的原因,
可能是因为 mapper.xml 配置文件中 ,
<mapper> 的 namespace 属性配置错误造成的,
没有根据命名空间的值(全称类名)找到相应映射接口。
如:
<mapper namespace="com.xxx.xxx.mapper.TestMapper" >














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值