zoukankan      html  css  js  c++  java
  • 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文件





  • 相关阅读:
    VS.NET提示"试图运行项目时出错:无法启动调试。绑定句柄无效"解决办法
    鼠标移动之hook学习
    今天完成任务之SQL中len的使用
    继承(2)方法《.NET 2.0面向对象编程揭秘 》
    框架设计:CLR Via C# 第二章
    启动IIS时提示“服务没有及时响应启动或控制请求”几种解决方法
    C#中处理字符串和数字
    TreeView实现权限管理
    鼠标单击右击双击简单功能的实现
    richTextBox 中插入图片
  • 原文地址:https://www.cnblogs.com/freewsf/p/8076463.html
Copyright © 2011-2022 走看看