mybatis-spring:mybatis在spring中的使用

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

当我们想在 spring 项目中使用 mybatis 的时候就需要 mybatis-spring 了,它可以让 spring 完美的整合 mybatis 代码。使用这个类库中的类,spring 将会加载必要的 mybatis 工厂类和 session 类。 这个类库也提供一个简单的方式来注入 mybatis 数据映射器和 SqlSession 到业务层的 bean 中。 而且它也会处理事务, 翻译 MyBatis 的异常到 Spring 的 DataAccessException 异常(数据访问异常)中

我们先走一个简单例子,再在基础上扩展

一、例子

1、添加依赖

使用 mybatis-spring 模块,需要添加 mybatis-spring-x.x.x.jar


    org.mybatis
    mybatis-spring
    1.3.2

同时加上 mybatis-x.x.x.jar 包和相关数据库连接包,spring 的依赖添加上 spring-context 和 spring-jdbc,如果是 web 项目,再加上 web 相关的 jar 包即可

2、创建 SqlSessionFactoryBean

我们在使用 mybatis 的时候,最关键的是去使用 SqlSession 去执行映射的 SQL 语句。而 SqlSession 是通过 SqlSesionFactory 来获取的。而 SqlSessionFactory 的实例则是由SqlSessionFactoryBuilder 从 XML 配置文件或一个预先定制的 Configuration 的实例构建出来的

现在,我们是要在 spring 上整合 mybatis,需要把 SqlSessionFactory 的创建和 注入交给 spring容器,在 mybatis-spring 中 SqlSessionFactory 的创建交给了 SqlSessionFactoryBean

我们在项目中创建一个 spring 的配置文件,添加相关配置,加上 SqlSessionFactoryBean 的配置
application-mybatis.xml




    
    

    
    

    
    
        
        
        
        
        
        
    

    
    
    
        
        
        
        
    

    
    
        
    

要注意 SqlSessionFactoryBean 实现了 Spring 的 FactoryBean 接口。 这就说明了由 Spring 最终创建的 bean 不是 SqlSessionFactoryBean 本身。 而是工厂类的 getObject()返回的方法的结果。这种情况下,Spring 将会在应用启动时为你 创建 SqlSessionFactory 对象,然后将它以 SqlSessionFactory 为名来存储。在 Java 中, 相同的代码是:
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
SqlSessionFactory sessionFactory = factoryBean.getObject();
但是一般我们不直接使用 SqlSessionFactoryBean 或 SqlSessionFactory。因为 session 工厂将会被注入到映射器中 或其它扩展了 SqlSessionDaoSupport 的 DAO(Data Access Object,数据访问对象)中

SqlSessionFactory有三个属性

  • dataSource 属性是必须的,配置数据源信息
  • configLocation 属性用来指定 MyBatis 的 XML 配置文件路径,如果基本的 MyBatis 配置需要改变(通常这会是的部分)
  • mapperLocations 属性用来指定映射器文件的资源位置

mapperLocations 可以配置多个位置


    
        classpath*:conf/mybatis/**/*Mapper.xml
        classpath*:conf/com/brave/**/*Mapper.xml
    

3、使用 SqlSessionTemplate

在 mybatis 中,我们使用 SqlSessionFactory 来创建 SqlSession。获取了一个 session 之后,使用它来执行映射的 SQL 语句、提交或回滚连接,最后当不再需要它的时候关闭 session。
使用 mybatis-spring 之后,就不需要直接使用 SqlSessionFactory 了,因为你的 bean 可以通过一个线程安全的 SqlSession 来注入,基于 spring 的事务配置来自动提交、回滚、关闭 session。

1)SqlSessionTemplate

SqlSessionTemplate 是 mybatis-spring 的核心。它负责管理 mybatis 的 SqlSession, 调用 mybatis 的 SQL 方法、翻译异常。它是线程安全的,可以被多个 DAO 所共享使用。
当调用 SQL 方法时,包含从映射器 getMapper()方法返回的方法,SqlSessionTemplate 将会保证使用的 SqlSession 是和当前 Spring 的事务相关的。它管理这 session 的生命周期,包含必要的关闭,提交或回滚操作。

