黑马就业班——mybatis框架:part1 -- mybatis入门

  • 本文参考文档:《Mybatis第一天讲义.pdf》
  • 本文代码项目:mybatis_day01、mybatis_day01_annotation、mybatis_day01_dao、mybatis_day01_design(路径:G:\idea_java_project\)
  • 说明:为了节省时间,大部分内容可以参考文档,本笔记只对一些重要的内容进行记录说明。

1、Mybatis的学习流程
  如下图:
黑马就业班——mybatis框架:part1 -- mybatis入门_第1张图片

2、三层架构与SSM框架
  SSM框架:Spring、SpringMVC、Mybatis3个架构;三层架构:表现层(web)、业务逻辑层(service)、数据访问层(dao)。
黑马就业班——mybatis框架:part1 -- mybatis入门_第2张图片
  2个补充

1、什么是框架?
	它是我们软件开发中的一套解决方案,不同的框架解决的是不同的问题。
使用框架的好处:
	框架封装了很多的细节,使开发者可以使用极简的方式实现功能。大大提高开发效率。
2、三层架构
	表现层:是用于展示数据的
	业务层:是处理业务需求
	持久层:是和数据库交互的

3、持久层技术解决方案

JDBC技术:
	Connection,PreparedStatement,ResultSet 
Spring
	Jdbc Template:Spring中对jdbc的简单封装
Apache
	DBUtils:它和Spring的JdbcTemplate很像,也是对Jdbc的简单封装
	以上这些都不是框架
	
JDBC是规范,Spring的Jdbc Template和Apache的DBUti1s都只是工具类。

4、mybatis的概述

	mybatis是一个持久层框架,用java编写的。它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等繁杂过程,它使用了ORM思想实现了结果集的封装。
	
ORM:Object Relational Mappging 对象关系映射
简单的说,就是把数据库表和实体类及实体类的属性对应起来,让我们可以操作实体类就实现操作数据库表。比如数据库中的user表,对应java中的User类。暂时我们需要做到,实体类中的属性和数据库表的字段名称保持一致。

5、mybatis环境搭建

  • 注意,这是mybatis的开发流程

part1:数据库,Maven坐标(视频5)

  在数据库中创建一个 lkj_mybatis 数据库,并添加user表,同时插入数据。

CREATE DATABASE lkj_mybatis; -- 创建数据库
USE lkj_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;

黑马就业班——mybatis框架:part1 -- mybatis入门_第3张图片
  创建一个Maven的普通的java工程(可以不使用Maven的java骨架),在pom.xml中添加打包方式为jar。随后,导入mybatis的坐标**(注意,在Maven项目中使用mybatis是需要添加mybatis的jar包在仓库中的坐标的)**。 同时,还需要导入mysql、log4j(日志)、junit模块的坐标。

  • 注意,添加坐标的时候IDEA的右下角有提示到导入,选择允许自动导入

part2:domain实体类与持久层接口dao(视频5)

  domain包下添加一个User实体类,目前,User类的属性名要与数据库user的属性名相同。dao包下创建一个UserDao,用户的持久层接口

//UserDao
package com.lkj.dao;

import com.lkj.domain.User;

import java.util.List;

/**
 * 用户的持久层接口
 */
public interface UserDao
{
    /**
     * 查询所有用户并放入List集合
     * @return
     */
    List<User> findAll();
}

part3:mybatis的主配置文件:SqlMapConfig.xml文件、映射配置文件,既每个dao独立的配置文件(视频6)

  在resource下创建一个xml配置文件,一般叫SqlMapConfig.xml,随后对该文件进行配置,这个文件是mybatis的主配置文件。
  在resource下创建一个dao的独立的xml配置文件(也叫映射配置文件),需要注意的是,dao(持久层)的独立配置文件,必须和dao持久层接口在相同的包中。
黑马就业班——mybatis框架:part1 -- mybatis入门_第4张图片
  代码如下

----SqlMapConfig.xml

 

