Spring Boot 開發系列一 開發踩坑


這是學習spring boot 的第二周,公司號稱這玩意是啥都不會的新手就可以填空開發,於是決定上手一把,怎么說我也是搞了快七八年的.NET和.NETcore,沒想到無情打臉,快被這個能填空開的IDE搞瘋了,下面是記下一些自己踩坑開發中遇到的一系列無窮無盡的問題。

一 .集成MyBatis

a)首先如何理解這個  MyBatis 的東西,我的理解是 :MyBatis 有點類似ORM的感覺,跟 JPA很類似,就是一個orm,需要一個類似 dbcontext的東西,這個東西,在MyBatis 里面叫做 sqlSessionFactoryBean,好了知道這個,我們就不需要像百度上面一樣,搞各種各樣的配置,不知道所雲的東西全都搞在工程里面。我的是這樣配置的package com.example.demo.configimport org.apache.ibatis.session.SqlSessionFactory;

import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.mybatis.spring.boot.autoconfigure.*; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.TransactionManagementConfigurer; import javax.sql.DataSource; @Configuration @EnableTransactionManagement public class MyBatisConfig { @Autowired private DataSource dataSource;
  @Value("${mybatis.mapper-locations}")
  private String MAPPER_LOCATION;
  //當容器里沒有指定的Bean的情況下創建該對象 @Bean(name = "SqlSessionFactoryBean") @ConditionalOnMissingBean 
  public SqlSessionFactoryBean sqlSessionFactoryBean() { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); // 設置數據源
sqlSessionFactoryBean.setDataSource(dataSource);
//設置 mapper.xml的路徑 (非常重要,這里踩坑兩天)
 sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(MAPPER_LOCATION));
return sqlSessionFactoryBean; } 

  

,去執行他內置的一些鬼CURD操作,對,他只需要這一個方法就可以了,設置數據源,然后你的 MyBatis  就可以認為有了 我們常說的 dbcontext了。

 

有了這個數據庫上下文的  sqlSessionFactoryBean,我們需要一些  CRUD的方法,方法在哪里呢,在那什么  mapper.xml文件里面的。

 

b). 配置  這些方法的路徑,什么,路徑,對是路徑,我沒有寫過 之前的spring mvc的,但是了解到這些 Mapper.xml 其它就是對應的一個個之前配置的Bean節點下的 方法,只是換了個馬甲而已吧。

package com.example.demo.config;

import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@AutoConfigureAfter(MapperScannerConfig.class) //保證在MyBatisConfig實例化之后再實例化該類
public class MapperScannerConfig {
    // mapper接口的掃描器
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.example.demo");
        return mapperScannerConfigurer;
    }
}

  mapperScannerConfigurer.setBasePackage("com.example.demo");  注意這句,是說我配置了我的數據庫上下文之后,我要掃我這個上下文里面 有哪些方法,我要從哪個基包開始掃描找到這些方法,傳說是遞歸去找的。這里你查看你的mapper接口的包名是什么,可以直接設置成上一層去,就可以掃描到的。

@AutoConfigureAfter(MapperScannerConfig.class) //保證在MyBatisConfig實例化之后再實例化該類

c)設置mapper.xml的路徑  也就是你的  mapper接口寫好了,得有一個對應的 mapper.xml對應,這樣才知道 你這個接口具體是執行了什么操作,對,就是這樣,殺人放火的動作,都是寫在XML文件里面的,當然,寫這個XML文件,個人覺得,沒有什么比用這各方法寫CRUD操作更坑爹的了,沒有。配置  application.yaml  里面:

# mybatis_config
mybatis:
mapper-locations: classpath:mapperXml/**/*.xml
具體路徑以自己項目做適當調整。

