Mybatis 框架
第1章 框架概述
1.1 什么是框架
1.1.1 什么是框架
框架(Framework)是整个或部分系统的可重⽤设计,表现为⼀组抽象构件及构件实例间交互的⽅法;另⼀种定义认为,框架是可被应⽤开发者定制的应⽤骨架。前者是从应⽤⽅⾯⽽后者是从⽬的⽅⾯给出的定义。
简⽽⾔之,框架其实就是某种应⽤的半成品,就是⼀组组件,供你选⽤完成你⾃⼰的系统。简单说就是使⽤别⼈搭好的舞台,你来做表演。⽽且,框架⼀般是成熟的,不断升级的软件。
1.1.2 框架要解决的问题
框架要解决的最重要的⼀个问题是技术整合的问题,在 J2EE 的 框架中,有着各种各样的技术,不同的软件企业需要从 J2EE 中选择不同的技术,这就使得软件企业最终的应⽤依赖于这些技术,技术⾃身的复杂性和技术的⻛险性将会直接对应⽤造成冲击。⽽应⽤是软件企业的核⼼,是竞争⼒的关键所在,因此应该将应⽤⾃身的设计和具体的实现技术解耦。这样,软件企业的研发将集中在应⽤的设计上,⽽不是具体的技术实现,技术实现是应⽤的底层⽀撑,它不应该直接对应⽤产⽣影响。
框架⼀般处在低层应⽤平台(如 J2EE**)和⾼层业务逻辑之间的中间层。
1.1.3 软件开发的分层重要性
框架的重要性在于它实现了部分功能,并且能够很好的将低层应⽤平台和⾼层业务逻辑进⾏了缓和。为了实现软件⼯程中的“⾼内聚、低耦合”。把问题划分开来各个解决,易于控制,易于延展,易于分配资源。我们常⻅的MVC 软件设计思想就是很好的分层思想。
1.1.4 分层开发下的常⻅框架
常⻅的 JavaEE 开发框架:
1、解决数据的持久化问题的框架
作为持久层的框架,还有⼀个封装程度更⾼的框架就是Hibernate,但这个框架因为各种原因⽬前在国内的流⾏程度下降太多,现在公司开发也越来越少使⽤。⽬前使⽤ Spring Data 来实现数据持久化也是⼀种趋势。
2、解决 WEB 层问题的 MVC 框架
3、解决技术整合问题的框架
1.1.5 MyBatis 框架概述
mybatis 是⼀个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,⽽不需要花费精⼒去处理加载驱动、创建连接、创建 statement 等繁杂的过程。
mybatis 通过 xml 或注解的⽅式将要执⾏的各种 statement 配置起来,并通过 java 对象和 statement 中
sql 的动态参数进⾏映射⽣成最终执⾏的 sql 语句,最后由 mybatis 框架执⾏ sql 并将结果映射为 java 对象并返回。
采⽤ ORM 思想解决了实体和数据库映射的问题,对 jdbc 进⾏了封装,屏蔽了 jdbc api 底层访问细节,使我们不⽤与 jdbc api 打交道,就可以完成对数据库的持久化操作。
1.2 JDBC 编程的分析
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//通过驱动管理类获取数据库链接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?
characterEncoding=utf-8","ro ot", "root");
//定义 sql 语句 ?表示占位符
//参数值
//获取预处理 statement
preparedStatement = connection.prepareStatement(sql);
//设置参数,第⼀个参数为 sql 语句中参数的序号(从 1 开始),第⼆个参数为设置的
preparedStatement.setString(1, "王五");
//向数据库发出 sql 执⾏查询,查询出结果集resultSet = preparedStatement.executeQuery();
//遍历查询结果集
while(resultSet.next()){
System.out.println(resultSet.getString("id")+""+resultSet.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
if(resultSet!=null){ try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) { e.printStackTrace();
}
}
if(connection!=null){ try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block e.printStackTrace();
}
}
}
}
上边使⽤ jdbc 的原始⽅法(未经封装)实现了查询数据库表记录的操作。
1.2.2 jdbc 问题分析
1、数据库链接创建、释放频繁造成系统资源浪费从⽽影响系统性能,如果使⽤数据库链接池可解决此问题。
2、Sql 语句在代码中硬编码,造成代码不易维护,实际应⽤ sql 变化的可能较⼤,sql 变动需要改变 java
代码。
3、使⽤ preparedStatement 向占有位符号传参数存在硬编码,因为 sql 语句的 where 条件不⼀定,可能多也可能少,修改 sql 还要修改代码,系统不易维护。
4、对结果集解析存在硬编码(查询列名),sql 变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成 pojo 对象解析⽐较⽅便。
第2章 Mybatis 框架快速⼊⻔
通过前⾯的学习,我们已经能够使⽤所学的基础知识构建⾃定义的 Mybatis 框架了。这个过程是基本功的考验,我们已经强⼤了不少,但现实是残酷的,我们所定义的 Mybatis 框架和真正的 Mybatis 框架相⽐,还是显得渺⼩。⾏业内所流⾏的 Mybatis 框架现在我们将开启学习。
2.1 Mybatis 框架开发的准备
2.1.1 官⽹下载 Mybatis 框架
从百度中“mybatis download”可以下载最新的 Mybatis 开发包。
我们所使⽤的 Mybatis 版本是 3.4.5 版本。
2.2 搭建 Mybatis 开发环境
2.2.1 创建 maven ⼯程
2.2.2 添加 Mybatis3.4.5 的坐标
在 pom.xml ⽂件中添加 Mybatis3.4.5 的坐标,如下:
<dependencies>
<dependency>
<groupId>org.mybatis</groupId><artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
2.2.3 编写 User 实体类
package com.soft.domain;
import java.util.Date;public class User {
private long id;
private String username;
//这⾥要改成java的类型
private Date birthday;
private String sex;
private String address;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
} public void setAddress(String address) {
this.address = address;
}
}
2.2.4 编写持久层接⼝ IUserDao
IUserDao 接⼝就是我们的持久层接⼝(也可以写成 UserDao 或者 UserMapper),具体代码如下:
public interface IUserDao {
/**
\* 查询所有⽤户
\* **@return**
*/
List<User> findAll();
}
2.2.5 编写持久层接⼝的映射⽂件 IUserDao.xml
要求:
**创建位置:**必须和持久层接⼝在相同的包中。
**名称:**必须以持久层接⼝名称命名⽂件名,扩展名是.xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace对象的映射的接⼝-->
<mapper namespace="com.soft.dao.IUserDao">
<!--id对应接⼝的⽅法-->
<!--resultType把结果封装对象类型-->
<select id="findAll" resultType="com.soft.domain.User">
select * from USER;
</select>
</mapper>
2.2.6 编写 SqlMapConfig.xml 配置⽂件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置 mybatis 的环境 -->
<environments default="development">
<!-- 配置 mysql 的环境 -->
<environment id="development">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"/>
<!-- 配置连接数据库的信息:⽤的是数据源(连接池) -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/smm"/>
<property name="username" value="root"/>
<property name="password" value="12345678"/>
</dataSource>
</environment>
</environments>
<!-- 告知 mybatis 映射配置的位置 -->
<mappers>
<mapper resource="com/soft/dao/IUserDao.xml"/>
</mappers>
</configuration>
2.2.7 编写测试类
public class MyBatisTest {
public static void main(String[] args) throws IOException {
//1.读取配置⽂件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建 SqlSessionFactory 的构建者对象 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.使⽤构建者创建⼯⼚对象 SqlSessionFactory
SqlSessionFactory factory = builder.build(in);
//4.使⽤ SqlSessionFactory ⽣产 SqlSession 对象
SqlSession session = factory.openSession();
//5.使⽤ SqlSession 创建 dao 接⼝的代理对象
IUserDao userDao = session.getMapper(IUserDao.class);
//6.使⽤代理对象执⾏查询所有⽅法
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
//7.释放资源
session.close();
in.close();
}
}
2.3 ⼩结
通过快速⼊⻔示例,我们发现使⽤ mybatis 是⾮常容易的⼀件事情,因为只需要编写 Dao 接⼝并且按照
mybatis 要求编写两个配置⽂件,就可以实现功能。远⽐我们之前的 jdbc ⽅便多了。(我们使⽤注解之后,将变得更为简单,只需要编写⼀个 mybatis 配置⽂件就够了。)
2.4 补充(基于注解的 mybatis 使⽤)
2.4.1 在持久层接⼝中添加注解
package com.soft.dao;
import com.soft.domain.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface IUserDao {
@Select("select * from user")
List<User> findAll();
}
2.4.2 修改 SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置 mybatis 的环境 -->
<environments default="development">
<!-- 配置 mysql 的环境 -->
<environment id="development">
<!-- 配置事务的类型 -->
<transactionManager type="JDBC"/>
<!-- 配置连接数据库的信息:⽤的是数据源(连接池) -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/smm"/>
<property name="username" value="root"/>
<property name="password" value="12345678"/>
</dataSource>
</environment>
</environments>
<!-- 告知 mybatis 映射配置的位置 -->
<mappers>
<!--<mapper resource="com/soft/dao/IUserDao.xml"/>-->
<mapper class="com.soft.dao.IUserDao"/>
</mappers>
</configuration>
2.4.3 注意事项:
在使⽤基于注解的 Mybatis 配置时,请移除 xml 的映射配置(IUserDao.xml)。