前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring框架(四)spring整合mybatis全部流程,附代码

Spring框架(四)spring整合mybatis全部流程,附代码

作者头像
一写代码就开心
发布2021-07-08 15:04:51
8020
发布2021-07-08 15:04:51
举报
文章被收录于专栏:java和python

目录

回顾

我们的java ee web项目,使用mybatis操作数据库,是写了一个mybatis.xml,里面是数据源。之后写了一个公共类,这个公共类就是利用这个xml创建对象,以后在业务层就利用这个公共类,创建mapper层的对象,然后调用mapper层对象里面的方法,实现对数据库的操作

使用Servlet+MVC+Mybatis+Jsp完成用户登录

原生的方法实现用户的登录,步骤为:

①在mysql中创建t_user用户信息表(id,name,pwd). ②使用idea创建一个新的web项目,项目名为 01-springioc-mybatis-login ③在web项目中导入相关jar包(SpringIOC的jar+Mybatis的 jar+mysql的jar) ④在web项目中创建login.jsp登录页面,并完善发送登录请求 ⑤在web项目中创建UserServlet,并完善代码处理登录请求 ⑥在web项目中创建UserService业务,并完善代码处理登录业务 ⑦在web项目中创建UserMapper,并完善代码根据用户名和密码 查询用户信息

我们写完mybatis.xml ,直接在业务层创建mapper层的对象,不需要使用工具类了

在这里插入图片描述
在这里插入图片描述

Service层使用Spring获取Mapper对象

问题:

目前我们开发功能的流程中,在service层会手动创建SQLSession对象,并使用SQLSession对象获取Mapper接口的实例化对象,但是我们真正使用的是Mapper接口的对象,目前的代码编写方式极大的影响了开发效率,而且mybatis层和service 层之间的耦合性非常高

解决:

使用SpringIOC技术实现service层和mybatis层的解耦:说白了就是让Spring容器帮我们获取Mapper层接口的实例化 对象,我们直接从Spring容器中获取使用即可.

===================================== 以前我们还要写一个mybatis.xml,里面写数据源,然后在service层创建mapper层的对象。现在我们不写mybatis,xml了,不在这个里面写数据源了,我们在applicationcontext.xml里面直接写数据源,写好数据源之后我们直接在这个里面创建对象,以后哪个地方要mapper层的对象,直接从这个容器里面拿就可以了。

实现:

①导入SpringIOC的jar包 ②在src下创建并配置Spring的配置文件 配置DataSource数据源的bean 配置SQLSessionFactory的工厂bean(DataSource的bean) 配置mapper扫描bean对象(SQLSessionFactory对象,扫 描路径) ③创建Spring容器对象,并获取Mapper接口的实例化对象完成数据库操作

Controller层使用Spring解耦service层

问题:

在业务层使用Spring容器对象获取Mapper接口实例化对象后实现了 service层和mybatis层的解耦,但是在controller层我们依然在Servlet 中直接创建Service对象,耦合性过高.

解决:

将service对象配置为bean对象,Servlet中从Spring容器中 获取Service对象,完成功能开发.

实现:

①在applicationcontext.xml文件中配置service的bean ②在servlet中的service方法中创建Spring容器对象 ③在servlet中的service方法中从Spring容器中获取 service对象 ④使用service对象完成功能处理

分析java ee web 项目整合的mybatis

获取到mapper层对象,需要sqlsession对象,创建sqlsession对象需要sqlsessionFactory 对象,创建sqlsessionFactory 对象需要sqlsessionFactory Builder()里面的方法build()

以上的这些事必须的

之前以上的这些对象都是我们再service层创建,或者写一个公共类,再service层进行调用。代码如下

sqlsessionFactory
sqlsessionFactory

问题

每次都要写sqlsession对象创建之前的那些代码,代码冗余。我们可以把那些交给spring进行创建,并且放到容器里面。mapper层对象,service层对象也可以放到容器里面,以后直接拿就可以了

spring整合mybatis

①导入的jar包:

②在src下创建并配置applicationcontext.xml文件

