spring框架-与mybatis的整合(二)--SM编程DAO层开发

1.到目前为止引入的依赖

spring  mybatis mysql   mybatis-spring  druid

2.编写spring.xml

整合:spring接管mybatis中SqlSessionFactory对象的创建
<!--创建数据源-->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/sm_learn?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull"></property>
    <property name="username" value="root"></property>
    <property name="password" value="123456"></property>
</bean>
<!--创建sqlSessionFactory-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactoryBean">
    <!--依赖的数据源-->
    <property name="dataSource" ref="dataSource"></property>
</bean>

3.建表

CREATE TABLE IF NOT EXISTS CF_USER_T(
    USER_ID INT PRIMARY KEY COMMENT'用户登录ID',
    USER_NAME VARCHAR(200) COMMENT'用户名',
    USER_AGE INT COMMENT'年龄',
    USER_SEX INT COMMENT'用户性别',
    USER_TEL VARCHAR(20) COMMENT'用户电话号码',
    USER_PASSWORD VARCHAR(20) COMMENT'用户登录密码'
) COMMENT'用户信息表'

4.实体类

package com.cf.testsmdao.entity;

import lombok.Data;

/**
 * User: 晨风
 * <p>
 * Author:
 * Date: 22:56
 */
@Data
public class User {
    private Long userId;
    private int userAge;
    private int userSex;
    private String userName;
    private String password;
    private String userTel;

    public User() {
    }

    public User(Long userId, int userAge, int userSex, String userName, String password, String userTel) {
        this.userId = userId;
        this.userAge = userAge;
        this.userSex = userSex;
        this.userName = userName;
        this.password = password;
        this.userTel = userTel;
    }
}

5.开发dao层接口

package com.cf.testsmdao.dao;

import com.cf.testsmdao.entity.User;

import java.util.List;

/**
 * @author yourname
 * @date 2021/4/16 23:04
 */
public interface UserDAO {
    void save();
    List<User> find();
}

6.开发mapper

<?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 namespace="com.cf.testsmdao.dao.UserDAO">


    <select id="find" resultType="com.cf.testsmdao.entity.User">
      select
      USER_ID userId,
      USER_NAME userName,
      USER_AGE userAge,
      USER_SEX userSex,
      USER_TEL userTel,
      USER_PASSWORD password from CF_USER_T


    </select>

</mapper>

7.启动工厂获取SqlSessionFactory

package com.cf.testsmdao.test;

import com.cf.testsmdao.dao.UserDAO;
import com.cf.testsmdao.entity.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

/**
 * User: 裴晨风
 * <p>
 * Author:
 * Date: 23:34
 */
public class TestMapper {
    @Test
    public void test() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/cf/sm2/spring.xml");
        SqlSessionFactory sessionFactory = (SqlSessionFactory) context.getBean("sqlSessionFactoryBean");
        SqlSession sqlSession = sessionFactory.openSession();
        UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
        userDAO.find().forEach(System.out::println);
        //User(userId=1, userAge=18, userSex=1, userName=小一, password=a11111, userTel=11111)
        //User(userId=2, userAge=19, userSex=2, userName=小二, password=a22222, userTel=22222)
    }
}

8.改进

虽然学到这里,感觉框架的封装已经很妙了,但是我们可以从test中发现,每次要获取DAO,我们都需要走三个步骤。

1).获取SqlSessionFactory ->{SqlSessionFactory sessionFactory = (SqlSessionFactory) context.getBean("sqlSessionFactoryBean");}

2).通过SqlSessionFactory 创建SqlSession -> {SqlSession sqlSession = sessionFactory.openSession();}

3).通过SqlSession 获取到dao的mapper文件-> {UserDAO userDAO = sqlSession.getMapper(UserDAO.class);}

然后,我们通过调用dao层的方法后,会执行mapper中的对应方法的sql语句,对数据库进行crud。

但是如果每次调用dao层时,都要经过这三个步骤的话,未免太过繁琐。因为我们不关心取mapper的过程(创建mybatis的核心对象SqlSessionFactory->创建SqlSession ->sqlSession.getMapper(UserDAO.class)),我们只要最后获取到mapper就可以了,当然是一步到位最好。

如何一步到位呢?