SqlSessionTemplate 对象可以使用 SqlSessionFactory 作为构造方法的参数来创建


  
  
  

SqlSessionTemplate 实现了 SqlSession 接口,不用再代码中对 mybatis 的 SqlSession 进行替换,直接在 Dao bean中直接注入这个 SqlSession 属性就可以了

@Repository
public class UpmsUserDaoImpl implements UpmsUserDao {

    @Autowired
    private SqlSession sqlSession;

    @Override
    public UpmsUser selectOne(Long userId) {
        return sqlSession.selectOne("com.brave.dao.UpmsUserDao.selectOne", userId);
    }

    @Override
    public List selectUser(UpmsUser upmsUser) {
        return sqlSession.selectList("com.brave.dao.UpmsUserDao.selectUser", upmsUser);
    }

    @Override
    public int insertUser(UpmsUser upmsUser) {
        return sqlSession.insert("com.brave.dao.UpmsUserDao.insertUser", upmsUser);
    }
}

这里附上我的映射文件 upmsUserMapper.xml





    
        
        
        
        
        
        
        
        
        
    

    

    
    
    
        insert into upms_user (user_id,loginname,password,realname,is_locked)
        value(#{userId},#{loginname},#{password},#{realname},#{locked})
    


使用 Junit 生成测试类

@RunWith(SpringJUnit4ClassRunner.class)  //使用junit4进行测试  
@ContextConfiguration ("/conf/spring/applicationContext*.xml") 
public class UpmsUserDaoImplTest {
    
    @Autowired
    private UpmsUserDao upmsUserDao;

    @Test
    public void testSelectOne() {
        System.out.println(upmsUserDao.selectOne(10001L).toString());
    }

    @Test
    public void testSelectUser() {
        UpmsUser user = new UpmsUser();
        user.setLoginname("zou");
        user.setUserId(2L);
        List upmsUsers = upmsUserDao.selectUser(user);
        for (UpmsUser upmsUser : upmsUsers) {
            System.out.println(upmsUser.toString());
        }
    }

    @Test
    @Transactional //声明需要事务
    public void testInsertUser() {
        UpmsUser upmsUser = new UpmsUser();
        upmsUser.setUserId(10002L);
        upmsUser.setLoginname("zou");
        upmsUser.setPassword("123456");
        upmsUser.setLocked(false);
        int n = upmsUserDao.insertUser(upmsUser);
        System.out.println("插入" + n + "行");
    }
}

2) SqlSessionDaoSupport

SqlSessionDaoSupport 是一个抽象的支持类,用来提供 SqlSession。getSqlSession()方法可以得到一个 SqlSessionTemplate

public class UpmsUserDaoImpl2 extends SqlSessionDaoSupport implements UpmsUserDao {
    @Override
    public UpmsUser selectOne(Long userId) {
        return getSqlSession().selectOne("com.brave.dao.UpmsUserDao.selectOne", userId);
    }
}

SqlSessionDaoSupport 需要设置一个 sqlSessionFactory 或 sqlSessionTemplate 属性
假如是 UpmsUserDaoImpl2 继承了 SqlSessionDaoSupport:


  

可以创建一个公用的 SuperDao 去继承 SqlSessionDaoSupport,为 SuperDao 设置 sqlSessionFactory 属性,然后让其他 dao 去继承 SuperDao,这样就不用每个 dao 都去设置这个属性了

public class SuperDao extends SqlSessionDaoSupport {
    @Autowired
    public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
       super.setSqlSessionFactory(sqlSessionFactory);
    }
}

不过通常我们更常用 MapperFactoryBean(只需要接口,不用实现类),因为它不需要额外的代码。但是如果需要在 DAO 中做其它非 MyBatis 的工作或需要具体的类,那么这个类就很有用了。

二、事务

mybatis-spring 允许 mybatis 参与到 spring 的事务管理中。利用了存在于 Spring 中的 DataSourceTransactionManager,而不是创建一个新的特定的事务管理器

一旦 Spring 的 PlatformTransactionManager 配置好了,可以在 spring 中以通常的做法来配置事务。@Transactional 注解和 AOP 样式的配置都是支持的。在事务处理期间,一个单独的 SqlSession 对象将会被创建和使用。当事务完成时,这个 session 会以合适的方式提交或回滚。