注意:坑來了,這個XML的坑很嚴重,有時候會折騰到你想死的心都有了,但是還是死不甘心。
<?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.example.demo.permission.mapper.UserMapper">
    <resultMap id="BaseResultMap" type="com.example.demo.permission.model.User">
        <id column="id" property="id" jdbcType="INTEGER"/>
        <result column="nickname" property="nickname" jdbcType="VARCHAR"/>
        <result column="email" property="email" jdbcType="VARCHAR"/>
        <result column="pswd" property="pswd" jdbcType="VARCHAR"/>
        <result column="create_time" property="createTime" jdbcType="TIMESTAMP"/>
        <result column="last_login_time" property="lastLoginTime" jdbcType="TIMESTAMP"/>
        <result column="status" property="status" jdbcType="TINYINT"/>
    </resultMap>
    <sql id="Base_Column_List">
    id, nickname, email, pswd, create_time, last_login_time, status
  </sql>
    <select id="selectByPrimaryKey" resultMap="BaseResultMap" resultType="com.example.demo.permission.model.User" parameterType="java.lang.Integer">
        select
        <include refid="Base_Column_List"/>
        from sys_user
        where id = #{id,jdbcType=INTEGER}
    </select>
</mapper>
(1).mapper.xml 文件的namespace要與 mapper接口的包名相同
(2).UserMapper 的方法在UserMapper.xml中沒有,然后執行 userService 的方法會報錯
(3).UserMapper 的方法返回值是List<User>,而select元素沒有正確配置ResultMap,或者只配置ResultType! 這個第三個非常隱敝,我在這里折騰了三天,就是少了一個ResultType

二  整合Druid
這玩意 取了一個 德魯伊 的名字,估計是阿里哪位大神喜歡玩游戲吧,哈哈。好了,這個東西主要是就是一個db連接池的作用。
所以我們只需要把一系列連接數據庫的參數配置上去就Ok了
1) DruidConfig
package com.example.demo.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.*;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import com.alibaba.druid.*;

import javax.sql.DataSource;
import java.sql.SQLException;

@Configuration()
public class DruidConfig {
    private Logger logger = LoggerFactory.getLogger(getClass());

    @Value("${spring.datasource.url}")
    private String dbUrl;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;

    @Value("${spring.datasource.filters}")
    private String filters;


    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new WebStatFilter());
        filterRegistrationBean.addUrlPatterns("/*");
        filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        filterRegistrationBean.addInitParameter("profileEnable", "true");
        filterRegistrationBean.addInitParameter("principalCookieName", "USER_COOKIE");
        filterRegistrationBean.addInitParameter("principalSessionName", "USER_SESSION");
        return filterRegistrationBean;
    }

    @Bean
    @Primary
    public DataSource druidDataSource() {
        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(this.dbUrl);
        datasource.setUsername(username);
        datasource.setPassword(password);
        datasource.setDriverClassName(driverClassName);
        try {
            datasource.setFilters(filters);
        } catch (SQLException e) {
            logger.error("druid configuration initialization filter", e);
        }
        return datasource;
    }

    @Bean
    public ServletRegistrationBean druidServlet() {
        ServletRegistrationBean reg = new ServletRegistrationBean();
        reg.setServlet(new StatViewServlet());
        reg.addUrlMappings("/druid/*");
        reg.addInitParameter("loginUsername", "druid");
        reg.addInitParameter("loginPassword", "druid");
        return reg;
    }


}
其實只需要配置一個 : druidDataSource 這個就可以了。
FilterRegistrationBean  與 ServletRegistrationBean 主要是為了試一試  Druid的監控介面而已,不要的話,完全沒有問題的。

2)配置文件
#datasource
spring:
datasource:
name: testdb
url: jdbc:mysql://localhost:3306/spring_boot?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
#initalSize: 5
filters: stat
applictaion.yaml文件里面把這些提供一下,OK,鳥德配置成功。

三 配置文件的讀到,各種坑,慢慢踩
暫且說有兩種配置文件吧,
第一種,application.yaml 這個,注意,springboot中 @Configraperporties 標記的 配置節點,讀到的都是application.yaml或得application.properties 里面的值的。
第二種,自定義的配置文件,注意,雖然 springboot 號稱能讀取.YAML文件,但是,只限 application.yaml 這一個,自定義的文件,只能用 .properties的文件做后綴才能讀的到。
      @PropertySource(value = {"classpath:config/globalconfig.properties"}) 是不能讀取 .yaml文件






免責聲明!

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



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