<configuration>
    
    <environments default="mysql">
        
        <environment id="mysql">
            
            <transactionManager type="JDBC">transactionManager>
            
            <dataSource type="POOLED">
                
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/lkj_mybatis" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            dataSource>
        environment>
    environments>

     
    <mappers>
        <mapper resource="com/lkj/dao/UserDao.xml" />
    mappers>
configuration>
------UserDao.xml

  

<mapper namespace="com.lkj.dao.UserDao">
    

    
    <select id="findAll" resultType="com.lkj.domain.User">
        select * from user;
    select>
mapper>

  总结:

mybatis的环境搭建
	第一步:创建maven工程并导入坐标
	第二步:创建实体类和dao的接口
	第三步:创建Mybatis的主配置文件:SqlMapConifg.xml
	第四步:创建映射配置文件:UserDao.xml

环境搭建的注意事项:
	第一个:创建UserDao.xml和UserDao.java时名称是为了和我们之前的知识保持一致。在Mybatis中它把持久层的操作接口名称和映射文件也叫做:Mapper所以:IUserDao和IUserMapper是一样的;
	
	第二个:在idea中创建目录Directory的时候,它和包Package是不一样的。包在创建时:com.itheima.dao它是三级结构目录,在目录创建时:com.itheima.dao是一级目录。我们在resource中没办法创建包,但是又要创建三级目录结构,就必须一级一级地创建Directory,如果一次性创建Directory:com.itheima.dao,只有一级目录结构!这点要注意;

	第三个:mybatis的映射配置文件包结构必须和dao接口的包结构相同;
	
	第四个:映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名;	

	第五个:映射配置文件的操作配置(如select),id属性的取值必须是dao接口的方法名。
	
	当我们遵从了第三,四,五点之后,我们在开发中就无须再写dao的实现类,mybatis会帮我们完成实现类的操作。I

6、mybatis的入门案例
  先将log4j的配置文件log4j.properties放入resource中。
  在test.java包下,创建一个新的包com.lkj.test,在下面创建一个MybatisTest.java的类进行测试(注意,我们这里不需要再写DAO的实现类!)。
  步骤:

第一步:读取配置文件
第二步:创建SqlSessionFactory工厂
第三步:创建SqlSession
第四步:创建Dao接口的代理对象
第五步:执行dao中的方法
第六步:释放资源
注意事项:
	不要忘记在映射配置中告知mybatis要封装到哪个实体类中。配置的方式:指定实体类的全限定类名

  代码

package com.lkj.test;

public class MybatisTest
{
    /**
     * 入门案例
     * 注意,记住这里实现SQL操作的6个步骤!!!
     * @param args
     */
    public static void main(String[] args) throws IOException
    {
        //1.读取配置文件(Mybatis的主配置文件SqlMapConfig.xml)
        /*
        这里使用Mybatis的getResourceAsStream方法来读取配置文件。
        读取的mybatis的主配置文件在resources目录下,不需要加其他目录,直接写“SqlMapConfig.xml”即可
         */
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

        //2.创建SqlSessionFactory工厂
        /*
        SqlSessionFactory是一个接口,我们必须要创建其实现类,而Mybatis已经为我们创建了相应的实现类:SqlSessionFactoryBuilder,
        我们直接使用这个实现类对象的build()方法即可创建SQLSessionFactory对象
         */
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);//注意将配置文件读取流对象放进去

        //3.使用工厂生产SqlSession对象(这个对象用于为我们提供DAO的实现)
        SqlSession session = factory.openSession();

        //4.使用SqlSession创建Dao接口的代理对象
        // 我们一般不使用SqlSession的对象实现dao层的方法,而会通过dao层相应dao的代理对象来实现其方法
        UserDao userDao = session.getMapper(UserDao.class);

        //5.使用代理对象执行方法
        List<User> list = userDao.findAll();
        for (User user : list)
        {
            System.out.println(user);
        }

        //6.释放资源
        session.close();//先关闭SqlSession对象
        is.close();//再关闭文件读取流对象
    }
}

7、mybatis的注解开发与编写dao实现类的方式
  创建一个新的项目mybatis_day01_annotation(同样是普通java项目)。为了方便,先将各个mybatis_day01项目的文件都拷贝过来,同时在pom.xml文件中导入mybatis以及其他相关组件的jar的坐标。测试刚刚的测试类,发现可以使用即可。

