Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象

楔子:


一、三层架构:

1、三层架构包含的三层:

界面层(User Interface layer)、业务逻辑层(Business Logic Layer)、数据访问层(Data access layer)。

 

2、三层的职责:

界面层:接受用户的数据,调用业务逻辑层进行功能处理,返回结果给客户端,过去的 servlet 就是界面层的功能。

业务逻辑层:用来进行整个项目的业务逻辑处理,向上为界面层提供处理结果,向下问数据访问层要数据。

数据访问层:专门用来进行对数据的增、删、改、查操作,向上为业务逻辑层提供数据。

 

3、三层之间处理请求的交互:

(客户端)<--->界面层<--->业务逻辑层<--->数据访问层<--->(数据库)

各层之间的调用顺序是固定的,不允许跨层访问。

 

二、框架:

1、框架(Framework)是一个半成品软件,将所有的公共的,重复的功能解决掉,帮助程序快速高效的进行开发,它是可复用的,可拓展的。

 

2、常见的框架 --- SSM:

Spring:它是整合其它框架的框架,它的核心是IOC和AOP,它由20多个模块构成,在很多领域都提供了很好的解决方案。

SpringMVC:专门用来优化控制器(servlet),提供了极简单的数据提交,数据携带,页面跳转等功能。

MyBatis:是持久化层的一个框架,用来进行数据库访问的优化,专注于sql语句,极大的简化了JDBC的访问。

 

正文:


一、MyBatis 概述:

1、MyBatis 是一个优秀的基于 java 的持久层框架,内部封装了 jdbc,开发者只需要关注 sql 语句本身,而不需要处理加载驱动、创建连接、创建 statement、关闭连接,资源等繁杂的过程。

 

2、MyBatis 通过 xml 或注解两种方式将要执行的各种 sql 语句配置起来,并通过 java 对象和 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。

 

3、MyBatis 解决的主要问题:

1)减轻使用 JDBC 的复杂性,不用编写,重复创建 Connetion , Statement ;

2)不用编写关闭资源代码;

3)直接使用 java 对象,表示结果数据;

 

二、MyBatis框架结构:

三层看架构的目录设计 三层架构查询功能_SSM

1、 mybatis配置文件:

【SqlMapConfig.xml】:此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

【mapper.xml】:文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

【SqlMapConfig.xml】:是mybatis的核心文件。mybatis将dao层与sql语句分离开来,虽然写的时候分离开来了,但是执行的时候还是要依靠sql语句,所以我们的sql语句写在Mapper.xml中。我们在加载核心的时候,会加载他下面的Mapper.xml,所以sql语句便会加载进去了。我们只需要在SqlMapConfig.xml中引入Mapper.xml就可以了,所以最后只需要加载SqlMapConfig.xml这一个核心配置文件。

2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂。工厂能帮我们去加载核心配置文件。加载了核心配置文件后就创建session,通过session可以对数据库进行操作。

3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

4、 mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。Executor是执行者,我们不需要管,因为mybatis已经为我们封装好了。mybatis直接执行sql语句。

5、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。

6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

7、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

8、Mapped Statement是输入与输出中间过程中产生的一些对象,通过这些对象去访问数据库。

 

总结:

        工厂能帮我们去加载核心配置文件,同时创建会话,会话里面有执行者,执行sql语句,在执行sql语句的过程中产生对象,通过Mapped Statement封装成对象。执行sql语句就要需要输入参数和输出参数。

 

三、MyBatis 的使用:

1、添加框架的步骤:

1)添加依赖

2)添加配置文件

 

2、具体步骤:

1)新建库,新建表

2)新建Maven项目,勾选 Create from archetype,选择quickstart模板

3)修改目录:添加缺失的目录,修改目录属性

4)修改pom.xml文件:添加MyBatis的依赖,添加mysql的依赖

5)修改pom.xml文件:添加资源文件指定

6)在idea中添加数据库的可视化

7)添加jdbc.properties 属性文件(数据库的配置)

8)添加SqlMapConfig.xml文件,MyBatis的核心配置文件

9)创建实体类Student,用来封装数据

10)添加完成学生表的增删改查的功能的StudentMapper.xml 文件

11)创建测试类,进行功能测试

 

3、数据库预准备:

创建ssm库,建表student:

CREATE DATABASE ssm DEFAULT CHARSET utf8;
use ssm;