也就是不用写mybatis.xml了,直接在applicationcontext.xml文件里面写数据源,并且利用这个数据源创建mapper对象,service层对象

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
   


 <!--配置DataSource的bean对象:存储数据库连接参数-->
    <bean id="datasource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="jdbc:mysql://localhost:3306/spring4?characterEncoding=utf8"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>



    <!--配置SQLSessionFactory的bean对象:生产SQLSession-->
    <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="datasource"></property>
    </bean>
    




    <!--配置Mapper扫描的bean对象:使用SQLSession扫描mapper包获取Mapper接口的实例化对象-->
    <bean id="a" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactory" ref="factory"></property>
        <property name="basePackage" value="com.mapper"></property>
    </bean>



    <!--配置service对象-->
    <bean id="us" class="com.service.UserServiceImpl">
        <property name="um" ref="userMapper"></property>
    </bean>
</beans>

③在web.xml文件中配置Spring容器对象的配置文件路径 因为项目开始,先走web.xml,所以得让项目找到我们写 的applicationcontext.xml文件,所以需要在web.xml里面进行配置

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
    <!--配置全局参数:被项目中所有servlet共享-->
    <context-param>
        <param-name>contextConfigLocation</param-name><!--键名-->
        <param-value>classpath:applicationcontext.xml</param-value><!--值-->
    </context-param>
   

 <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
</web-app>

④在Servlet的init方法中完成初始化资源的加载(从Spring容器对象中获取业务层对象)

代码语言:javascript
复制
package com.controller;

import com.pojo.User;
import com.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.async.WebAsyncUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author wuyw2020
 * @date 2020/1/8 20:55
 */
@WebServlet(value = "/user", loadOnStartup = 1)
public class UserServlet extends HttpServlet {
    UserService userService;

    //在初始化方法中完成Spring容器资源的加载
    @Override
    public void init() throws ServletException {
        //获取spring容器对象
        ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        //获取业务层对象
        userService = (UserService) ac.getBean("us");
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        resp.setCharacterEncoding("utf-8");

        String uname = req.getParameter("uname");
        String pwd = req.getParameter("pwd");

        //处理请求
        //调用业务层方法
        User user = userService.userLoginService(uname, pwd);
        //响应结果
        //直接响应
        if (user != null) {
            resp.getWriter().write("登录成功");
        } else {
            resp.getWriter().write("登录失败");
        }

    }
}

⑤在业务层中声明mapper层的属性,并声明对应的get/set方法

代码语言:javascript
复制
package com.service;
import com.mapper.UserMapper;
import com.pojo.User;
/**
 * @author wuyw2020
 * @date 2020/1/8 20:48
 */
public class UserServiceImpl implements UserService{
    private UserMapper um;//定义mapper层的属性

//定义mapper层的get   set  方法
    public UserMapper getUm() {
        return um;
    }
    public void setUm(UserMapper um) {
        this.um = um;
    }
    @Override
    public User userLoginService(String uname, String pwd) {
        User user = um.userLoginMapper(uname, pwd);
        return user;
    }
}

⑥正常完成功能开发即可

SpringIOC的创建对象的单例多例模式和自动注入

SpringIOC创建对象的单例和多例模式

问题:

Spring容器对象根据配置文件创建对象的时机默认发生在Spring容器对象在被创建的时候,也就是说,我们一旦获取到Spring容器对象,意味着可以直接获取Spring容器中的对象使用了.

那么,如果我对同一个bean对象,连续获取N次,获取到的是不是同一个对象呢?因为spring容器对象底层使用的是map集合存储的bean对象,对map集合按照同一个键名获取数据,获取的是同一个,也就说按照同一个键名从Spring容器中获取的都是同一个对象,

那么如果我们希望相同的键名获取的对象每次都不一样,怎么实现?

解决:

不要在Spring容器对象创建的时候,就完成对象的初始化创建,而是变为,从Spring容器中获取的时候才创建,每次获取都重新创建.

实现:

Spring容器的单例和多例模式创建对象.

单例模式(默认):

设置了单例模式的bean,会在Spring容器对象被创建的时候 就完成初始化创建,无论获取多少次都是同一个对象.

多例模式:

设置了多例模式的bean,在Spring容器对象被创建的时候不会被初 始化创建,每次获取的时候都会重新创建,每次获取的对象都不相同.

