1. 程式人生 > >Spring Boot 開發系列一 開發踩坑

Spring Boot 開發系列一 開發踩坑

strong contex configure post crud操作 如何 result png exce

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

一 .集成MyBatis

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

package com.example.demo.config;

import 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;

    //當容器裏沒有指定的Bean的情況下創建該對象
    @Bean(name = "SqlSessionFactoryBean")
    @ConditionalOnMissingBean
    public SqlSessionFactoryBean sqlSessionFactoryBean() {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        // 設置數據源
        sqlSessionFactoryBean.setDataSource(dataSource);
        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文件





Spring Boot 開發系列一 開發踩坑