1、dao的独立配置文件没有用,我们要通过注解来配置,我们将dao的配置文件的包:com.lkj.dao.UserDao.xml删除。但是mybatis的主配置文件不能删除!!!

2、在UserDao的方法前面加上注解,注解中写上要执行的SQL语句
	@Select("select * from user")
    List<User> findAll();

3、在主配置文件中,我们不需要再指定dao的独立配置文件,而是要在主配置文件中指定操作的被注解的dao(原先是在dao的配置文件UserDao.xml中的namespace属性指定要操作的dao),使用class属性指定被注解的dao全限定类名。
	<mappers>
       // 
        <mapper class="com.lkj.dao.UserDao"/>
    </mappers>

总结:
	现在只需要在dao接口的方法上使用@Select注解,并且指定SQL语句。同时需要在SqlMapConfig.xml中的mapper配置时,使用class属性指定dao接口的全限定类名。这里也不需要指定最后的结果最后封装的实体类。因为最后封装的结果类型在方法中已经有定义:List<User> findAll(); 就是这里面的User。因此,我们不需要再指定结果类型。

  说明:我们在实际开发中,不管使用XML还是注解配置,都是越简便越好,所以都是采用不写dao实现类的方式。但是Mybatis它是支持写dao实现类的。
  创建自己测试的项目mybatis_day01_dao,同样将第一个项目的所有资源放进来,同时在dao包下添加一个impl.UserDaoImpl.java实现类。

  代码如下,我们只需要修改实现类UserDaoImpl与测试类MyBatisTest的代码,其他的不变。

//实现类UserDaoImpl
package com.lkj.dao.impl;

public class UserDaoImpl implements UserDao
{
    //由于是我们自己写实现类,前面使用SqlSession生成dao的代理对象这一步就不需要!
    // 读取配置文件、创建SqlSessionFactory工厂、使用工厂生产SqlSession对象、使用SqlSession对象执行、释放资源
    /*
    我们先在UserDaoImpl中创建一个SqlSessionFactory的引用,然后在调用这个UserDaoImpl的service或者是测试类中,
    创建这个UserDaoImpl的对象,并且将这个SqlSessionFactory对象传递进来,即可在UserDaoImpl使用SqlSessionFactory。
    同时,我们需要在service或者是测试类中 读取配置文件、创建SqlSessionFactory工厂并创建UserDaoImpl对象,调用findAll方法完成查询。
     */
    private SqlSessionFactory factory;
    public UserDaoImpl(SqlSessionFactory factory)
    {
        this.factory = factory;
    }

    public List<User> findAll()
    {
        //使用工厂生产SqlSession对象
        SqlSession session = factory.openSession();

/*
使用SqlSession自带的方法执行SQL语句并返回。
注意,这里可以在selectList中自己写SQL语句,但是这样我们之前在UserDao.xml中已经配置过UserDao接口中findAll方法的SQL语句,
这里我们直接通过UserDao.xml配置来获取执行语句,我们在UserDao.xml配置中已经通过namespace="com.lkj.dao.UserDao" 指定了findAll方法作用的dao(UserDao),
我们直接写要执行的方法在UserDao接口中的全名即可:"com.lkj.dao.UserDao.findAll"

注意,如果使用的是注解开发,没有UserDao.xml,这时如果想要获取执行语句,同样通过"com.lkj.dao.UserDao.findAll",
“com.lkj.dao.UserDao.findAll”会找到UserDao类下的findAll()方法,注解方法的SQL语句定义在findAll方法上,这样实现类也可以找到SQL语句。

注意:不管使用的是dao.xml的方式还是使用注解的方式,都可以创建UserDao的实现类,关键的是selectList()方法通过 “com.lkj.dao.UserDao.findAll” 找到UserDao.xml中select标签定义的SQl语句,或者是找到UserDao.java中注解@Select中定义的SQL语句。
 */
        List<User> list = session.selectList("com.lkj.dao.UserDao.findAll");
        //关闭SqlSession对象
        session.close();

        return list;
    }
}
//测试类MyBatisTest
package com.lkj.test;

