Spring整合MyBatis

 

環境搭建

一、新建Spring項目,添加所需的jar包

  • spring-core.jar
  • spring-beans.jar
  • spring-context.jar
  • spring-expression.jar
  • spring-aop.jar   (使用spring的註解)
  • spring-jdbc.jar  (spring-tx.jar依賴spring-jdbc,若是要使用spring的事務管理,需添加此包。就算不使用spring的事務管理,mybatis-spring.jar依賴此包,也必須添加此包)
  • spring-tx.jar  (事務通常是用spring的事務管理,若是要使用spring的事務管理,須要添加此包)

 

  (若是要整合AspectJ)mysql

  • spring-aspects.jar
  • aopalliance.jar
  • aspectjweaver.jar

 

  • mybatis.jar

 

  • log4j.jar
  • commons-logging.jar

 

  • mybatis-spring.jar   (這個是spring整合mybatis須要的包,須要自行下載添加,官方提倡使用maven,在github上也只提供源碼,jar只能到maven倉庫去下載)

 

  • 數據庫驅動

 

  • dbcp的jar包 (也可使用其它鏈接池)

 

 

 

二、src下新建db.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/my_db?serverTimezone=GMT
jdbc.username=chy
jdbc.password=abcd
jdbc.initialSize=5
jdbc.maxTotal=30
jdbc.maxIdle=10

 

 

 

三、src下新建log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout,D


# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE 


# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender 
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 
# log4j.appender.stdout.Threshold = ERROR
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n


# File output...
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
#若是是web項目,會輸出到tomcat的logs文件夾下的指定文件中
log4j.appender.D.File = ../logs/error.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = ERROR
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
log4j.appender.D.encoding=UTF-8

spring默認會讀取資源根目錄下名爲log4j.properties的文件來做爲log4j的配置,因此無需在配置中指定log4j的配置文件名。git

 

 

 

四、src下新建mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <!--配置別名-->
    <typeAliases>
        <package name="com.chy.model"/>
    </typeAliases>

    <!--指定映射文件的位置-->
    <mappers>
        <package name="com.chy.mapper"/>
    </mappers>

</configuration>

不少配置,好比數據源、SqlSessionFactory的配置,都放到Spring的配置文件中去了,由於要做爲bean由spring容器管理。mybatis自己的配置就減小了不少。github

 

 

 

(5)src下新建spring-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<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"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <!--引入數據庫鏈接信息db.properties-->
    <context:property-placeholder location="db.properties" />

    <!--配置dbcp數據源-->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="initialSize" value="${jdbc.initialSize}" />
        <property name="maxTotal" value="${jdbc.maxTotal}" />
        <property name="maxIdle" value="${jdbc.maxIdle}" />
    </bean>

    <!--配置MyBatis的SqlSessionFactory-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--注入數據源-->
        <property name="dataSource" ref="dataSource" />
        <!--指定mybatis配置文件的位置-->
        <property name="configLocation" value="mybatis-config.xml" />
    </bean>

    <!--配置事務管理器-->
    <!--<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">-->
    <!--    &lt;!&ndash;注入數據源&ndash;&gt;-->
    <!--    <property name="dataSource" ref="dataSource" />-->
    <!--</bean>-->

    <!--開啓事務註解,指定要使用的事務管理器-->
    <!--<tx:annotation-driven transaction-manager="transactionManager" />-->

</beans>

要使用事務的話,將註釋去掉。web

 

 

 

(6)新建包com.chy.model,編寫實體類

@Component("user")
public class User {
    private int id;
    private String username;
    private String password;
    private double money;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}

 

 

 

(7)新建包com.chy.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.chy.mapper.UserMapper">
    <select id="queryMoneyById" parameterType="integer" resultType="double">
        select money from user_tb where id=#{id}
    </select>
    <update id="updateMoney" parameterType="map">
        <!--傳入map,直接經過key來引用-->
        update user_tb set money=#{money} where id=#{id}
    </update>
</mapper>

 

至此,環境搭建完畢。spring

 

 


 

 

Spring整合MyBatis有2種整合方式:sql

  • 傳統dao方式的整合
  • Mapper接口方式的整合。可細分爲2種:基於MapperFactoryBean的整合、基於MapperScannerConfigurer的整合。

 

 


 

 

傳統dao方式的整合

