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 对象关系映射

  1. 在Java中编程:使用的是面向对象的开发方式。
  2. 在MySQL中写的SQL语句:使用的是关系型的数据库将表中的数据映射成一个对象,对象关系映射。

mybatis的两种映射方式

  1. 通过XML的配置文件。
  2. 通过注解的方式

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();
    }
}
posted @ 2021-12-27 10:59  guardwhy  阅读(128)  评论(0编辑  收藏  举报