public class MybatisTest
{
    /**
     * 入门案例
     * 注意,记住这里实现SQL操作的6个步骤!!!
     * @param args
     */
    public static void main(String[] args) throws IOException
    {
        //1.读取配置文件(Mybatis的主配置文件SqlMapConfig.xml)
        /*
        这里使用Mybatis的getResourceAsStream方法来读取配置文件。
        读取的mybatis的主配置文件在resources目录下,不需要加其他目录,直接写“SqlMapConfig.xml”即可
         */
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

        //2.创建SqlSessionFactory工厂
        /*
        SqlSessionFactory是一个接口,我们必须要创建其实现类,而Mybatis已经为我们创建了相应的实现类:SqlSessionFactoryBuilder,
        我们直接使用这个实现类对象的build()方法即可创建SQLSessionFactory对象
         */
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);//注意将配置文件读取流对象放进去

        /**
         //3.使用工厂生产SqlSession对象(这个对象用于为我们提供DAO的实现)
         SqlSession session = factory.openSession();
        //4.使用SqlSession创建Dao接口的代理对象
        // 我们一般不使用SqlSession的对象实现dao层的方法,而会通过dao层相应dao的代理对象来实现其方法
        UserDao userDao = session.getMapper(UserDao.class);
         */

        //这里不再需要创建dao的代理对象,因为我们有dao的实现类。直接使用工厂创建dao对象
        UserDaoImpl userDao = new UserDaoImpl(factory);

        //3.执行UserDaoImpl中的findAll方法
        List<User> list = userDao.findAll();
        for (User user : list)
        {
            System.out.println(user);
        }

        //4.释放资源
        is.close();//再关闭文件读取流对象
    }
}

  注意,我们在开发中是不会写实现类的,这里是为了说明Mybatis想执行语句的时候,必须通过在dao的独立的配置文件UserDao.xml中,使用namespace配置语句找到要执行的dao(UserDao),使用id配置找到要执行的方法(findAll),这样就可以找到要执行的SQL语句。当然,在使用注解配置的时候,“com.lkj.dao.UserDao.findAll”也可以找到UserDao的findAll()方法上的@Select("select * from user") 注解中的sql语句!
只有指定dao、方法名与SQL语句,Mybatis才会执行


8、mybatis入门案例中的设计模式分析
  分析的就是我们第一个项目中Mybatis.test测试类的方法(主要见视频10的分析)。

1、我们在读取配置文件的时候,不管是绝对路径还是相对路径,都会面临因文件目录不存在而读取不到的问题。我们读取配置文件一般使用2个方法:
	1) 使用类加载器:只能读取类路径(src)的配置文件(之前读取JDBCUtils的druid.properties配置文件就是使用这种方法,druid.properties放在类目录src的resources文件夹下,这样就可以读取到);
	2) 使用ServletContext对象(代表整个项目)的getRealPath()方法,可以读取到当前项目运行位置的绝对路径(当前项目部属在哪里,它就可以读取到哪里)。
	我们以后读取配置文件一般都使用这两种方法,其他的都不太靠谱。

2、创建工厂SqlSessionFactory,mybatis使用了构建者模式(视频10-4.00)。
	SqlSessionFactoryBuilder的对象builder就是构建者。构建者模式的好处是,把对象繁琐的创建细节隐藏,使得使用者直接调用方法就可以拿到对象。

3、创建SqlSession对象,使用了工厂模式。
	我们使用SqlSessionFactory工厂为我们生成SqlSession对象,在工厂中new SqlSession的对象,这样的优势是:解耦,降低了类之间的依赖关系。
	比如我们想换一个SqlSession对象,不需要再重新new,直接在工厂中获取即可,如果直接new的话,每次都要修改代码并重新编译,重新部属项目,耦合性太强。

4、创建Dao接口实现类的对象,使用了代理模式。
	优势:在不修改源码的基础上,对已有方法进行增强。
	我们通过创建Dao接口实现类的代理对象,实现了不创建Dao接口的实现类也能实现功能。

