SpringBoot14 SpringBoot整合mybatis、依賴注入找不到Bean的問題


 

1 版本說明

  springboot:2.0

  jdk:1.8

  

 

2 創建springBoot項目

  創建項目時勾選必要web,MySQL,mybatis相關依賴

  創建完成后再pom文件中添加自動部署、lombok相關依賴

  2.1 編寫測試類

    技巧01:項目創建成功后先將mybatis和mysql相關的jar注釋掉,在到控制層中創建一個簡單的測試類來確認項目是否創建成功

package cn.test.demo.mybatis_demo02.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author 王楊帥
 * @create 2018-04-08 7:53
 * @desc 控制層測試類
 **/
@RestController
@RequestMapping(value = "/test")
public class TestController {

    @GetMapping(value = "/test01")
    public String test01() {
        return "HELLO BOY";
    }
}

  2.2 配置文件信息

server.port=9999
server.servlet.path=/dev

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/testdemo?useUnicode=true&characterEncoding=UTF-8&&useSSL=false
jdbc.username=root
jdbc.password=root

mabatis_config_file=mybatis-config.xml
mapper_path=/mapper/**.xml
entity_package=cn.test.demo.mybatis_demo02.entity

 

3 創建數據庫

  根據springboot的配置信息,創建一個數據庫;並在數據庫中創建一個表

  技巧01:必須在springboot配置文件中配置的那個數據庫中進行數據表的創建

/*
Navicat MySQL Data Transfer

Source Server         : mysql5.4
Source Server Version : 50540
Source Host           : localhost:3306
Source Database       : testdemo

Target Server Type    : MYSQL
Target Server Version : 50540
File Encoding         : 65001

Date: 2018-04-08 13:33:08
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `tb_area`
-- ----------------------------
DROP TABLE IF EXISTS `tb_area`;
CREATE TABLE `tb_area` (
  `area_id` int(2) NOT NULL AUTO_INCREMENT,
  `area_name` varchar(200) NOT NULL,
  `priority` int(2) NOT NULL DEFAULT '0',
  `create_time` datetime NOT NULL,
  `last_edit_time` datetime NOT NULL,
  PRIMARY KEY (`area_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of tb_area
-- ----------------------------
INSERT INTO `tb_area` VALUES ('1', '東苑', '0', '2018-03-07 08:50:37', '2018-04-08 13:28:58');
INSERT INTO `tb_area` VALUES ('2', '南苑', '1', '2018-04-08 09:44:48', '2018-04-08 09:44:48');

 

4 創建實體類

  技巧01:可以利用mybatis提供的生成器來自動生成entity、dao、xml、service、controller對應的代碼,具體步驟請參見上一篇博文

  技巧02:在編寫代碼時可以開啟代碼提示

    

package cn.test.demo.mybatis_demo02.entity;

import java.util.Date;

/**
 * @author 王楊帥
 * @create 2018-04-08 8:40
 * @desc
 **/
public class Area {
    //    @TableId(value="area_id", type= IdType.AUTO)
    private Integer areaId;
    //    @TableField("area_name")
    private String areaName;
    private Integer priority;
    //    @TableField("create_time")
    private Date createTime;
    //    @TableField("last_edit_time")
    private Date lastEditTime;

    public Integer getAreaId() {
        return areaId;
    }

    public void setAreaId(Integer areaId) {
        this.areaId = areaId;
    }

    public String getAreaName() {
        return areaName;
    }

    public void setAreaName(String areaName) {
        this.areaName = areaName;
    }

    public Integer getPriority() {
        return priority;
    }

    public void setPriority(Integer priority) {
        this.priority = priority;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getLastEditTime() {
        return lastEditTime;
    }

    public void setLastEditTime(Date lastEditTime) {
        this.lastEditTime = lastEditTime;
    }

    @Override
    public String toString() {
        return "Area{" +
                "areaId=" + areaId +
                ", areaName='" + areaName + '\'' +
                ", priority=" + priority +
                ", createTime=" + createTime +
                ", lastEditTime=" + lastEditTime +
                '}';
    }
}
View Code

  

5 配置部分

  5.1 POM配置

    保證pom.xml文件中有mybatis、mysql、mysql驅動這三個對應的依賴

        <!--mysql數據庫-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--數據庫連接池-->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.2</version>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>

  5.2 mybatis相關配置

    在ersources文件夾中創建一個mybatis-config.xml文件用來mybatis相關的配置

    技巧01:在項目啟動的時候會自動加載resources中的文件進行全局的配置,所有mybatis的配置文件也會被加載

    5.2.1 <setting name="useGeneratedKeys" value="true"/>

      開啟JDBC的getGeneratedKeys獲取數據庫自增主鍵,即:當我們新增一條數據時會自動設置主鍵值

    5.2.2 <setting name="useColumnLabel" value="ture" />