首先,我们可以回想下spring的AOP思想,将这三步封装成一个前置通知是否可以呢?将切面设定为所有dao层内的方法,然后每次调用dao方法的时候,执行前置通知获取mapper。

思考了下,应该是不可以。对比下之前未整合mybatis时的AOP编程代码,可以看到,当时的dao层方法可以执行,是基于有其对应的实现类。而整合mybatis后,我的理解是此时的dao层的实现其实就是对应的mapper文件中的sql语句。而获取mapper正是dao层得以实现的必要条件。如果封装成前置通知,那大概意思就是这样了:执行dao的方法前,在前置通知中获取对应的mapper文件。其中有两点有待商榷:1.dao的方法能够执行么?2.通知的定义是对业务功能之外的附加功能的实现。即:前置通知可以是业务功能实现的必要条件吗?以我现在的只是储备量来思考的话,是不能够的。

mybatis想的很周到:

mybatis-spring jar包中的org.mybatis.spring.mapper.MapperFactoryBean已经封装了getMapper的过程

 <!-- 创建DAO组件类-->
    <!-- 创建userDAO-->
    <bean id="userDAO" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <!-- 注入SqlSessionFactory-->
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
        <!-- 注入创建DAO接口类型  注入接口的全限定名 包.接口名-->
        <property name="mapperInterface" value="com.cf.testsmdao.dao.UserDAO"></property>
    </bean>

    <!-- 创建studentDAO-->
    <bean id="studentDAO" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <!-- 注入SqlSessionFactory-->
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
        <!-- 注入创建DAO接口类型  注入接口的全限定名 包.接口名-->
        <property name="mapperInterface" value="com.cf.testsmdao.dao.studentDAO"></property>
    </bean>

于是一步到位,我们想要获取哪个mapper,只需要在配置文件中注入即可value="com.cf.testsmdao.dao.studentDAO"。

此时,再回顾一下整个整合的思路:

1.什么是复杂对象?复杂对象怎么创建?

a.复杂对象:不可通过new创建实例的对象

b.复杂对象怎么创建:创建对应bean类,在类中通过重写getObject自定义创建复杂对象

2.spring整合mybatis的切入点是什么?

掌握mybatis的核心对象的创建

3.SqlSessionFactory核心对象如何通过spring工厂创建?

a.引入mybatis-spring jar包

b.注入依赖-数据源dataSource

4.spring工厂创建SqlSessionFactory后,怎么通过SqlSessionFactory获取到dao的mapper文件?

a.SqlSessionFactory bean中  注入依赖--要获取的mapper文件

b.获取SqlSessionFactory 

c.通过SqlSessionFactory 创建SqlSession 

d.通过SqlSession 获取到dao的mapper文件

5.如何封装获取mapper的过程?或者说直接获取dao层?

a.引入org.mybatis.spring.mapper.MapperFactoryBean

b.注入依赖--含有mapper文件依赖的SqlSessionFactory bean

c.注入依赖--获取哪个dao的mapper文件

感想:

整合mybatis之前,通过spring生成一个对象是那么的简单,工厂中对象的路径一写,id一确定,要啥属性就注入啥,工厂启动后拿来对象就能用。

整合mybatis后,先是复杂对象的创建,然后再是复杂对象创建的封装,封装的过程中又伴随着许多复杂的依赖注入。所幸,结果是一样的,还是工厂启动后拿来就能用。

另:在工作中springboot用起来是真的方便,没有这么多依赖、配置。实现持久化也不需要先得到SqlSessionFactory 再得到xxx最后得到mapper。只要mapper中namespace关联上dao层路径,方法id一致,直接new出来就能实现。

会不会是,越高端的框架使用起来就越简单呢?然而当你用起来很简单的时候,你就忽略了他的底层实现,想都不会想一下。

希望我一直努力学下去,对框架封装的那些思想原理不再是一头雾水。

最好的软件是傻子都会用的。

但是身为一个开发者,不能真的像个傻子一样对自己使用的技术一无所知!

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

推荐阅读更多精彩内容

  • 夜莺2517阅读 127,720评论 1 9
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,536评论 28 53
  • 兔子虽然是枚小硕 但学校的硕士四人寝不够 就被分到了博士楼里 两人一间 在学校的最西边 靠山 兔子的室友身体不好 ...
    待业的兔子阅读 2,603评论 2 9
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,190评论 4 8