【MyBatis】01 - MyBatis入门
1. 认识MyBatis
1.1 什么是框架 ?
-
它是我们软件开发中的一套解决方案,不同的框架解决的是不同的问题。
-
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种定义认为,框架是可被应用开发者定制的应用骨架。前者是从应用方面而后者是从目的方面给出的定义。
-
简而言之,框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。简单说就是使用别人搭好的舞台,你来做表演。而且,框架一般是成熟的,不断升级的软件。
1.2 三层架构
-
表现层 : 用于展示数据的;
-
业务层:是处理业务需求;
-
持久层: 是和数据库交互的;
1.3 持久层技术解决方案
-
JDBC技术 :Connection 、 PrepareStatement 、ResultSet;
-
Spring的JdbcTemplate: spring中对jdbc的简单封装 。
-
Apache 的DBUtils :它和Spring的jdbcTemplate很像,都是对jdbc的简单封装;
-
以上都不是框架 ,JDBC是规范,Spring 的JdbcTemplate和Apache的DBUtils都只是工具类。
1.4 JDBC编程分析
1.4.1 JDBC程序回顾
/**
* JDBC回顾
*/
public class JdbcTest {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement statement = null;
ResultSet set = null;
try {
// 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 通过驱动管理类获取数据库连接
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "root");
// 定义sql语句 ? 表示占位符
String sql = "select * from user where username = ?";
// 获取预处理 statement
statement = conn.prepareStatement(sql);
// 设置参数 第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
statement.setString(1, "老王");
// 向数据库发出SQL执行,查询出结果集
set = statement.executeQuery();
// 遍历结果集
while (set.next()) {
System.out.println(" id :" + set.getInt("id") + "\t username: " + set.getString("username")
+ "\tbirthday: " + set.getDate("birthday"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (set != null) {
try {
set.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
1.5 MyBatis框架概述
-
mybatis 是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。
-
mybatis 通过 xml 或注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。
-
采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。
-
为了我们能够更好掌握框架运行的内部过程,并且有更好的体验,下面我们将从自定义 Mybatis 框架开始来学习框架。此时我们将会体验框架从无到有的过程体验,也能够很好的综合前面阶段所学的基础。
-
总结 : MyBatis是一个持久层框架,用Java编写 。它是封装了jdbc操作的很多细节,使开发者只需关注sql语句本身,而无需关注注册驱动,创建连接等繁杂的过程。它使用了ORM思想结果集的封装。
-
ORM 思想 :Object Relational Mapping 对象关系映射 。 简单的说就是把数据库表和实体类的属性对应起来,让我们可以操作实体类就实现操作数据库。
2. MyBatis 入门案例 (使用xml配置文件的方式)
2.1 创建一个工程
- 创建一个Maven工程不使用骨架
- 填写GroupId(域名反写) 和 ArtifactId(工程名称)
- 修改项目的打包方式为Jar 包 。在pom.xml文件中加上如下的打包方式:
<packaging>jar</packaging>
- 导入MyBatis依赖 、 Mysql驱动、log4j依赖、junit依赖。
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
- MyBatis官网地址 :https://mybatis.org/mybatis-3/zh/index.html
2.2 建立需要使用的数据库表
- 创建学习中需要使用的到的数据库及表。并导入数据。
CREATE DATABASE mybatis CHARACTER SET utf8;
USE mybatis;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`username` VARCHAR(32) NOT NULL COMMENT '用户名称',
`birthday` DATETIME DEFAULT NULL COMMENT '生日',
`sex` CHAR(1) DEFAULT NULL COMMENT '性别',
`address` VARCHAR(256) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user`(`id`,`username`,`birthday`,`sex`,`address`) VALUES (41,'老王','2018-02-27 17:47:08','男','北京'),(42,'小二王','2018-03-02 15:09:37','女','北京金燕龙'),(43,'小二王','2018-03-04 11:34:34','女','北京金燕龙'),(45,'传智播客','2018-03-04 12:04:06','男','北京金燕龙'),(46,'老王','2018-03-07 17:37:26','男','北京'),(48,'小马宝莉','2018-03-08 11:44:00','女','北京修正');
- 使用传统的jdbc方式操作数据库查询数据
- 加载数据库驱动 ;
- 通过驱动管理类获取到数据库连接;
- 定义SQL ,使用 ? 表示占位符;
- 获取预处理对象;
- 使用预处理对象设置查询参数;
- 向数据库发出sql执行 ,获取结果集;
- 遍历结果集。
2.3 mybatis 环境搭建
2.3.1 创建实体类
- 注意创建的实体类属性名称需要与数据库保持
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
// 省略setter 和 getter 方法
// 省略 toString方法
}
2.3.2 创建dao层接口
public interface UserDao {
/**
* 查询所用用户信息
* @return
*/
List<User> findAll();
}
2.3.3 在resources文件夹下创建全局配置文件 SqlMapConfig.xml
- 在resources文件夹下创建一个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">
- 配置mysql环境 、 配置事务类型 、 配置数据库连接池(数据源)、配置数据库的4个基本信息
<?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">
<!-- mybatis的主配置文件 -->
<configuration>
<!-- 配置环境 -->
<environments default="mysql">
<!-- 配置mysql的环境-->
<environment id="mysql">
<!-- 配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置数据源(连接池) -->
<dataSource type="POOLED">
<!-- 配置连接数据库的4个基本信息 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
<mappers>
<mapper resource="com/lyp/dao/UserDao.xml"/>
</mappers>
</configuration>
2.3.4 创建UserDao接口所对应的映射配置文件
- 在resources目录下,创建和UserDao相同目录结构的目录并创建和UserDao同名的UserDao.xml配置文件。
- 在配置文件中使用约束 :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
- 映射配置文件中的配置 :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lyp.dao.UserDao">
<select id="findAll" resultType="com.lyp.domain.User">
select * from user ;
</select>
</mapper>
2.3.5 在以上的操作中的注意事项
- 在IDEA中创建目录的时候和创建包的方式是不一样的。
- MyBatis的映射配置文件位置,必须和dao接口的包结构相同。
- 映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名。
- 映射配置文件的操作配置,id属性的取值必须是到接口的方法名称。
- 当遵从了 2 ,3,4,5点之后我们在开发中无须再写dao的实现类。
2.3.6 创建测试类进行测试
创建测试类进行测试/**
* Mybatis 入门案例
*/
public class MybatisDemoTest01 {
public static void main(String[] args) throws IOException {
// 1. 读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2. 创建 SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
// 3. 使用工厂生产SqlSession对象
SqlSession sqlSession = factory.openSession();
// 4. 使用SqlSession创建dao接口代理对象
UserDao userDao = sqlSession.getMapper(UserDao.class);
// 5. 使用代理对象执行方法
List<User> userList = userDao.findAll();
for (User user : userList) {
System.out.println(user);
}
// 6. 释放资源
sqlSession.close();
in.close();
}
}
2.3.7 项目远程地址
3. Mybatis 入门 (使用注解的方式)
3.1 同上 创建一个项目 并 导入相关依赖
-
将UserDao.xml映射配置文件移除,在dao接口的方法上使用@Select注解,并且指定SQL语句,同时需要在SqlMapconfig.xml中的mapper配置时,使用class属性指定dao接口的全限定类名。
使用注解开发的时候需要使用mapper的class属性在标签中指定dao的全限定类名 -
在UserDao接口的方法上使用@Select 注解并写上sql语句
/**
* 查询所用用户信息
* @return
*/
@Select("select * from user")
List<User> findAll();
4. Mybatis入门 编写 dao 实现类的方式
-
该案例的主要目的:了解Userdao.xml配置文件中mapper标签的namespace属性作用 。
-
依旧在 第一个项目 (基于xml的Mybatis入门案例)的基础上进行实现。
-
编写 UserDao 的实现类 :
public class UserDaoImpl implements UserDao {
// 需要使用构造方法传递 factory 工厂到实现类中
private SqlSessionFactory factory;
public UserDaoImpl(SqlSessionFactory factory) {
this.factory = factory;
}
public List<User> findAll() {
// 使用工厂创建SqlSession对象
SqlSession session = factory.openSession();
return session.selectList("com.lyp.dao.UserDao.findAll");
}
}
- 更改测试类 使用实现类创建UserDao对象 调用findAll方法查询 :
/**
* Mybatis 入门案例 使用自定义实现类的方式
*/
public class MybatisDemoTest01 {
public static void main(String[] args) throws IOException {
// 1. 读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2. 创建 SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
// 3. 使用自定义实现类的方式实现对数据库的查询 在实现类中使用 SqlSession的 selectList方法查询
UserDao userDao = new UserDaoImpl(factory);
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
// 6. 释放资源
in.close();
}
}
- 在实现类中是如何找到我们在映射配置文件中编写的sql语句的 ?
5. Mybatis入门案例中设计模式分析
入门案例中设计模式的分析6. 自定义MyBatis的分析
6.1 mybatis在使用代理dao的方式实现增删改查时做了什么事?
-
创建代理对象;
-
在代理对象中调用selectList方法;