阅读 130

MapperFactoryBean和MapperScannerConfigurer的作用和区别

在介绍这两个映射接口之前首先了解这两个接口的目的是啥:

为了代替手工使用 SqlSessionDaoSupport 或 SqlSessionTemplate 编写数据访问对象(DAO)的代码,MyBatis-Spring 提供了一个动态代理的实现——MapperFactoryBean。这个类可以让你直接注入数据映射器接口到你的 service 层bean 中。当使用映射器时,你仅仅如调用你的 DAO 一样调用它们就可以了,但是你不需要编写任何 DAO 实现的代码,因为 MyBatis-Spring将会为你创建代理。同样,MapperFactoryBean创建的代理控制开放和关闭 session

也就是说dao层的对数据访问对象被映射器直接注入到了service层,因此这个dao实现类就没必要写和注册了,从而简化操作,那么sqlsession也就不需要了吧。

先详细回顾一下之前的spring的原生sqlsession方法,也就是使用到了dao实现层。

方法一:使用SqlSessionTemplate生成Mapper

需要先在spring-dao.xml里面注册
















 

dao层里面创建实现UserMapper的类

package com.bupt.dao;

import com.bupt.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;

import java.util.List;

public class UserMapperImpl implements UserMapper{

    private SqlSessionTemplate sqlSessionTemplate;

    public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    @Override
    public List selectUser() {
        return sqlSessionTemplate.getMapper(UserMapper.class).selectUser();
    }

    @Override
    public int addUser(User user) {
        return 0;
    }

    @Override
    public int deleteUser(int id) {
        return 0;
    }
}

可以看到此时sqlSessionTemplate因为已经被注册到spring-dao.xml里面,通过set方法便可以直接获取sqlSessionTemplate对象,通过该对象生成Mapper调用相关的数据操作方法。

方法二:继承SqlSessionDaoSupport生成Mapper

该方法只需要继承SqlSessionDaoSupport类便可以直接获取sqlSession对象,因此不需要额外的注册Bean

dao层里面创建实现UserMapper的类UserDaoImpl.java

package com.bupt.dao;

import com.bupt.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper {

//   SqlSessionDaoSupport有一个getSqlSession方法可以直接获取一个sqlsession对象
    @Override
    public List selectUser() {
        User user = new User(445,"小明","123456");
        UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
        mapper.addUser(user);
        mapper.deleteUser(444);
        return mapper.selectUser();
    }

    @Override
    public int addUser(User user) {

        return getSqlSession().getMapper(UserMapper.class).addUser(user);
    }

    @Override
    public int deleteUser(int id) {
        return getSqlSession().getMapper(UserMapper.class).deleteUser(id);
    }
}

通过这两种方法在dao层里面封装了sqlsession对dao的操作,因此可以在service层里面去直接调用就可以操作数据库了,不过要先把上面的两种方法注册到spring里面ApplicationContext.xml

    class="com.bupt.dao.UserMapperImpl">
        
    

    class="com.bupt.dao.UserDaoImpl">
        
    

 

先写个测试看一下

    @Test
    public void test04(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        UserMapper userMapper = classPathXmlApplicationContext.getBean("userMapper", UserMapper.class);
        for (User user : userMapper.selectUser()) {
            System.out.println(user);
        }
    }

    @Test
    public void test05(){
        ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml");
        UserMapper userMapper = classPathXmlApplicationContext.getBean("userDao", UserMapper.class);
        for (User user : userMapper.selectUser()) {
            System.out.println(user);
        }
    }
 

 

 

可以看到这两种方法都是spring的生成sqlsession获取Mapper操作dao方法的两种对策,但是spring也提供了进一步的封装技术,也就是不需要显示的去获取sqlsession操作dao,MapperFactoryBean就是其中

一个技术。

方法三:MapperFactoryBean封装sqlsession

mybatis-config.xml


DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">


    
        <package name="com.bupt.pojo"/>
    


spring-dao.xml

class="com.mchange.v2.c3p0.ComboPooledDataSource">

        
        
        
        

        
        
        
        

        
     

    class="org.mybatis.spring.SqlSessionFactoryBean">

        

        
    
class="org.mybatis.spring.mapper.MapperFactoryBean">
    
    
 

 

通过注册MapperFactoryBean我们就不要去写Mapper接口的实现类(也就是封装了sqlsession的使用),就可以直接在service里面进行使用,dao里面只需要BookMapper接口和对应的sql操作的xml文件

 

在service层里面可以直接通过set方法注入dao里面的接口,通过接口对象直接使用操作数据库的方法

 

BookService接口

package com.bupt.service;

import com.bupt.pojo.Books;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface BookService {
    //增加一个Book
    int addBook(Books book);
    //根据id删除一个Book
    int deleteBookById(int id);
    //更新Book
    int updateBook(Books books);
    //根据id查询,返回一个Book
    Books queryBookById(int id);
    //查询全部Book,返回list集合
    List queryAllBook();

    List queryBookByName(@Param("bookName") String bookname);
}

BookServiceImpl实现类

package com.bupt.service;

import com.bupt.dao.BookMapper;
import com.bupt.pojo.Books;

import java.util.List;

public class BookServiceImpl implements BookService{

    //调用dao层的操作,设置一个set接口,方便Spring管理
    private BookMapper bookMapper;

    public void setBookMapper(BookMapper bookMapper) {
        this.bookMapper = bookMapper;
    }

    public int addBook(Books book) {
        return bookMapper.addBook(book);
    }

    public int deleteBookById(int id) {
        return bookMapper.deleteBookById(id);
    }

    public int updateBook(Books books) {
        return bookMapper.updateBook(books);
    }

    public Books queryBookById(int id) {
        return bookMapper.queryBookById(id);
    }

    public List queryAllBook() {
        return bookMapper.queryAllBook();
    }

    @Override
    public List queryBookByName(String bookname) {
        return bookMapper.queryBookByName(bookname);
    }

}

然后把service层进行注入到bean里面

在spring-service.xml里面(其中bookMapper已经被自动注册)

    
    package="com.bupt.service" />

    
    class="com.bupt.service.BookServiceImpl">

这样就可以直接在control里面使用该service

 @Resource(name = "BookServiceImpl")
    private BookService bookService;
    @RequestMapping("/allBook")
    public String list(Model model){
        List books = bookService.queryAllBook();
        model.addAttribute("list",books);
        return "allbook";

    }

关于MapperFactoryBean底层的东西可以看这篇文章:

 

但是MapperFactoryBean的一个问题是每个接口我们都需要注册一下,是不是很麻烦。需要用到的映射器较多的话,采用这种配置方式就会很低效。为了解决这个问题,我们可以使用MapperScannerConfigurer,让它扫描特定的包,自动帮我们成批的创建映射器。这样一来,就能大大减少配置的工作量。




其他的相关操作就是和方法三一样,但是由于扫描包的存在可以对包里面的所有接口直接注入,很是方便。

原文:https://www.cnblogs.com/lxyxs/p/15253298.html

文章分类
代码人生
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