CREATE TABLE `student` (
`id` int(11)  AUTO_INCREMENT primary key ,
`name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`age` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into student(name,email,age) values('张三','zhangsan@126.com',22);
insert into student(name,email,age) values('李四','lisi@126.com',21);
insert into student(name,email,age) values('王五','wangwu@163.com',22);
insert into student(name,email,age) values('赵六','zhaoliun@qq.com',24);

 

四、MyBatis 对象分析:

1、 Resources 类:

Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。

 

2、SqlSessionFactoryBuilder 类

SqlSessionFactory 的创建 , 需要使用 SqlSessionFactoryBuilder 对象的 build() 方法 。 由于SqlSessionFactoryBuilder对象在创建完工厂对象后,就完成了其使命,即可被销毁。所以,一般会将该对象创建为一个方法内的局部对象,方法结束,对象销毁。

 

3、SqlSessionFactory 接口

SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用只需要一个该对象即可。创建 SqlSession 需要使用 SqlSessionFactory 接口的的 openSession()方法。

1)openSession(true):创建一个有自动提交功能的SqlSession

2)openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交

3)openSession():同 openSession(false)

 

4、SqlSession 接口

SqlSession  接口对象用于执行持久化操作。一个 SqlSession  对应着一次数据库会话,一次会话以SqlSession 对象的创建开始,以 SqlSession 对象的关闭结束。

SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将其关闭。再次需要会话,再次创建。 SqlSession 在方法内部创建,使用完毕后关闭。

 

五、一堆栗子:

1、module 目录结构:

三层看架构的目录设计 三层架构查询功能_三层看架构的目录设计_02

 

2、pom.xml:

<?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>org.burning</groupId>
  <artifactId>mybatis_001_student</artifactId>
  <version>1.0</version>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!--记得修改对应的JDK版本-->
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <!--添加依赖-->
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <!--mybatis框架依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.9</version>
    </dependency>

    <!--mysql依赖-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.27</version>
    </dependency>
  </dependencies>

  <build>
    <!--添加资源文件的指定(为了保证在源码中用到的各种配置文件,在编译之后,都顺利地到我tomcat指定的目录下)-->
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>

      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
    </resources>
  </build>
</project>

 

3、jdbc.properties:

//这是博主的mysql配置信息,记得要修改为你的信息哟~

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=888

 

4、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 下的子标签的顺序不能变-->
<configuration>
    <!--读取属性文件(jdbc.properties)
      属性(两种方式):
        resource:从resource录下找指定名称的文件加载
        url:使用绝对路径加载属性文件
         例如:(记得把"\"改为“/”或者“\\”)
              C:\java\mybatis\mybatis-course\mybatis_001_student\src\main\resources\jdbc.properties
    -->
    <properties resource="jdbc.properties"></properties>

    <!--设置日志输出底层执行的代码-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <!--注册实体类的别名-->
    <typeAliases>
<!--        <!–单个实体类别名的注册–>-->
<!--        <typeAlias type="org.burning.entity.Student" alias="student"></typeAlias>-->

        <!--批量注册别名
            别名是类名的驼峰命名法
        -->
        <package name="org.burning.entity"/>
    </typeAliases>

    <!--配置数据库的环境变量(数据库连接配置)
          default:根据下面不同environment的id决定使用哪种数据库连接配置
    -->
    <environments default="development">
        <!--开发时在公司时使用的配置-->
        <environment id="development"><!--id:就是提供给environments的default属性使用-->
            <!--配置事务管理器
                  type:指定事务管理的模式
                     JDBC:事务的控制交给程序员控制
                     MANAGED:由容器(spring)来管理事务
            -->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源
                type:指定不同的配置方式
                    JNDI:java命名目录接口,在服务器端进行数据库连接池的管理
                    POOLED:使用数据库连接池
                    UNPOOLED:不使用数据库连接池
            -->
            <dataSource type="POOLED">
            <!--配置数据库连接的基本参数
                private String driver;
                private String url;
                private String username;
                private String password;
            -->
                <property name="driver" value="${jdbc.driverClassName}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>

        <!--因为这里面都没有配内容,所以先将下面两个配置注释掉-->
        <!--在家数据库的配置-->
        <!--        <environment id="home">-->
        <!--            <transactionManager type=""></transactionManager>-->
        <!--            <dataSource type=""></dataSource>-->
        <!--        </environment>-->

        <!--上线后的数据库的配置-->
        <!--        <environment id="online">-->
        <!--            <transactionManager type=""></transactionManager>-->
        <!--            <dataSource type=""></dataSource>-->
        <!--        </environment>-->

    </environments>

    <!--注册mapper.xml
        resource:从resources目录下找指定名称的文件加载
        url:使用绝对路径加载属性文件
        class:动态代理方式下的注册
    -->
    <mappers>
        <mapper resource="StudentMapper.xml"></mapper>
    </mappers>
</configuration>

 

5、Student.java:

package org.burning.entity;

public class Student {
    private Integer id;
    private String name;
    private String email;
    private Integer age;

    public Student() {
    }

    public Student(String name, String email, Integer age) {
        this.name = name;
        this.email = email;
        this.age = age;
    }

    public Student(Integer id, String name, String email, Integer age) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
}

 

6、StudentMapper.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">
<!--
    mapper:是整个文件的大标签,用来开始和结束xml文件
    属性:
        namespace:指定命名空间(相当于包名),用来区分不同mapper.xml文件中相同的id属性
-->
<mapper namespace="wgd">
    <!--完成查询全部学生的功能
        resultType:指定查询返回的结果集的类型,如果是集合,则必须是泛型的类型
        parameterType:如果有参数,则通过它来指定参数的类型
    -->
    <select id="getAll" resultType="student">
        select id,name,email,age
        from student
    </select>

    <!--按主键id查询学生信息
    -->
    <select id="getById" parameterType="int" resultType="student">
        select id,name,email,age
        from student
        where id=#{id}
    </select>

    <!--按学生名称模糊查询
       判断使用 ${} 还是 #{} ?
         如果要在字符串中使用,则用${},否则用 #{}
    -->
    <select id="getByName" parameterType="string" resultType="student">
        select id,name,email,age
        from student
        where name like '%${name}%'
    </select>

    <!--增加学生-->
    <insert id="insert" parameterType="student">
        insert into student (name,email,age) value (#{name},#{email},#{age})
    </insert>

    <!--按主键删除学生-->
    <delete id="deleteById" parameterType="int">
        delete from student
        where id=#{id}
    </delete>

    <!--按主键更新学生-->
    <update id="updateById" parameterType="student">
        update student set name=#{name},email=#{email},age=#{age}
        where id=#{id}
    </update>
</mapper>

 

7、Mytest.java:

package org.burning.test;

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.burning.entity.Student;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class Mytest {
    SqlSession sqlSession;

    //在所有的@Test方法执行前先执行的代码
    @Before
    public void openSqlSession() throws IOException {
        //使用文件流读取核心配置文件SqlMapConfig.xml
        InputStream in = Resources.getResourceAsStream
                ("SqlMapConfig.xml");

        //创建SqlSessionFactory工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);

        //取出SqlSession的对象
        sqlSession = factory.openSession();
    }

    //在所有的@Test方法执行后执行的代码
    @After
    public void closeSqlSession() {
        sqlSession.close();
    }

    @Test
    public void testGetAll() throws IOException {
        //完成查询操作
        List<Student> list = sqlSession.selectList("wgd.getAll");
        list.forEach(student -> System.out.println(student));
    }

    @Test
    public void testGetById() throws IOException {
        //按主键完成查询操作
        Student student = sqlSession.selectOne("wgd.getById",2);
        System.out.println(student);
    }

    @Test
    public void testGetByName() throws IOException {
        //按学生名称关键字完成查询操作
        List<Student> studentList = sqlSession.selectList("wgd.getByName","杨");
        studentList.forEach(student -> System.out.println(student));
    }

    @Test
    public void testInsert() throws IOException {
        //添加学生信息
        int num = sqlSession.insert("wgd.insert",new Student("大爷","daye@126.com",50));
        System.out.println(num);

        //切记:在所有的增删改后,必须手动提交事务!
        sqlSession.commit();
    }

    @Test
    public void testDeleteById() throws IOException {
        //按学生id完成删除操作
        int num = sqlSession.delete("wgd.deleteById",21);
        System.out.println(num);

        //切记:在所有的增删改后,必须手动提交事务!
        sqlSession.commit();
    }

    @Test
    public void testUpdateById() throws IOException {
        //按学生id完成更新操作
        int num = sqlSession.update("wgd.updateById",new Student(20,"大爷","daye126@.com",500));
        System.out.println(num);

        //切记:在所有的增删改后,必须手动提交事务!
        sqlSession.commit();
    }

}

 

ps:

      参考资料链接:mybatis框架的架构(图解) - wyhluckydog