使用:

applicationcontext.xml:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
    SpringIOC设置对象的单例模式和多例模式创建对象
    单例模式:默认模式,在bean标签上使用scope属性,默认值为singleton
    多例模式:在bean标签上使用scope属性设置,值为prototype
    -->
    <bean id="stu" class="com.pojo.Student" scope="singleton"></bean>
    <bean id="tea" class="com.pojo.Teacher" scope="prototype"></bean>
</beans>
代码语言:javascript
复制
TestIocModel
package com.controller;
import com.pojo.User;
import com.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.async.WebAsyncUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.rmi.CORBA.StubDelegate;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
 * @author wuyw2020
 * @date 2020/1/8 20:55
 */
@WebServlet(value = "/user", loadOnStartup = 1)
public class UserServlet extends HttpServlet {
   
    public static void main(String[] args) {
        //获取Spring容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationcontext.xml");
        Student stu =(Student) ac.getBean("stu");
        Student stu2 =(Student) ac.getBean("stu");
        
        Teacher teacher = (Teacher) ac.getBean("stu");
        Teacher teacher2 = (Teacher) ac.getBean("stu");
        System.out.println("学生:"+(stu==stu2));
        System.out.println("教室:"+(teacher==teacher2));
    }
}

SpringIOC的自动注入

问题:

在学习了SpringIOC的DI依赖注入后,我们可以根据对象之间的依赖关系的 责任链,让Spring容器对象帮我们创建有一个组装好的对象,比如A中有B,B 中有C,C中有D.将A,B ,C,D都创建为Bean对象,然后使用ref属性告诉Spring 对象之间的依赖关系的组装规则,假如依赖责任链特别长,使用ref注入就会很 麻烦.怎么办?

解决:

不要声明ref属性来指明依赖关系的注入,只需要告诉Spring容器对象依赖关 系的注入规则,Spring容器对象自动根据规则完成依赖关系的注入.

实现:

①根据bean的ID和属性名一致的规则 ②根据bean的类型和属性的类型一致的规则 ③根据构造器形参的类型和bean的类型一致的规则 ④不能使用自动注入,只能手动声明 ⑤使用默认规则

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
       default-autowire="byName"><!--设置自动注入-->
    <!--
       自动注入:
       在标签上使用autowire属性设置自动注入规则.该属性声明在要注入资源的bean标签上,比如:学生的bean
         autowire属性的值:
           byName:按照属性名和某个bean的id相同的规则自动注入
           byType:按照属性的类型和某个bean的类型相同的规则自动注入.
               注意:同类型的bean只能有一个,否则报错.
           constructor:
               必须声明对应的构造器,根据构造器形参的类型和某个bean的类型相同的规则自动注入.
           no:不使用自动注入,必须使用ref手动注入.
           default:使用默认注入规则.默认值.
           注意:
                可以在beans顶层元标记中使用属性default-autowire声明全局自动注入规则.
   -->
    <bean id="stu" class="com.pojo.Student" autowire="byName">
        <!--用构造器的方法,此处要创建一个只有Teacher一个参数的构造器-->
        <!--<constructor-arg index="0" type="com.Teacher"  ref="tea"></constructor-arg>-->
        <property name="sid" value="1"></property>
        <property name="sname" value="张三"></property>
    </bean>



    <bean id="teacher" class="com.Teacher">
        <property name="tname" value="liu"></property>
        <property name="tid" value="1"></property>
    </bean>
</beans>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/07/01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • 回顾
  • 使用Servlet+MVC+Mybatis+Jsp完成用户登录
  • Service层使用Spring获取Mapper对象
    • 问题:
      • 解决:
        • 实现:
        • Controller层使用Spring解耦service层
          • 问题:
            • 解决:
              • 实现:
              • 分析java ee web 项目整合的mybatis
                • 问题
                • spring整合mybatis
                • SpringIOC的创建对象的单例多例模式和自动注入
                  • SpringIOC创建对象的单例和多例模式
                    • 问题:
                    • 解决:
                    • 实现:
                    • 使用:
                  • SpringIOC的自动注入
                    • 问题:
                    • 解决:
                    • 实现:
                相关产品与服务
                容器服务
                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档