02.Mybatis入门案例

1.mybatis的入门

首先我们需要配置一下log4j.properties文件


02.Mybatis入门案例_第1张图片
配置一下log4j.properties

代码如下,直接放进resource文件里就可以.

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE            debug   info   warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE

# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE

# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n

接下来再往后,入门的时候,我们创建一个测试类,我们使用main函数来执行。

main函数的思路: 读取配置文件 创建SqlSessionFactory工厂 创建SqlSession对象 创建Dao接口的代理对象 执行dao长的方法 释放资源


1.读取配置文件

通过读取配置文件来准备一个工厂 工厂来创建一个对象 用于提供Dao的实现 有了Dao的实现就能提供查询方法 从而实现功能


2.创建SqlSessionFactory工厂

SqlSessionFactory是一个接口,我们要用它的实现类,我们使用这个工厂,不外乎就是为了创建对象,于是Mybatis给我们提供工厂的时候,把工厂的实现细节给省略了,它为我们准备了一个SqlSessionFactoryBuilder的对象,这个对象可以直接new,new这个对象的好处就是我们用builder.build来构建工厂把流传进去,如何解析如何封装的细节都被隐藏起来,我们可以不再管,以后的事情就交给mybatis。


4.使用SqlSession创建Dao接口的代理对象

有了openSession 以后,我们可以用IUserDao来去接受session.getMapper()返回的代理对象
02.Mybatis入门案例_第2张图片
5.使用代理对象执行方法

有了代理对象后,我们就可以使用代理对象来执行方法,得到返回的List,并遍历出结果。


6.释放资源

接下来就是释放资源了

完整代码:

public class Test {
    public static void main(String[] args)throws Exception {
        //1.读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.使用工厂生产SqlSession对象
        SqlSession session = factory.openSession();
        //4.使用SqlSession创建Dao接口的代理对象
        IUserDao userDao = session.getMapper(IUserDao.class);
        //5.使用代理对象执行方法
        List users = userDao.findAll();
        for(User user : users){
            System.out.println(user);
        }
        //6.释放资源
        session.close();
        in.close();
    }
}

到了这一步,还没有完成我们的流程
mybatis框架 并不知道查询完了以后要封装到哪里去,它并不清楚实体类和表的关系。


配置resultType

我们在开发过程中,除了Sql语句,还需要配置 ResultType 返回类型,当我们执行了findAll语句,实现封装的时候,会把结果集封装在User对象里,并把User对象添加到List当中,这样,我们的功能就完整了。

初学Mybatis,这些都是新的知识,不必过于纠结,关注流程就好。

mybatis的入门案例的步骤总结

  • 读取配置文件
  • 创建SqlSessionFactory工厂
  • 创建SqlSession对象
  • 创建Dao接口的代理对象
  • 执行dao长的方法
  • 释放资源、

还需要两点需要注意

  • 用代理的方式,不写Dao接口
  • 配置的过程中 必须说清楚,要配置到哪里去
    我们强调这两点,是为了自定义Mybatis时把一些情况说明白。
2.mybatis 注解开发和编写dao实现类的方式
  • ①mybatis基于注解的入门案例

如果我们觉得xml方式很麻烦,我们用注解的方式一样的也能实现功能。

注解如何使用?xml将不再有意义,可以删掉了,但是主配置文件是仍需要保存的。

使用注解的方式是在dao的方法上打上注解,我们的findAll方法是查询功能,我们用到了@select注解

package com.itheima.dao;

import com.itheima.domain.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @author 黑马程序员
 * @Company http://www.ithiema.com
 *
 * 用户的持久层接口
 */

public interface IUserDao {

    /**
     * 查询所有操作
     * @return
     */
    @Select("select * from user")
    List findAll();
}

在SqlMaoConfigxml文件中 我们指定了映射文件的位置 现在我们不是用配置文件了,我们应该用class属性来指定注解的dao的全限定类名。

    
        
        
        
        
    

我们运行一下,可以看到结果仍然能查询出来。注解比起来xml更加简单,它不再需要指定id和和返回类型。
总结
把 IUserDao.xml移除,在dao接口的方法上使用@Select注解,并指定Sql语句。
同时需要在SqlMapConfig中mapper配置时,使用class属性指定dao的全限定类名。

  • ②编写dao实现类的方式
    我们在实际开发中都是越简单越好,所以都是采用不写dao实现类的方式,不管是xml和注解配置。
    mybatis也是支持写实现类的,如果我们需要写实现类,那要如何使用?

有实现类的时候我们需要提供方法来实现功能,我们需要通过测试类的sqlSession这个对象来看一看。
我们现在有了实现类,就不再需要代理实现类。

02.Mybatis入门案例_第3张图片
我们不再需要代理实现类

session有很多方法 selectForList 就是我们需要的,因为它返回的是一个List,但我们不是在这里用到它,而是在dao里面。

02.Mybatis入门案例_第4张图片
session对象的方法

现在我们拥有了Dao的实现类 UserDaoImpl2,它里面需要有session对象的selectList方法。