一旦事务创建之后,mybatis-spring 将会透明的管理事务。在你的 DAO 类中就不需要额外的代码了

1、标准配置

要 开 启 Spring 的 事 务 处 理 , 在 Spring 的 XML 配 置 文 件 中 简 单 创 建 一 个 DataSourceTransactionManager 对象:


  

三、注入映射器

在 mybatis 中,我们可以创建一个来绑定映射的语句的接口映射器(实际上也就是我们的 dao 接口),在映射文件的命名空间与我们的映射器完全限定名一致,映射语句id名就是映射器的方法名,这样我们可以不用实现这个映射器,通过 sqlSession 获取映射器,直接使用 sql 方法

UpmsUserDao upmsUserDao = sqlSession.getMapper(UpmsUserDao.class);
UpmsUse upmsUse = upmsUserDao.selectOne(10002L);

为了代替手工使用 SqlSessionDaoSupport 或 SqlSessionTemplate 编写数据访问对象 (DAO)的代码,mybatis-spring 也提供了一个动态代理的实现:MapperFactoryBean。这个类可以让你直接注入 数据映射器接口 到你的 service 层 bean 中。当使用映射器时,直接调用就可以了,不需要实现 DAO接口,因为 mybatis-spring 将会为你创建代理。

使用注入的映射器代码,在 mybatis、spring 或 mybatis-spring 上面不会有直接的依赖。 MapperFactoryBean 创建的代理控制开放和关闭 session,会翻译任意的异常到 spring 的 DataAccessException 异常中。此外,如果需要或参与到一个已经存在活动事务中,代理将会开启一个新的 spring 事务。

1、MapperFactoryBean

想要直接使用 数据映射器接口,先添加 MapperFactoryBean 到 spring 中:


    
    

MapperFactoryBean 创建的代理类实现了 UpmsUserMapper 接口,并且注入到应用程序中。 因为代理创建在运行时环境中,那么指定的映射器必须是一个接口,而不是一个具体的实现类。

如果 XML 映射器文件在类路径的位置和映射器类相同时,它会被 MapperFactoryBean 自动解析,否则你需要在 SqlSessionFactoryBean 的 mapperLocations 或是在 mybatis 的配置文件中指明映射文件的位置

这里附上映射文件,这里的命名空间一定要是映射器的完全限定名





    
    

接口映射器 UpmsUserMapper.java

public interface UpmsUserMapper {
    List selectUser();
}

然后我们在应用程序逻辑中可以直接使用

@Service
public class UpmsUserServiceImpl implements UpmsUserService {
    @Autowired
    private UpmsUserMapper upmsUserMapper;

    @Override
    public List listUser() {
         return upmsUserMapper.selectUser();
    }
}

2、MapperScannerConfigurer

我们没有必要在 spring 的 XML 配置文件中注册所有的映射器。只用使用一个 MapperScannerConfigurer 即可,它会查找类路径下的映射器并自动将它们创建成 MapperFactoryBean


  

这样就不用每个 mapper 都配置一个 MapperFactoryBean 了

basePackage 属性是让你为映射器接口文件设置基本的包路径。 可以使用 分号 或 逗号 作为分隔符设置多于一个的包路径。每个映射器将会在指定的包路径中递归地被搜索到

3、@MapperScan 和 mybatis:scan

另外还有两种扫描映射器的方法

  • 元素
  • @MapperScan 注解

1) 元素

元素将在特定的以逗号分隔的包名列表中搜索映射器 mapper 接口。 要使用这个元素需要添加以下的 schema 声明


    
    


2) @MapperScan

如果使用基于java的配置,可以使用@MapperScan 注解来扫描映射器 Mapper 接口。 @MapperScan 和 工作方式 相同,并且也提供了对应的自定义选项
在 spring-boot 项目中可能会使用到

@SpringBootApplication  
@MapperScan("com.brave.mapper")  
public class App {  
    public static void main(String[] args) {  
       SpringApplication.run(App.class, args);  
    }  
} 

转载于:https://my.oschina.net/morgan412/blog/2998893

你可能感兴趣的:(mybatis-spring:mybatis在spring中的使用)