(1)新建包com.chy.dao,編寫dao層接口、實現類:數據庫

public interface UserDao {
    public Double queryMoneyById(int id);
    public void updateMoney(@Param("id") int id, @Param("money") double money);
}

 

//需繼承SqlSessionDaoSupport類,主要是爲了繼承getSqlSession()方法,獲取SqlSession的實例
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao{
    @Override
    public Double queryMoneyById(int id) {
        //傳入映射文件中sql語句的id、實參,this可缺省
        return this.getSqlSession().selectOne("com.chy.mapper.UserMapper.queryMoneyById", id);
    }

    @Override
    public void updateMoney(int id, double money) {
        Map<String, Object> map = new HashMap<>(2);
        map.put("id", id);
        map.put("money", money);
        getSqlSession().update("com.chy.mapper.UserMapper.updateMoney",map);
    }
}

 

 

(2)在spring配置文件中配置實現類express

    <!--配置dao層的bean-->
    <bean id="userDao" class="com.chy.dao.UserDaoImpl">
        <!--注入以前配置的SqlSessionFactory實例-->
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

在業務層使用這個bean(dao)來處理業務。apache

 

每一個dao層的實現類都要搞這三處,十分麻煩,不推薦。tomcat

 

 


 

 

基於MapperFactoryBean的整合

(1)在com.chy.mapper包下,編寫映射文件對應的mapper接口

public interface UserMapper {
    public double queryMoneyById(int id);
    public void updateMoney(@Param("id") int id, @Param("money") double money);
}

 

 

(2)在spring配置文件中配置mapper

    <!--配置mapper-->
    <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <!--指定Mapper接口-->
        <property name="mapperInterface" value="com.chy.mapper.UserMapper" />
        <!--注入以前配置的SqlSessionFactory-->
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

把mapper做爲dao層,直接在業務層獲取這個bean的實例(Mapper接口類型)來操做數據庫,可以使用mapper接口的方法來操做數據庫。

 

比起傳統dao方式的整合,能夠少寫一處,但每一個mapper都要配置<bean>,仍是有點麻煩。

 

 


 

 

基於MapperScannerConfigurer的整合(推薦)

(1)在com.chy.mapper包下,編寫映射文件對應的Mapper接口

 

(2)在Spring的配置文件中配置mapper代理

    <!--配置mapper代理-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--會自動掃描指定包下的Mapper接口,爲其建立映射器。多個包用逗號或分號分隔-->
        <property name="basePackage" value="com.chy.mapper" />
    </bean>

指定了mapper代理後,無需在mybatis配置文件中指定映射文件的路徑。

 

只需配置一個<bean>,無需配置每一個mapper,省事兒,推薦。

 

 


 

 

使用Spring的事務管理

(1)新建包com.chy.service,事務要加在業務層

public interface UserService {
    public void transfer(int to, int from, double amount);
}

 

@Service("userService")
public class UserServiceImpl implements UserService{

    private UserMapper userMapper;

    //自動裝配mapper
    @Autowired
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @Override
    @Transactional public void transfer(int from, int to, double amount) {
        double fromMoney = userMapper.queryMoneyById(from);
        if (fromMoney-amount>=0){
            double toMoney = userMapper.queryMoneyById(to);
            userMapper.updateMoney(from,fromMoney-amount);
            userMapper.updateMoney(to,toMoney+amount);
        }
    }
}

 

 

(2)在spring配置文件中配置事務(取消註釋)

    <!--配置事務管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入數據源-->
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--開啓事務註解,指定要使用的事務管理器-->
    <tx:annotation-driven transaction-manager="transactionManager" />

注意:IDEA自動導入的事務的約束每每不對,須要修改。

 

 


 

 

說明

隨着包、註解愈來愈多,要在spring配置文件中使用包掃描,並注意把新建的包加進去,

不然可能會出現「NoSuchBeanDefinitionException: No bean named 'xxx' available」的錯誤。

 

基於Mapper接口方式的整合,以mapper包做爲dao層,因此命名有一些變化:

mapper的包命名爲dao,XxxMapper命名爲XxxDao。

 

接口、實現類愈來愈多,能夠把新建一個子包impl,來單獨放實現類。

好比service層,把接口直接放在service下面,在service下新建一個子包impl,來放實現類。

相關文章
相關標籤/搜索