我们mybatis中创建了那么多对象,其实可以更加简单,为什么要创建这么多对象?
	因为创建的类越多,代码就更加灵活,我们在使用的时候选择性更多。后面我们可能就会把中间的细节全部屏蔽,只专注于功能的实现。

黑马就业班——mybatis框架:part1 -- mybatis入门_第5张图片
黑马就业班——mybatis框架:part1 -- mybatis入门_第6张图片


9、自定义Mybatis的分析-执行查询所有的分析(视频11)与创建代理对象的分析(视频12)(这部分很重要!!!)

mybatis在使用代理dao的方式实现增删改查时做什么事呢?
	只有两件事:
	  第一:创建代理对象
	  第二:在代理对象中调用selectList

  这部分较为复杂,见视频11,12分析。(下面的图片较为模糊,可以直接看自己的资源下的文件:D:\资源\黑马就业班2019\05-Mybatis\01-第一天\截图
黑马就业班——mybatis框架:part1 -- mybatis入门_第7张图片
黑马就业班——mybatis框架:part1 -- mybatis入门_第8张图片

10、自定义Mybatis

自定义mybatis能通过入门案例看到类
	class Resources
	class SqlSessionFactoryBuilder
	interface SqlSessionFactory
	interface SqlSession

  创建一个新的项目:mybatis_day01_design。先将各个mybatis_day01项目的文件都拷贝过来,同时在pom.xml文件中导入mybatis以及其他相关组件的jar的坐标。
  随后,我们在项目pom.xml中将Mybatis的依赖坐标删除,因为我们要自定义Mybatis。同时,我们将主配置文件与UserDao的配置文件UserDao.xml的mybatis约束全部删除。(注意不要将第一行xml文件的定义也删除!)
  下面就是要创建Mybatis相关的类与接口

1、创建一个Resources类。
	在这个类中创建一个getResourceAsStream(String filePath)方法,根据类加载器读取配置文件。(配置文件)
	
2、创建SqlSessionFactoryBuilder类、SqlSessionFactory接口、SqlSession接口。(3个类与接口的方法见代码,不再赘述)
下面的代码补全,见视频13-视频

3、几个类的说明:
	XMLConfigBuilder:用于解析配置文件(从配置文件流中读取配置的连接信息与映射信息并封装到Configuration对象中);
	Configuration:自定义mybatis的配置类(用于封装连接信息及映射信息(sql语句与结果封装的实体类的全限定类名),连接信息与映射信息的涵义见上图);
	Mapper:用于封装执行的SQL语句和结果类型的全限定类名;
	DefaultSqlSessionFactory:SqlSessionFactory接口的实现类;
	DefaultSqlSession:SqlSession接口的实现类;
	Executor:负责执行SQL语句,并且封装结果集;
	DataSourceUtil:用于创建数据源的工具类(这里用于获取数据库的连接);
	MapperProxy:用于代理Proxy.newProxyInstance过程中,实现InvocationHandler接口,并对findAll方法进行增强。

  流程说明:我们使用Resource的getResourceAsStream获取主配置文件的读取流,随后,XMLConfigBuilder工具类的loadConfiguration方法,使用Resource提供的读取流,将主配置文件所映射的dao的独立配置文件的信息——执行的SQL语句,结果封装的实体类的全限定类型(这两个用Mapper封装,映射信息,Map中Mapper的key是com.lkj.dao.UserDao.findAll)与 数据库连接信息 ,封装到自定义mybatis的配置类Configuration中。
  随后,将这些信息Configuration交给构建者SqlSessionFactoryBuilder,构建者使用build方法,创建了一个工厂接口SqlSessionFactory的对象DefaultSqlSessionFactory,工厂对象使用openSession方法,创建了一个SqlSession接口的对象DefaultSqlSession。
  接下来,我们在DefaultSqlSession中使用getMapper方法来创建代理对象,并增强原来UserDao对象的findAll方法,使得代理对象可以调用findAll方法执行查询所有的操作。(具体细节见代码)
  其实最后那么多操作总结起来只有2件事:创建代理对象,执行查询所有
  使用注解实现自定义Mybatis,见视频17。(测试的时候将UserDao.xml删除)

你可能感兴趣的:(Java资料)