Mybatis-入门案例
1-框架概念
程序开发中的框架往往是对常见功能的封装,程序框架理解为基础或者机械标准件(例如螺丝螺母标准的机械部件)。
假如你要造一辆马车,在没有框架的情况下,你需要自己去伐木,去把木头做成木板,木棍,然后组成轮子,门,等部件,然后组装起来。但如果你用了框架,就相当于你有现成的轮子,门等部件,你只需要组装一下就可以了。一个框架是一组可复用的设计构件。
框架(Framework):是整个或者部分系统的可重用设计,是JavaEE底层技术的封装。框架是可以被开发者定制的应用骨架。框架是一个半成品,软件是成品。
2-三层结构
2.1分层方式
一个中大型软件开发需要有明确分层。
分层包 | 功能描述 | 作用 |
---|---|---|
cn.guardwhy.view | 表示层 View | 面向客户,用于处理客户的输入和输出,前端的代码。 |
cn.guardwhy.service | 业务层 Service | 处理业务逻辑代码,如:登录,转账,挂号 |
cn.guardwhy.dao | 数据访问层 DAO Data Access Object | 也叫持久层。面向数据库,实现对数据库增删改查操作 |
2.2 分层的优缺点
优点:
- 降低了代码的耦合度,降低类与类之间关系。有利于团队的开发。
- 项目的可扩展性更好,可维护性更好。
- 可重用性更好,同一个方法可以由多个类去调用。
缺点:
- 执行效率更低,开发工作量更大
- 会导致级联的修改,如果修改一个功能,导致三层都要进行修改。
3-mybatis简介
3.1 什么是Mybatis
- MyBatis 是一款优秀的持久层框架。
- MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程。
- MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 【Plain Old Java Objects,普通的 Java对象】映射成数据库中的记录。
- MyBatis 本是apache的一个开源项目ibatis, 2010年这个项目由apache 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
3.2 持久化
持久化是将程序数据在持久状态和瞬时状态间转换的机制。
即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。JDBC就是一种持久化机制。文件IO也是一种持久化机制。
为什么需要持久化服务呢?
- 有一些对象,不能让它消失。
- 内存价格昂贵。
持久层
- 完成持久化工作的代码块 . ----> dao层 (DAO (Data Access Object) 数据访问对象)
- 大多数情况下,数据持久化往往也就意味着将内存中的数据保存到磁盘上加以固化,而持久化的实现过程则大多通过各种关系数据库来完成。
- 与系统其他部分相对而言,这个层面应该具有一个较为清晰和严格的逻辑边界。 说白了就是用来操作数据库的。
3.3 mybatis的优缺点
优点
- 简单易学:mybatis本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个SQL映射文件即可。
- 使用灵活:Mybatis不会对应用程序或者数据库的现有设计强加任何影响。SQL语句写在XML里,便于统一管理和优化。
- 解除SQL与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易进行单元测试。
缺点
- 编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
- SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
- 框架还是比较简陋,功能尚有缺失,二级缓存机制不佳。
3.4 ORM的概念
Object Relational Mapping 对象关系映射
- 在Java中编程:使用的是面向对象的开发方式。
- 在MySQL中写的SQL语句:使用的是关系型的数据库将表中的数据映射成一个对象,对象关系映射。
mybatis的两种映射方式
- 通过XML的配置文件。
- 通过注解的方式
3.5 下载安装
官网下载
Mybatis官方地址: http://www.mybatis.org/mybatis-3/
github下载
github地址: https://github.com/mybatis/mybatis-3/releases
4- Mybatis入门
4.1 项目准备
4.1.1项目目录
导入相关依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.guardwhy</groupId>
<artifactId>Mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<!--倒入项目所需依赖-->
<dependencies>
<!-- mybatis相关依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!-- mysql数据库相关依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- 日志相关依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- 测试相关依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--lombok插件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
</dependencies>
</project>
Sql基本结构
-- 创建数据库
create database db_mybatis;
-- 创建数据表
create table user (
id int primary key auto_increment,
username varchar(20) not null,
birthday date,
sex char(1) default '男',
address varchar(50)
);
-- 插入数据
insert into user values (null, '侯大利','1980-10-24','男','江州');
insert into user values (null, '田甜','1992-11-12','女','扬州');
insert into user values (null, '王永强','1983-05-20','男','扬州');
insert into user values (null, '杨红','1995-03-22','女','秦阳');
select * from user;
log4j.properties
### 设置Logger输出级别和输出目的地 ###
log4j.rootLogger=debug, stdout
### 把日志信息输出到控制台 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
db.properties
编写数据库连接属性资源文件(db.properties),放在resources资源文件下。
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_mybatis
jdbc.username=root
jdbc.password=root
加载db.properties属性文件
<!--在内部配置属性:先读取内部的属性,再读取外部的属性,外部的会覆盖内部的,最后外部的属性起作用-->
<properties resource="db.properties">
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="root"/>
</properties>
4.1.2 User实体类
package cn.guardwhy.domain;
/**
* 实体类
*/
import java.sql.Date;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
}
}
4.1.3 UserMapper接口
这个接口其实就是数据访问层:DAO层
package cn.guardwhy.dao;
import cn.guardwhy.enty.User;
import java.util.List;
/**
* 数据访问层方法
*/
public interface UserMapper {
// 查找所有用户
List<User> findAllUsers();
}
4.1.4 UserMapper.xml
- 接口映射文件:UserMapper.xml编写SQL语句。
- 在resources中创建 cn/guardwhy/dao 文件夹,在目录中创建UserMapper.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">
<!--
实体类的映射文件: namespace 指定接口的类全名
-->
<mapper namespace="cn.guardwhy.dao.UserMapper">
<!--
查询语句id: 接口中方法的名字, resultType:返回的实体类的类型类全名, parameterType: 参数的类型
-->
<select id="findAllUsers" resultType="cn.guardwhy.enty.User">
select * from user
</select>
</mapper>
4.1.5 sqlMapConfig.xml
sqlMapConfig.xml 是 mybatis 框架的核心配置文件, sqlMapConfig.xml 配置连接数据库参数。
properties | 外部的可替代的属性,可以从 Java 属性配置文件中读取。 |
---|---|
settings | mybatis 全局的配置参数 |
typeAliases | 给 Java 类型定义别名 |
typeHandlers | 类型处理器,将结果集中的值以合适的方式转换成 Java 类型 |
objectFactory | 可以指定用于创建结果对象的对象工厂 |
plugins | 允许使用插件来拦截 mybatis 中一些方法的调用 |
environments | 配置多种环境,可以将 SQL 映射应用于多种数据库之中。 transactionManager , 两种事务管理器类型。 dataSource 指定数据源的类型 |
mappers | 定义SQL映射语句的配置文件 |
<?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>
<!--在内部配置属性:先读取内部的属性,再读取外部的属性,外部的会覆盖内部的,最后外部的属性起作用-->
<properties resource="db.properties">
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="root"/>
</properties>
<!-- 一个核心配置文件,可以配置多个运行环境,default默认使用哪个运行环境 -->
<environments default="default">
<!-- 其中的一个运行环境,通过id来进行标识-->
<environment id="default">
<!--事务管理器 -->
<transactionManager type="JDBC"/>
<!--数据源 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 加载其他的映射文件 -->
<mappers>
<mapper resource="cn/guardwhy/dao/UserMapper.xml"/>
</mappers>
</configuration>
4.2 测试类实现
4.2.1 Mybatis三大对象
在mybatis中一个会话相当于一次访问数据库的过程,一个会话对象类似于一个Connection连接对象。
- SqlSessionFactoryBuilder:通过这个工厂建造类来创建一个会话工厂。
- SqlSessionFactory:从一个工厂类中得到一个会话对象,通过会话工厂对象来创建会话对象。
- SqlSession: 每次访问数据库都需要创建一个会话对象,这个会话对象不能共享。访问完成以后会话需要关闭。
4.2.2 实现步骤
- 通过框架提供的Resources类,加载sqlMapConfig.xml,得到文件输入流InputStream对象
- 实例化会话工厂创建类SqlSessionFactoryBuilder。
- 通过上面的SqlSessionFactoryBuilder对象,读取核心配置文件的输入流,得到会话工厂SqlSessionFactory类
- 使用SqlSessionFactory对象,创建SqlSession对象
它相当于JDBC中的Connection对象,提供了操作数据库的CRUD方法。
它提供了一个getMapper()方法,获取接口的实现对象。
-
获取接口的对象UserMapper,得到接口的代理对象
-
执行数据库的查询操作,输出用户信息
-
关闭会话,释放资源。
4.2.3 代码示例
工具类代码
package cn.guardwhy.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
// 1.声明一个工厂对象
private static SqlSessionFactory factory;
// 2.在静态代码块中创建会话工厂
static {
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 得到输入流
try(InputStream inputStream = Resources.getResourceAsStream("sqlMapConfig.xml");){
factory = builder.build(inputStream);
}catch(IOException e){
e.printStackTrace();
}
}
// 3.静态方法得到会话工厂
public static SqlSessionFactory getSessionFactory(){
return factory;
}
// 4.得到会话对象
public static SqlSession getSession(){
return factory.openSession();
}
}
测试类代码
package cn.guardwhy.test;
import cn.guardwhy.dao.UserMapper;
import cn.guardwhy.enty.User;
import cn.guardwhy.utils.MybatisUtils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* 使用db_mybatis数据库
*/
public class TestUserMapper {
@Test
/*
* 查询所有用户
*/
public void selectUser(){
// 1.通过工具类得到会话对象
SqlSession session = MybatisUtils.getSession();
// 2.会话对象的得到UserMapper接口代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
// 3.生成了代理对象
System.out.println(userMapper);
// 4.执行查询操作
List<User> users = userMapper.findAllUsers();
// 5.遍历
users.forEach(System.out::println);
// 6.关闭会话
session.close();
}
}