Spring整合MyBatis

Spring整合MyBatis

1. 整合思路

1、SqlSessionFactory对象应该放到spring容器中作为单例存在。
2、传统dao的开发方式中,应该从spring容器中获得sqlsession对象。
3、Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象。
4、数据库的连接以及数据库连接池事务管理都交给spring容器来完成。

2 整合需要的依赖

依赖信息有:mysql驱动、druid连接池、mybatis、spring-context、log4j、spring-test、spring-aspects、aopalliance、spring-jdbc
比之前要多加一个mybatis整合spring的依赖:mybatis-spring   (spring-ibatis)

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0modelVersion>

    <groupId>com.qf.springgroupId>
    <artifactId>spring-mybatisartifactId>
    <version>1.0-SNAPSHOTversion>

    <dependencies>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
        dependency>

        
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.45version>
        dependency>

        

        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druidartifactId>
            <version>1.1.6version>
        dependency>

        

        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatisartifactId>
            <version>3.4.6version>
        dependency>


        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-contextartifactId>
            <version>4.3.21.RELEASEversion>
        dependency>
        <dependency>
            <groupId>log4jgroupId>
            <artifactId>log4jartifactId>
            <version>1.2.17version>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-testartifactId>
            <version>4.3.21.RELEASEversion>
        dependency>
        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-aspectsartifactId>
            <version>4.3.21.RELEASEversion>
        dependency>
        <dependency>
            <groupId>aopalliancegroupId>
            <artifactId>aopallianceartifactId>
            <version>1.0version>
        dependency>

        
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-jdbcartifactId>
            <version>4.3.21.RELEASEversion>
        dependency>

        
        
        <dependency>
            <groupId>org.mybatisgroupId>
            <artifactId>mybatis-springartifactId>
            <version>1.3.2version>
        dependency>


    dependencies>


project>

3 整合步骤

创建工程

创建项目spring_mybatis

加入依赖信息

在pom.xml文件中添加

加入配置文件

(1)MyBatis的配置文件:mybatis-config.xml

可以使用Spring的配置文件代替



<configuration>
    <typeAliases>
        
        <package name="com.pojo"/>
    typeAliases>
    

    <mappers>
        <mapper resource="com/mapper/User.xml"/>
        
    mappers>

configuration>

(2)加入Spring配置文件:applicationContext.xml

Spring的配置文件中要包含以下内容

a) 数据库连接及连接池
b) 事务管理(可以不配置)
c) sqlsessionFactory对象,配置到spring容器中
d) mapper代理对象或者是dao实现类配置到spring容器中。

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">


    
    <context:property-placeholder location="classpath:db.properties"/>

    
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

    bean>

    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    bean>

beans>

(3)db.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis_01
jdbc.username=root
jdbc.password=root

(4)log4j.properties

log4j.rootLogger=debug, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d:\\mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

Dao开发

两种dao的实现方式:

1、原始dao的开发方式

2、使用Mapper接口动态代理开发方式

​ a) 直接配置Mapper代理

​ b) 使用扫描包配置Mapper代理

需求:

  1. 实现根据用户 id查询
  2. 实现根据用户名模糊查询
  3. 添加用户
创建pojo

User.java

public class User {
	private int id;
	private String username;// 用户姓名
	private String sex;// 性别
	private Date birthday;// 生日
	private String address;// 地址

	//get/set。。。
}

原始Dao开发

原始的DAO开发:接口+实现类来完成。

添加User.xml文件