      使用列標簽替換列別名

    5.2.3 <setting name="mapUnderscoreToCamelCase" value="true" />

      開啟駝峰轉換,即:數據庫中的字段名全部是小寫和下划線組成,實體類中的屬性全部使用駝峰原則時他們之間就會是一一對應的關系

<?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>
    <settings>
        <!--使用JDBC的getGeneratedKeys獲取數據庫自增主鍵-->
        <setting name="useGeneratedKeys" value="true"/>
        <!--使用列標簽替換列別名-->
        <setting name="useColumnLabel" value="ture" />
        <!--開啟駝峰轉換-->
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>
</configuration>

  5.3 DataSource配置和SqlSessionFactory配置

    由於我們使用c3p0作為數據庫連接池,所以我們在配置DataSource直接對成c3p0的連接信息進行配置即可

    5.3.1 創建一個DataSourceConfiguration類來配置DataSource

      注意:類名可以隨便取

      技巧01:在啟動類同一級別或啟動類下面級別的地方創建一個config包來存放java配置類

        

      技巧02:java配置類需要在類上添加@Configuration注解來指明該類是一個配置類

      技巧03:DataSourceConfiguration配置類說明

        》生成一個DataSource實例並注入到Bean容器中

          技巧01:向數據庫連接信息,我們可以把它放到springboot的全局配置文件中去,然后在需要用到的地方通過@Value注解來獲取獲取,這樣就可以做到一改全改的作用  

   

          技巧02:DataSource配置類上還需要利用@MapperScan注解來配置mapper映射器的掃描路徑,例如:

@MapperScan("cn.test.demo.mybatis_demo02.dao") // mapper映射器的掃描路徑

          

package cn.test.demo.mybatis_demo02.config.dao;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.CommonDataSource;
import java.beans.PropertyVetoException;

/**
 * @author 王楊帥
 * @create 2018-04-08 8:09
 * @desc DataSource配置
 **/
@Configuration
@MapperScan("cn.test.demo.mybatis_demo02.dao") // mapper映射器的掃描路徑
public class DataSourceConfiguration {

    @Value("${jdbc.driver}")
    private String jdbcDriver;
    @Value("${jdbc.password}")
    private String jdbcPassword;
    @Value("${jdbc.username}")
    private String jdbcUsername;
    @Value("${jdbc.url}")
    private String jdbcUrl;

    @Bean(name = "dataSource")
    public ComboPooledDataSource createDataSource() throws PropertyVetoException {
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        dataSource.setDriverClass(jdbcDriver);
        dataSource.setJdbcUrl(jdbcUrl);
        dataSource.setUser(jdbcUsername);
        dataSource.setPassword(jdbcPassword);
        dataSource.setAutoCommitOnClose(false); // 關閉連接后不會自動進行事務提交
        return dataSource;
    }
}
View Code

    5.3.2 創建一個crateSqlSessionFactoryBean類來配置SqlSessionFactory

      注意:類名可以隨便取

      技巧01:java配置類需要在類上添加@Configuration注解來指明該類是一個配置類

      技巧02:在配置SqlSessionFactoryBean時需要用到DataSrouce實例,所以需要在配置SqlSessionFactoryBean的配置類依賴注入DataSrouce實例,例如:

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

      技巧03:配置說明

        》SqlSessionFactoryBean並注入到Bean容器中

          

package cn.test.demo.mybatis_demo02.config.dao;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;
import java.io.IOException;

/**
 * @author 王楊帥
 * @create 2018-04-08 8:22
 * @desc SessionFactory配置類
 **/
@Configuration
//@MapperScan
public class SessionFactoryConfiguration {
    @Value("${mabatis_config_file}")
    private String mybatisConfigFilePath;
    @Value("${mapper_path}")
    private String mapperPath;
    @Value("${entity_package}")
    private String entityPackage;

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactoryBean crateSqlSessionFactoryBean() throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); // 創建SqlSessionFactoryBean實例
        sqlSessionFactoryBean.setConfigLocation(new ClassPathResource(mybatisConfigFilePath)); //  掃描mybatis配置文件

//        設置mapper映射器對應的XML文件的掃描路徑
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        String packageSearchPath = PathMatchingResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + mapperPath;
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(packageSearchPath));

//        設置數據庫連接信息
        sqlSessionFactoryBean.setDataSource(dataSource);

//        設置實體類掃描路徑
        sqlSessionFactoryBean.setTypeAliasesPackage(entityPackage);
        return sqlSessionFactoryBean;
    }

}
View Code

        》將掃描路徑配置到springboot的全局配置配置文件中,然后利用@Value去獲取即可,這樣既可以實現一改全改的效果;例如:

        

      

        》@Autowired進行依賴注入的時候可以利用@Qualifier指定名字,例如:   

    @Autowired
    @Qualifier("dataSource")
    private DataSource dataSource;

 