02.Mybatis入门案例_第5张图片
UserDaoImpl2

我们现在是没有session对象的,于是我们需要定义一个能拿到session对象的SqlSessionFactory。
SqlSessionFactory怎么能保证它一定有值呢?
我们只需要在创建的时候传值就可以,换句话说,我们把默认构造函数给覆盖掉,这就相当于没有默认构造函数了。
当我们用的时候,它就一定会给我们传一个工厂进来。


02.Mybatis入门案例_第6张图片
image.png

有了工厂以后,我们就可以使用使用工厂 创建SqlSession对象,再用SqlSesson对象的selectList方法。需要思考的是,selectList方法里的参数的statement究竟该是什么?


02.Mybatis入门案例_第7张图片
selectList方法里的参数的statement究竟该是什么?

我们也许会想,可用在statement里写上Sql语句,但如果在statement里写sql语句,那么我们配置文件又有什么用呢?所以我们的目标是需要读取配置文件里的sql语句。


这样写是错误的

如果我们在这里写上findAll的id,那么也过于理想化了,实际上开发过程中有很多FindAll方法,如何才能找到我们想用的哪个findAll呢?

这个时候这个属性就起到作用了 它就指定了它是IUserDao,并且IUserDao里的id为findAll的方法,它能作为一种唯一标识来使用。

02.Mybatis入门案例_第8张图片

于是我们在statement上写上namespace和方法的id所组成的全限定名
于是我们在statement上写上namespace和方法的id所组成的全限定名

这样我们就能执行selectList方法了。

完整的IUserDao的代码如下:

package com.itheima.dao.impl;

import com.itheima.dao.IUserDao;
import com.itheima.domain.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import java.util.List;

public class UserDaoImpl implements IUserDao {
    private SqlSessionFactory sqlSessionFactory;

    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory = sqlSessionFactory;
    }

    public List findAll() {
        //用SqlSessionFactory创建SqlSeesion
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //使用SqlSession查询所有方法
        List lists = sqlSession.selectList("com.itheima.dao.IUserDao.findAll");
        //释放资源
        sqlSession.close();
        //返回结果
        return lists;
    }
}

那么现在我们IUserDao的实现类有了方法可实现功能了 。

在测试类中,我们现在通过Dao来执行方法,来得到list。


02.Mybatis入门案例_第9张图片
Test方法

我们用Dao的实现类也同样实现了功能 但是没有意义 因为不写Dao实现类也可以实现功能

那么我们为什么要写Dao的实现类呢 其实我们的目的就是为了说明 namespace 和 id 它们两个的作用,光有id是无法定位到的,还需要namespace。
即使我们用了代理对象来执行方法,也是需要让代理对象知道Sql语句的位置,它也是通过namespace定位到具体的Dao接口,并且根据id定位到方法,找到我们的sql语句。

3.mybatis入门案例中的设计模式分析

读取配置文件绝对路径和相对路径都会遇到一些问题
绝对路径:d:/xxxx/xxxx.xml
那如果我的机器没有D盘怎么办
相对路径: src/java/main/xxxxx.xml
而相对路径大家知道,如果是web工程,一部署,src文件就没了

所以这两种方式我们都不用
读取src文件 只有两招
1.使用类加载器,它只能读取类路径的配置文件
2.使用ServletContext对象的getRealPath(),它能得到当前应用部署的绝对路径,这个绝对路径就是项目运行在哪,它就在哪.

我们的工厂并不是我们自己创建的,创建工厂mybatis使用了构建者模式 什么是构建者模式?
举个例子 我们在创建一个工厂的时候 需要诸多考虑 比如选址 选完地址之后 还需要雇佣人工啊等操作 就费时费力 工厂也不一定建好 所以我们选择了找一个包工队 给他钱 剩下的事就交给他


builder就是构建者

那在这段代码中,builder就是构建者,我们只需要把钱给了它,剩下的事情都不要再操心.这不就是我们框架的目的吗?把繁琐的细节封装起来

生产SqlSession使用了工厂模式 它有降低耦合的作用


SqlSession使用了工厂模式
创建Dao接口实现类使用了代理模式

不修改源码的方式上,对代码进行增强.我们通过代理对象对接口进行增强,实现了不写实现类也能实现功能.

通过这里面的代码我们使用了这么多设计模式 其实它可以非常简单的为我们实现功能,如果要想做的简单,就直接getMapper然后直接拿个dao实现类接口即可
(我试了下没懂老师是什么意思,先记录在这里)


02.Mybatis入门案例_第10张图片
简单就直接getMapper实现功能

既然简单就能实现,那么我们为什么要分步骤写的那么复杂呢 为了灵活 每加出一个类都能可以选择更灵活的配置,比如builder就有很多重载的方法,我们虽然只用了InputStream的对象,但用其他的也行.


02.Mybatis入门案例_第11张图片
多创建一个类的优势就是能进行灵活封装

以后在实际开发中,以后可能就像刚刚老师讲的,以实现项目为目的,把细节隐藏。

你可能感兴趣的:(02.Mybatis入门案例)