<mapper namespace="test">
    
    <select id="queryUserById" parameterType="int" resultType="user">
		select * from user where id = #{id}
	select>

    
    <select id="queryUserByUsername" parameterType="string"
            resultType="user">
		select * from user where username like '%${value}%'
	select>

    
    <insert id="saveUser" parameterType="user">
        <selectKey keyProperty="id" keyColumn="id" order="AFTER"
                   resultType="int">
            select last_insert_id()
        selectKey>
        insert into user
        (username,birthday,sex,address)
        values
        (#{username},#{birthday},#{sex},#{address})
    insert>

mapper>    

实现UserDao接口

UserDao.java

package com.dao;

import com.pojo.User;

import java.util.List;

/**
 * @author wgy 2018/12/20 22:44
 * @version 1.0
 */
public interface UserDao {
    /**
     * 根据id查询用户
     *
     * @param id
     * @return
     */
    User queryUserById(int id);

    /**
     * 根据用户名模糊查询用户列表
     *
     * @param username
     * @return
     */
    List<User> queryUserByUsername(String username);

    /**
     * 保存
     *
     * @param user
     */
    void saveUser(User user);

}

UserDaoImpl实现类

UserDaoImpl.java

编写DAO实现类,实现类必须集成SqlSessionDaoSupport
SqlSessionDaoSupport提供getSqlSession()方法来获取SqlSession
package com.dao.impl;

import com.dao.UserDao;
import com.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

/**
 * @version 1.0
 */
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {
    @Override
    public User queryUserById(int id) {
        // 获取SqlSession
        SqlSession sqlSession = super.getSqlSession();
        // 使用SqlSession执行操作
        User user = sqlSession.selectOne("test.queryUserById", id);
        // 不要关闭sqlSession
        return user;
    }

    @Override
    public List<User> queryUserByUsername(String username) {
        // 获取SqlSession
        SqlSession sqlSession = super.getSqlSession();
        // 使用SqlSession执行操作
        List<User> list = sqlSession.selectList("test.queryUserByUsername", username);
        // 不要关闭sqlSession
        return list;
    }

    @Override
    public void saveUser(User user) {
        // 获取SqlSession
        SqlSession sqlSession = super.getSqlSession();
        // 使用SqlSession执行操作
        sqlSession.insert("test.saveUser", user);
        // 不用提交,框架会默认给你提交
        // 不要关闭sqlSession
    }

}


注意:在dao方法中不能关闭和提交SqlSession对象,由Spring帮助提交和关闭sqlSession

配置dao

applicationContext.xml中添加

 
    <bean id="userDao" class="com.dao.impl.UserDaoImpl">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    bean>

测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserDaoTest {

   @Resource(name ="userDao")
   private UserDao userDao;
    @Test
    public void testFindUserByid(){
        User user = userDao.queryUserById(1);
        System.out.println(user.toString());
    }
}
Mapper接口代理形式开发dao

实现Mapper.xml

** UserMapper.xml**



<mapper namespace="com.mapper.UserMapper">
    
    <select id="queryUserById" parameterType="int" resultType="user">
		select * from user where id = #{id}
	select>

    
    <select id="queryUserByUsername" parameterType="string"
            resultType="user">
		select * from user where username like '%${value}%'
	select>

    
    <insert id="saveUser" parameterType="user">
        <selectKey keyProperty="id" keyColumn="id" order="AFTER"
                   resultType="int">
            select last_insert_id()
        selectKey>
        insert into user
        (username,birthday,sex,address)
        values
        (#{username},#{birthday},#{sex},#{address})
    insert>

mapper>

** UserMapper接口**

package com.mapper;

import com.pojo.User;

import java.util.List;

public interface UserMapper {
    /**
     * 根据id查询用户
     *
     * @param id
     * @return
     */
    User queryUserById(int id);

    /**
     * 根据用户名模糊查询用户列表
     *
     * @param username
     * @return
     */
    List<User> queryUserByUsername(String username);

    /**
     * 保存
     *
     * @param user
     */
    void saveUser(User user);
}

** 配置mapper代理**

配置mapper有两种方式:

方式一:

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
	
	<property name="mapperInterface" value="com.mapper.UserMapper" />
	
	<property name="sqlSessionFactory" ref="sqlSessionFactory" />
bean>

方式二:


<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	
	<property name="basePackage" value="com.mapper" />
bean>

每个mapper代理对象的id就是类名,首字母小写。

注意:如果配置了mapper代理或包扫描方式后,在mybatis-config文件中就不必要加映入映射文件了。

**测试 **

package com.test;

import com.mapper.UserMapper;
import com.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;


@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserMapperTest {

   @Resource(name ="userMapper")
   private UserMapper userMapper;
    @Test
    public void testFindUserByid(){
        User user = userMapper.queryUserById(1);
        System.out.println(user.toString());
    }
}

​ Spring在整合MyBatis时,需要一些jar包以及API,接下来介绍常用的jar包以及API

#####总结

1 整合spring与mybatis需要mybatis-spring.jar包

2 SqlSessionFactoryBean类

​ 使用MyBatis的核心是SqlSessionFactory,使用Spring不能直接创建,所以Mybatis-Spring给我们封装了一个SqlSessionFactoryBean,在这个bean里面还是通过SqlSessionFactoryBuilder来建立对应的SqlSessionFactory,进而获取到对应的SqlSession。通过SqlSessionFactoryBean我们可以通过对其指定一些属性来提供Mybatis的一些配置信息。


<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
  		<property name="configLocation" value="classpath:mybatis-config.xml"/>
 		<property name="dataSource" ref="dataSource" />  
        <property name="mapperLocations"  
               value="classpath:com/qf/mybatis/mappers/*Mapper.xml" />  
        <property name="typeAliasesPackage" value="com.qf.model" />  
 bean> 

​ 在定义SqlSessionFactoryBean的时候,dataSource属性是必须指定的,它表示用于连接数据库的数据源。当然,我们也可以指定一些其他的属性,下面简单列举几个:

  • mapperLocations:它表示我们的Mapper文件存放的位置,当我们的Mapper文件跟对应的Mapper接口处于同一位置的时候可以不用指定该属性的值。
  • configLocation:用于指定Mybatis的配置文件位置。如果指定了该属性,那么会以该配置文件的内容作为配置信息构建对应的SqlSessionFactoryBuilder,但是后续属性指定的内容会覆盖该配置文件里面指定的对应内容。
  • typeAliasesPackage:它一般对应我们的实体类所在的包,这个时候会自动取对应包中不包括包名的简单类名作为包括包名的别名。多个package之间可以用逗号或者分号等来进行分隔。
  • typeAliases:数组类型,用来指定别名的。指定了这个属性后,Mybatis会把这个类型的短名称作为这个类型的别名,前提是该类上没有标注@Alias注解,否则将使用该注解对应的值作为此种类型的别名。
<property name="typeAliases">  
     <array>  
         <value>com.mybatis.model.Blogvalue>  
         <value>com.mybatis.model.Commentvalue>  
     array>  
 property>
  • plugins:数组类型,用来指定Mybatis的Interceptor。

  • typeHandlersPackage:用来指定TypeHandler所在的包,如果指定了该属性,SqlSessionFactoryBean会自动把该包下面的类注册为对应的TypeHandler。多个package之间可以用逗号或者分号等来进行分隔。

  • typeHandlers:数组类型,表示TypeHandler。

    3、MapperFactoryBean

    通过MapperFactoryBean可以获取到我们想要的Mapper对象。MapperFactoryBean实现了Spring的FactoryBean接口,所以MapperFactoryBean是通过FactoryBean接口中定义的getObject方法来获取对应的Mapper对象的。在定义一个MapperFactoryBean的时候有两个属性需要我们注入,一个是Mybatis-Spring用来生成实现了SqlSession接口的sqlSessionFactory;另一个就是我们所要返回的对应的Mapper接口。

 <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <!-- 配置Mapper接口 -->
        <property name="mapperInterface" value="com.qf.mapper.UserMapper" />
        <!-- 配置sqlSessionFactory -->
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
 </bean>

4、MapperScannerConfigurer

​ 利用上面的方法进行整合的时候,我们有一个Mapper就需要定义一个对应的MapperFactoryBean,当我们的Mapper比较少的时候,这样做也还可以,但是当我们的Mapper相当多时我们再这样定义一个个Mapper对应的MapperFactoryBean就显得速度比较慢了。为此Mybatis-Spring为我们提供了一个叫做MapperScannerConfigurer的类,通过这个类Mybatis-Spring会自动为我们注册Mapper对应的MapperFactoryBean对象。

​ 如果我们需要使用MapperScannerConfigurer来帮我们自动扫描和注册Mapper接口的话我们需要在Spring的applicationContext配置文件中定义一个MapperScannerConfigurer对应的bean。对于MapperScannerConfigurer而言有一个属性是我们必须指定的,那就是basePackage。basePackage是用来指定Mapper接口文件所在的基包的,在这个基包或其所有子包下面的Mapper接口都将被搜索到。多个基包之间可以使用逗号或者分号进行分隔。最简单的MapperScannerConfigurer定义就是只指定一个basePackage属性,如:

Xml代码

 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
    <property name="basePackage" value="com.tiantian.mybatis.mapper" />  
 bean> 

你可能感兴趣的:(Spring整合MyBatis)