6 創建Dao層代碼

  Dao層在使用mybatis實現時也叫作Mapper映射器,其實Mapper映射器就是一個接口而已

package cn.test.demo.mybatis_demo02.dao;

import cn.test.demo.mybatis_demo02.entity.Area;
import com.sun.applet2.preloader.event.InitEvent;

import java.util.List;

/**
 * @author 王楊帥
 * @create 2018-04-08 8:42
 * @desc
 **/
public interface AreaDao {
    List<Area> queryArea();
    Area queryById(Integer areaId);
    Integer insertArea(Area area);
    Integer updateArea(Area area);
    Integer deleteArea(Integer areaId);
}

 

7 創建XML文件代碼

  一個XML文件和一個Mapper映射器對應,具體這么對應請參見mybatis先關博文

<?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="cn.test.demo.mybatis_demo02.dao.AreaDao">



    <!-- 通用查詢映射結果 -->
    <!--<resultMap id="BaseResultMap" type="org.ibase4j.entity.TbArea">-->
        <!--<id column="area_id" property="areaId" />-->
        <!--<result column="area_name" property="areaName" />-->
        <!--<result column="priority" property="priority" />-->
        <!--<result column="create_time" property="createTime" />-->
        <!--<result column="last_edit_time" property="lastEditTime" />-->
    <!--</resultMap>-->


    <select id="queryArea" resultType="cn.test.demo.mybatis_demo02.entity.Area">
        SELECT
          *
        FROM
          tb_area
        ORDER BY
          priority
        DESC
    </select>

    <select id="queryById" resultType="cn.test.demo.mybatis_demo02.entity.Area">
        SELECT
          *
        FROM
          tb_area
        WHERE
          area_id = #{areaId}
    </select>
    
    <insert id="insertArea"
            useGeneratedKeys="true" keyProperty="areaId" keyColumn="area_id"
            parameterType="cn.test.demo.mybatis_demo02.entity.Area">
      INSERT INTO
        tb_area(area_name, priority, create_time, last_edit_time)
      VALUES
        (#{areaName}, #{priority}, #{createTime}, #{lastEditTime})
    </insert>
    
    <update id="updateArea" parameterType="cn.test.demo.mybatis_demo02.entity.Area">
      UPDATE tb_area
      <set>
          <if test="areaName!=null">area_name=#{areaName},</if>
          <if test="priority!=null">priority=#{priority},</if>
          <if test="lastEditTime!=null">last_edit_time=#{lastEditTime}</if>
      </set>
      WHERE
        area_id = #{areaId}
    </update>

    <delete id="deleteArea">
      DELETE FROM
        tb_area
      WHERE
        area_id = #{areaId}
    </delete>

</mapper>
View Code

 

8 創建Dao層測試類

  坑01:在測試類中進行依賴注入時可能會報錯,報錯信息為:找不到相關的Bean

  原因:IDEA是一個比較智能的編輯器,所以在進行依賴注入的時候就會檢查需要注入的Bean在容器中是否存在,如果不存在就會報出這樣的錯誤;但是由於IDEA的該功能還不夠完善所以即使Bean容器有對應的Bean也會報出找不到相關Bean的錯誤

  解決辦法:將IDEA這個功能的報錯級別調低,調成warning即可,例如:

    

package cn.test.demo.mybatis_demo02.dao;

import cn.test.demo.mybatis_demo02.entity.Area;
import lombok.extern.slf4j.Slf4j;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;


import java.util.Date;
import java.util.List;

import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class AreaDaoTest {

    @Autowired
    private AreaDao areaDao;

    @Test
    public void queryArea() throws Exception {
        List<Area> areaList = areaDao.queryArea();
//        assertEquals(1, areaList.size());
        log.info("獲取到的數據為:{}", areaList);
    }

    @Test
    public void queryById() throws Exception {
        Area area = areaDao.queryById(1);
        log.info("獲取到的數據為:{}",area.toString());
    }

    @Test
//    @Ignore
    public void insertArea() throws Exception {
        Area area = new Area();
        area.setAreaName("南苑");
        area.setPriority(1);
        area.setCreateTime(new Date());
        area.setLastEditTime(new Date());
        Integer result = areaDao.insertArea(area);
        log.info("插入完成的數據為:{}", result);
    }

    @Test
    public void updateArea() throws Exception {
        Area area = new Area();
        area.setAreaName("東苑");
        area.setLastEditTime(new Date());
        area.setAreaId(1);
        Integer result = areaDao.updateArea(area);
        log.info("更新完成后得到的結果為:{}", result);
    }

    @Test
    public void deleteArea() throws Exception {
    }

}
View Code

 

9 SpringBoot集成mybatis腳手架

  點擊前往

  

·下面是我的公眾號二維碼,歡迎關注·

尋渝記

微信號:xyj_fury

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM