第1章 框架概述
1.1 软件开发常用结构
1.1.1 三层架构
三层架构包含的三层:
界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)
三层的职责
- 界面层(表示层,视图层):主要功能是接受用户的数据,显示请求的处理结果。使用 web 页面和
用户交互,手机 app 也就是表示层的,用户在 app 中操作,业务逻辑在服务器端处理。 - 业务逻辑层:接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据。
- 数据访问层:与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交
给业务层,同时将业务层处理的数据保存到数据库.
三层的处理请求的交互:
用户---> 界面层--->业务逻辑层--->数据访问层--->DB 数据库
如图:
为什么要使用三层?
- 结构清晰、耦合度低, 各层分工明确,
- 可维护性高 可扩展性高
- 有利于标准化
- 开发人员可以只关注整个结构中的其中某一层的功能实现
- 有利于各层逻辑的复用
1.1.2 常用框架
常见的 J2EE 中开发框架:
MyBatis 框架:
MyBatis 是一个优秀的基于 java 的持久层框架,内部封装了 jdbc,开发者只需要关注 sql 语句
本身,而不需要处理加载驱动、创建连接、创建 statement、关闭连接,资源等繁杂的过程。
MyBatis 通过 xml 或注解两种方式将要执行的各种 sql 语句配置起来,并通过 java 对象和 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java
对象并返回。
Spring 框架:
Spring 框架为了解决软件开发的复杂性而创建的。Spring 使用的是基本的 JavaBean 来完成以前
非常复杂的企业级开发。Spring 解决了业务对象,功能模块之间的耦合,不仅在 javase,web 中使用,
大部分 Java 应用都可以从 Spring 中受益。
Spring 是一个轻量级控制反转(IoC)和面向切面(AOP)的容器。
SpringMVC 框架
Spring MVC 属于 SpringFrameWork 3.0 版本加入的一个模块,为 Spring 框架提供了构建 Web
应用程序的能力。现在可以 Spring 框架提供的 SpringMVC 模块实现 web 应用开发,在 web 项目中
可以无缝使用 Spring 和 Spring MVC 框架。
1.2 框架是什么
1.2.1 框架定义
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方
法;另一种认为,框架是可被应用开发者定制的应用骨架、模板。
简单的说,框架其实是半成品软件,就是一组组件,供你使用完成你自己的系统。从另一个角度来
说框架一个舞台,你在舞台上做表演。在框架基础上加入你要完成的功能。
框架安全的,可复用的,不断升级的软件。
1.2.2 框架解决的问题
框架要解决的最重要的一个问题是技术整合,在 J2EE 的 框架中,有着各种各样的技术,不同的应
用,系统使用不同的技术解决问题。需要从 J2EE 中选择不同的技术,而技术自身的复杂性,有导致更
大的风险。企业在开发软件项目时,主要目的是解决业务问题。 即要求企业负责技术本身,又要求解
决业务问题。这是大多数企业不能完成的。框架把相关的技术融合在一起,企业开发可以集中在业务领
域方面。
另一个方面可以提供开发的效率。
1.3 JDBC 编程
1.3.1 用 使用 JDBC 编程的回顾
public void findStudent() {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//注册 mysql 驱动
Class.forName("com.mysql.jdbc.Driver");
//连接数据的基本信息 url ,username,password
String url = "jdbc:mysql://localhost:3306/springdb";
String username = "root";
String password = "123456";
//创建连接对象
conn = DriverManager.getConnection(url, username, password);
//保存查询结果
List<Student> stuList = new ArrayList<>();
//创建 Statement, 用来执行 sql 语句
stmt = conn.createStatement();
//执行查询,创建记录集,
rs = stmt.executeQuery("select * from student");
while (rs.next()) {
Student stu = new Student();
stu.setId(rs.getInt("id"));
stu.setName(rs.getString("name"));
stu.setAge(rs.getInt("age"));
//从数据库取出数据转为 Student 对象,封装到 List 集合
stuList.add(stu);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//关闭资源
if (rs != null) ;
{
rs.close();
}
if (stmt != null) {
stmt.close();
}
if (conn != null) {
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
1.3.2 用 使用 JDBC 的缺陷
- 代码比较多,开发效率低
- 需要关注 Connection ,Statement, ResultSet 对象创建和销毁
- 对 ResultSet 查询的结果,需要自己封装为 List
- 重复的代码比较多些
- 业务代码和数据库的操作混在一起
1.4 MyBatis 框架概述
MyBatis 框架:
MyBatis 本是 apache 的一个开源项目 iBatis, 2010 年这个项目由 apache software foundation 迁移到了 google code,并且改名为 MyBatis 。2013 年 11 月迁移到 Github。
iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于 Java 的持久层框架。iBATIS 提供的
持久层框架包括 SQL Maps 和 Data Access Objects(DAOs)
当前,最新版本是 MyBatis 3.5.1 ,其发布时间是 2019 年 4 月 8 日。
1.4.1 MyBatis 解决的主要问题
减轻使用 JDBC 的复杂性,不用编写重复的创建 Connetion , Statement ; 不用编写关闭资源代码。
直接使用 java 对象,表示结果数据。让开发者专注 SQL 的处理。 其他分心的工作由 MyBatis 代劳.
MyBatis 可以完成:
- 注册数据库的驱动,例如 Class.forName(“com.mysql.jdbc.Driver”))
- 创建 JDBC 中必须使用的 Connection , Statement, ResultSet 对象
- 从 xml 中获取 sql,并执行 sql 语句,把 ResultSet 结果转换 java 对象
List<Student> list = new ArrayLsit<>();
ResultSet rs = state.executeQuery(“select * from student”);
while(rs.next){
Student student = new Student();
student.setName(rs.getString(“name”));
student.setAge(rs.getInt(“age”));
list.add(student);
}
4.关闭资源ResultSet.close() , Statement.close() , Conenection.close()
第2章 MyBatis 框架快速入门
内容列表:
◼ 快速开始一个 MyBatis
◼ 基本 CURD 的操作
◼ MyBatis 内部对象分析
◼ 使用 Dao 对象
2.1 入门案例
MyBatis 开发准备
搭建 MyBatis 开发环境,实现第一个案例
2.1.1 使用 Mybatis 准备
下载 mybatishttps://github.com/mybatis/mybatis-3/releases
2.1.2 搭建 MyBatis 开发环境
1. 创建 mysql 数据库和表
数据库名 ssm ;表名 student
CREATE TABLE student (
id int(11) NOT NULL ,
name varchar(255) DEFAULT NULL,
email varchar(255) DEFAULT NULL,
age int(11) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2. 创建 maven 工程
创建 maven 工程,信息如下:
模板:
工程坐标:
3. 删除默认创建的 App 类文件
4. 加入 maven 坐标
pom.xml 加入 maven 坐标:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
</dependencies>
5. 加入 maven 插件
<build>
<resources>
<resource>
<directory>src/main/java</directory><!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
6. 编写 Student 实体类
创建包 com.g0rez.domain, 包中创建 Student 类
package com.g0rez.domain;
/**
* <p>Description: 实体类 </p>
*/
public class Student {
// 属性名和列名一样
private Integer id;
private String name;
private String email;
private Integer age;
// set ,get , toString
}
7.编写 Dao接口StudentDao
创建 com.g0rez.dao 包,创建 StudentDao 接口
package com.g0rez.dao;
import com.g0rez.domain.Student;
import java.util.List;
/*
* <p>Description: Dao 接口 </p>
*/
public interface StudentDao {
/* 查询所有数据*/
List<Student> selectStudents();
}
8.编写Dao接口Mapper映射文件StudentDao.xml
要求:
- 在 dao 包中创建文件 StudentDao.xml
- 要 StudentDao.xml 文件名称和接口 StudentDao 一样,区分大小写的一样。
<?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">
<!--
namespace :必须有值,自定义的唯一字符串
推荐使用: dao 接口的全限定名称
-->
<mapper namespace="com.g0rez.dao.StudentDao">
<!--
<select>: 查询数据, 标签中必须是 select 语句
id: sql 语句的自定义名称,推荐使用 dao 接口中方法名称,
使用名称表示要执行的 sql 语句
resultType: 查询语句的返回结果数据类型,使用全限定类名
-->
<select id="selectStudents" resultType="com.g0rez.domain.Student">
<!-- 要执行的 sql 语句 -->
select id,name,email,age from student
</select>
</mapper>
9.创建MyBatis主配置文件
项目 src/main 下创建 resources 目录,设置 resources 目录为 resources root
创建主配置文件:名称为 mybatis.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="mysql">
<!--id: 数据源的名称 -->
<environment id="mysql">
<!-- 配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回滚) -->
<transactionManager type="JDBC"/>
<!-- 数据源 dataSource :创建数据库 Connection 对象
type: POOLED 使用数据库的连接池
-->
<dataSource type="POOLED">
<!-- 连接数据库的四个要素 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 告诉 mybatis 要执行的 sql 语句的位置 -->
<mapper resource="com/g0rez/dao/StudentDao.xml"/>
</mappers>
</configuration>
10.创建测试类MyBatisTest
src/test/java/com/g0rez/ 创建 MyBatisTest.java 文件
/*
* mybatis 入门
*/
@Test
public void testStart() throws IOException {
//1.mybatis 主配置文件
String config = "mybatis-config.xml";
//2. 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
//3. 创建 SqlSessionFactory 对象, , 目的是获取 Sql Session
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//4. 获取 SqlSession,SqlSession 能执行 sql 语句
SqlSession session = factory.openSession();
//5. 执行 SqlSession 的 selectList()
List<Student> studentList =
session.selectList("com.g0rez.dao.StudentDao.selectStudents");
//6. 循环输出查询结果
studentList.forEach( student -> System.out.println(student));
//7. 关闭 SqlSession ,释放资源
session.close();
}
List<Student> studentList =
session.selectList("com.g0rez.dao.StudentDao.selectStudents");
//近似等价的 jdbc 代码
Connection conn = 获取连接对象
String sql=” select id,name,email,age from student”
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
11.配置日志功能
mybatis.xml 文件加入日志配置,可以在控制台输出执行的 sql 语句和参数
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
2.2 基本的 CURD
查询一个用selectOne
insert ,update ,delete
2.2.1 insert
1.StudentDao 接口中增加方法
int insertStudent(Student student);
2.StudentDao.xml 加入sql 语句
<insert id="insertStudent">
insert into student(id,name,email,age)
values(#{id},#{name},#{email},#{age})
</insert>
3.增加测试方法
@Test
public void testInsert() throws IOException {
//1.mybatis 主配置文件
String config = "mybatis-config.xml";
//2. 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
//3. 创建 SqlSessionFactory 对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//4. 获取 SqlSession
SqlSession session = factory.openSession();
//5. 创建保存数据的对象
Student student = new Student();
student.setId(1005);
student.setName(" 张丽");
student.setEmail("zhangli@163.com");
student.setAge(20);
//6. 执行插入 insert
int rows = session.insert(
"com.g0rez.dao.StudentDao.insertStudent",student);
//7. 提交事务
session.commit();
System.out.println(" 增加记录的行数:"+rows);
//8. 关闭 SqlSession
session.close();
}
2.2.2 update
1.StudentDao 接口中增加方法
int updateStudent(Student student);
2.StudentDao.xml 增加 sql 语句
<update id="updateStudent">
update student set age = #{age} where id=#{id}
</update>
3.增加测试方法
@Test
public void testUpdate() throws IOException {
//1.mybatis 主配置文件
String config = "mybatis-config.xml";
//2. 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
//3. 创建 SqlSessionFactory 对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//4. 获取 SqlSession
SqlSession session = factory.openSession();
//5. 创建保存数据的对象
Student student = new Student();
student.setId(1005);// 要修改的 id
student.setAge(30); // 要修改的年龄值
//6. 执行 更新 update
int rows = session.update(
"com.g0rez.dao.StudentDao.updateStudent",student);
//7. 提交事务
session.commit();
System.out.println(" 修改记录的行数:"+rows);
//8. 关闭 SqlSession
session.close();
}
2.2.3 delete
1.StudentDao 接口中增加方法
int deleteStudent(int id);
2.StudentDao.xml增加sql语句
<delete id="deleteStudent">
delete from student where id=#{studentId}
</delete>
3.增加测试方法
@Test
public void testDelete() throws IOException {
//1.mybatis 主配置文件
String config = "mybatis-config.xml";
//2. 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
//3. 创建 SqlSessionFactory 对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//4. 获取 SqlSession
SqlSession session = factory.openSession();
//5. 删除的 id
int id = 1001;
//6. 执行删除 delete
int rows = session.delete(
"com.g0rez.dao.StudentDao.deleteStudent",id);
//7. 提交事务
session.commit();
System.out.println(" 修改记录的行数:"+rows);
//8. 关闭 SqlSession
session.close();
}
2.3 MyBatis 对象分析
2.3.1 对象使用
SqlSession , SqlSessionFactory 等
1.Resources类
Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返
回不同类型的 IO 流对象。
2.SqlSessionFactoryBuilder类
SqlSessionFactory 的 创 建 , 需 要 使 用 SqlSessionFactoryBuilder 对 象 的 build() 方 法 。 由 于
SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将
该 SqlSessionFactoryBuilder 对象创建为一个方法内的局部对象,方法结束,对象销毁。
3.SqlSessionFactory接口
SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用
只需要一个该对象即可。创建 SqlSession 需要使用 SqlSessionFactory 接口的的 openSession()方法。
openSession(true):创建一个有自动提交功能的 SqlSession
openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交
openSession():同 openSession(false)
4.SqlSession接口
SqlSession 接口对象用于执行持久化操作。一个 SqlSession 对应着一次数据库会话,一次会话以
SqlSession 对象的创建开始,以 SqlSession 对象的关闭结束。
SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将
其关闭。再次需要会话,再次创建。 SqlSession 在方法内部创建,使用完毕后关闭。
2.3.2 创建工具类
1.创建 MyBatisUtil 类
package com.g0rez.common;
/**
* <p>Description: 实体类 </p>
*/
public class MyBatisUtil {
// 定义 SqlSessionFactory
private static SqlSessionFactory factory = null;
static {
// 使用 静态块 创建一次 SqlSessionFactory
try{
String config = "mybatis-config.xml";
// 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
// 创建 SqlSessionFactory 对象
factory = new SqlSessionFactoryBuilder().build(in);
}catch (Exception e){
factory = null;
e.printStackTrace();
}
}
/* 获取 SqlSession 对象 */
public static SqlSession getSqlSession(){
SqlSession session = null;
if( factory != null){
session = factory.openSession();
}
return session;
}
}
2.使用MyBatisUtil类
@Test
public void testUtils() throws IOException {
SqlSession session = MyBatisUtil.getSqlSession();
List<Student> studentList = session.selectList(
"com.g0rez.dao.StudentDao.selectStudents");
studentList.forEach( student -> System.out.println(student));
session.close();
}