02.Mybatis入门案例

1.mybatis的入门

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


配置一下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()返回的代理对象
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<User> 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<User> findAll();
}

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

    <mappers>
        <!--使用xml的时候用resource属性指定位置-->
        <!-- <mapper resource="com/itheima/dao/IUserDao.xml"></mapper>-->
        <!--使用注解的时候用class属性指定全限定类名-->
        <mapper class="com.itheima.dao.IUserDao"></mapper>
    </mappers>

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

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

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

我们不再需要代理实现类

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

session对象的方法

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


UserDaoImpl2

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


image.png

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


selectList方法里的参数的statement究竟该是什么?

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


这样写是错误的

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

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

<mapper namespace>

于是我们在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<User> findAll() {
        //用SqlSessionFactory创建SqlSeesion
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //使用SqlSession查询所有方法
        List<User> lists = sqlSession.selectList("com.itheima.dao.IUserDao.findAll");
        //释放资源
        sqlSession.close();
        //返回结果
        return lists;
    }
}

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

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


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实现类接口即可
(我试了下没懂老师是什么意思,先记录在这里)


简单就直接getMapper实现功能

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


多创建一个类的优势就是能进行灵活封装

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267

推荐阅读更多精彩内容