美文网首页springbootSpringBoot + Vue后台维护系统
SpringBoot + Vue 后台管理系统(五):mybat

SpringBoot + Vue 后台管理系统(五):mybat

作者: Bertram_Wang | 来源:发表于2019-05-30 01:42 被阅读100次

    什么是MyBatis-Plus?

    翻译过来就是“加强的mybatis”;封装了各种方法,形成了类似于JPA的使用方式。有兴趣的朋友参考文档:MyBatis-Plus

    SpringBoot集合方式

    1.添加以下依赖(注:包含MyBatis的依赖)

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.1.0</version>
        </dependency> 
    
    本文使用的是druid + mysql 的多数据源;所以在pom文件导入依赖
        <!-- 数据库关联 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    
    自动配置
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    
    配置文件
    spring: 
      profiles:
        active: dev
      datasource: 
        url: jdbc:mysql://lcoalhost:3306/db_comm_01?useUnicode=true&characterEncoding=utf-8&useSSL=false
        username: root
        password: 12345678
        type: com.alibaba.druid.pool.DruidDataSource
      member: 
        datasource: 
          url: jdbc:mysql://lcoalhost:3306/db_member_01?useUnicode=true&characterEncoding=utf-8&useSSL=false
          username: root
          password: 12345678
          type: com.alibaba.druid.pool.DruidDataSource 
      oauth: 
        datasource: 
          url: jdbc:mysql://lcoalhost:3306/oauth2?useUnicode=true&characterEncoding=utf-8&useSSL=false
          username: root
          password: 12345678
          type: com.alibaba.druid.pool.DruidDataSource 
      redis:
        database: 0
        host: lcoalhost
        port: 6379
        password: 12345678
    

    2.配置

    数据源DataSourceConfig.java
    @Configuration
    public class DataSourceConfig {
        @Bean
        @ConfigurationProperties(prefix = "spring.datasource")
        DataSource dsComm() {
            return DruidDataSourceBuilder.create().build();
        }
        @Bean
        @ConfigurationProperties(prefix = "spring.member.datasource")
        DataSource dsMember() {
            return DruidDataSourceBuilder.create().build();
        }
        @Bean
        @ConfigurationProperties(prefix = "spring.oauth.datasource")
        DataSource dsOauth() {
            return DruidDataSourceBuilder.create().build();
        }
    }
    
    MyBatis-Plus配置MyBatisPlusConfig.java
    @Configuration
    public class MybatisPlusConfig {
        /**   mybatis-plus分页插件<br>  */
        @Bean
        public PaginationInterceptor paginationInterceptor() {
            PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
            // 设置数据库方言  
           paginationInterceptor.setDialectType(DbType.MYSQL.getDb());
            return paginationInterceptor;
        } 
    }
    
    多数据源分开配置SqlSessionFactory等Bean
    //只要拷贝多个这个文件即可处理多数据源的问题,根据不同的数据源创建相应的包分开放Entity,Mapper,Repository等类即可。
    @Configuration
    @MapperScan(basePackages = "bertram.wang.domain.mapper.comm", 
                sqlSessionFactoryRef = "sqlSessionFactoryComm", 
                sqlSessionTemplateRef = "sqlSessionTemplateComm")
    public class MyBatisConfigCommTest { 
        @Resource(name = "dsComm")
        DataSource dsComm;
        //配置事务管理器
        @Primary
        @Bean(name = "dsCommTransaction")
        PlatformTransactionManager dsMemberTransaction() {
            return new DataSourceTransactionManager(dsComm);
        } 
        
        @Bean
        SqlSessionFactory sqlSessionFactoryComm() {
            SqlSessionFactory sessionFactory = null;
            try {
                MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
                sqlSessionFactory.setDataSource(dsComm);
                sqlSessionFactory.setTypeAliasesPackage("bertram.wang.domain.entity.comm");
                sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/comm/*Mapper.xml"));
                MybatisConfiguration configuration = new MybatisConfiguration();
                configuration.setJdbcTypeForNull(JdbcType.NULL);
                configuration.setMapUnderscoreToCamelCase(true);
                sqlSessionFactory.setConfiguration(configuration); 
                sessionFactory =  sqlSessionFactory.getObject();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return sessionFactory;
        }
        
        @Bean
        SqlSessionTemplate sqlSessionTemplateComm() {
            return new SqlSessionTemplate(sqlSessionFactoryComm());
        }
    }
    
    文档结构示例

    3.使用

    实体示例: User extends BaseEntity (主动填充后面会介绍)
    @Data
    @Accessors(chain = true)
    public class BaseEntity implements Serializable {
        private static final long serialVersionUID = 1L;
        /**
         * 主键标识,自动增长
         */
        @TableId(type = IdType.AUTO)
        private Integer id;
        
        /**
         * 创建日期,添加时自动填充当前日期
         */
        @TableField(fill = FieldFill.INSERT)
        private Date createDate;
        
        /**
         * 修改日期,添加和修改自动填充当前日期
         */
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private Date modifyDate;
    }
    @Data
    @EqualsAndHashCode(callSuper = true)
    @Accessors(chain = true)
    @TableName("sys_user")
    public class User extends BaseEntity {
    
        private static final long serialVersionUID = 1L;
        /**
         * *角色ID数组
         */
        private transient List<Integer> roleIds;
    
        /**
         * *昵称,限制16字符
         */
        private String name;
        /**
         * *用户密码(MD5加密)
         */
        private String password;
    
    }
    
    Mapper示例: 没有自实现的方法
    @Mapper
    public interface UserMapper extends BaseMapper<User> {
    }
    
    Repository以其实现示例
    public interface UserRepository extends IService<User> {
    } 
    @Repository
    public class UserRepositoryImpl extends ServiceImpl<UserMapper, User> implements UserRepository { 
    }
    
    测试单元
    // Select
    @Test
    public void () throws Exception { 
        User user = userRepository.getById(1);
        log.info("users:{}", page.getRecords()); 
    }
    
    执行日志

    执行的SQL很简单: select * from user where id = 1;(忽略通配符)
    再看上面的logo。和springboot一样自带logo牛逼哄哄的样子。springboot打印logo是可以关闭:app.setBannerMode(Banner.Mode.OFF);
    以上是用了mybatis-plus默认配置。

    mybatis-plus配置字段及意义
    mybatis-plus:
      config-location: xxxxxxx  # MyBatis 配置文件位置  ---String 默认:null 
      mapper-locations: # MyBatis Mapper 所对应的 XML 文件位置  ---String[]  默认: [] 
      - classpath*:/mapper/comm
      - classpath*:/mapper/member
      type-aliases-package: bertram.wang.domain.entity # 实体包   --- String
      type-aliases-super-type: bertram.wang.domain.entity.BaseEntity # 实体的父类类名 Class<?>
      type-handlers-package: xxxxxxxx # SqlSessionFactoryBean 会把该包下面的类注册为对应的 TypeHandler ---String 默认:null 
      typeEnumsPackage: xxxxx # 让实体类字段能够简单快捷的使用枚举属性  ---String 默认:null 
      check-config-location: false # 检查mybatis xml 文件的存在
      executor-type: simple # 知道mybatis的执行器
      # configuration-properties:  # 指定外部化 MyBatis Properties 配置,通过该配置可以抽离配置,实现不同环境的配置部署
      configuration: # 本部分(Configuration)的配置大都为 MyBatis 原生支持的配置
        map-underscore-to-camel-case: true #  是否开启自动驼峰命名规则(camel case)映射
        default-enum-type-handler: org.apache.ibatis.type.EnumTypeHandler 
        aggressive-lazy-loading: true #当设置为 true 的时候,懒加载的对象可能被任何懒属性全部加载,否则,每个属性都按需加载。需要和 lazyLoadingEnabled 一起使用
        auto-mapping-behavior: partial # 自动映射策略
        auto-mapping-unknown-column-behavior: none # 自动映射遇到未知列时的处理策略
        cache-enabled: true # 映射器缓存开启
        call-setters-on-nulls: false # 空值的列
        configuration-factory: xxxxxxx # 指定一个提供 Configuration 实例的工厂类 (从 3.2.3 版本开始)
      global-config:
        banner: true # 控制台 print mybatis-plus 的 LOGO
        sql-parser-cache: true # 开启缓存
        worker-id: 1234312 # ID的部分值
        datacenter-id: 1313 # 数据标识ID部分
        super-mapper-class: com.baomidou.mybatisplus.core.mapper.Mapper.class # 通用Mapper父类
        db-config:
          db-type: mysql # 数据库类型
          id-type: auto  # id策略
          table-prefix: t_ # 表前缀
          table-underline: true # 表明下划线命名
          column-like: false # 是否开启 LIKE 查询,即根据 entity 自动生成的 where 条件中 String 类型字段 是否使用 LIKE,默认不开启
          capital-mode: false # 不开启大写命名
          logic-delete-value: 1 # 逻辑已删除值
          logic-not-delete-value: 0 #逻辑未删除值
    
    添加以下配置到配置文件:
    mybatis-plus:
      global-config:
        banner: false # 控制台 print mybatis-plus 的 LOGO
        sql-parser-cache: true # 开启缓存
        db-config:
          db-type: mysql # 数据库类型
          id-type: auto  # id策略
          table-underline: true # 表明下划线命名    
    

    ***执行发现并没有生效???????

    image.png

    没生效,那就自己注册一个Bean呗! MyBatisPlusConfig.java添加Bean

    // 和上面配置文件同样的属性
    @Bean
    public GlobalConfig globalConfig() {
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setBanner(false);
        globalConfig.setSqlParserCache(true);
        DbConfig dbConfig = new GlobalConfig.DbConfig();
        dbConfig.setDbType(DbType.MYSQL);
        dbConfig.setIdType(IdType.AUTO);
        dbConfig.setTableUnderline(true);
        return globalConfig;
    }
    

    MyBatisConfigComm.java 中使用

    @Autowired
    GlobalConfig globalConfig;
    //  在SqlSessionFactory Bean生成时添加以下代码。
    sqlSessionFactory.setGlobalConfig(globalConfig);
    
    执行生效

    没有打印logo说明注入的Bean生效了。
    如果就这样结束了那就不怎么坑了。在项目中insert, insertBatch操作!

    Insert插入一条数据

    公用字段创建时间和修改时间其实使用的都是当前时间。如果能自动填充方便一些。强大的mybatis-plus提供了自动填充功能。具体参考:自动填充功能
    根据官方说的创建MyMetaObjectHandler,实体有加注解。

    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
        
        private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class);
    
        @Override
        public void insertFill(MetaObject metaObject) {
            LOGGER.info("start insert fill ....");
            this.setInsertFieldValByName("createDate", new Date(), metaObject);
            this.setInsertFieldValByName("modifyDate", new Date(), metaObject);
        }
    
        @Override
        public void updateFill(MetaObject metaObject) {
            LOGGER.info("start update fill ....");
            this.setUpdateFieldValByName("modifyDate", new Date(), metaObject);
        }
    }
    

    执行单元测试

    @Test
    public void test2() {
        log.info("==============测试开始==================");
        User user = new User();
        user.setName("bertram.wang");
        user.setPassword("password_bertram.wang");
        userRepository.save(user);
        log.info("==============测试结束==================");
    }
    
    结果很明显并没有用

    在看配置的时候就发现GlobalConfig下有个 MetaObjectHandler属性,只是告诉我们说注入Bean即可。既然没用那就set进去就好了

    globalConfig.setMetaObjectHandler(myMetaObjectHandler());
    
    成功生效

    看到这里应该万事大吉了。

    InsertBatch 批量插入

    @Test
    public void test3() {
        log.info("==============测试开始==================");
        List<User> users = new ArrayList<>();
        for(int i=0; i<3; i++) {
            User user = new User();
            user.setName("name_"+i);
            user.setPassword("password_"+i);
            users.add(user);
        }
        userRepository.saveBatch(users);
        log.info("==============测试结束==================");
    }
    
    执行异常

    org.apache.ibatis.exceptions.PersistenceException: ...Mapped Statements collection does not contain value for bertram.wang.domain.mapper.comm.UserMapper.insert????

    异常一直没有找到处理的方式。 求大神指教!!!! 换了一个方式处理。

    自动配置不会存在这个异常

    很好。把刚才一系列的操作删除换回原始的自动配置的GlobalConfig


    发现现在确实没有抛出以上异常

    异常虽然没有了又回到怎么设置自动填充的问题了?
    数据库设置成默认当前时间。每次修改都设置一下修改时间。这样可以解决。(不建议)

    处理方案

    找到当前的自动配置GlobalConfig信息,然后再手动set进去。
    MyBatisConfigComm.java 方法 sqlSessionFactoryComm 添加一下代码:

            // 获得前配置的全局变量修改
            GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration);
            globalConfig.setBanner(false);
            globalConfig.setMetaObjectHandler(myMetaObjectHandler);
            globalConfig.setSqlInjector(logicSqlInjector);
            globalConfig.getDbConfig().setDbType(DbType.MYSQL);
            globalConfig.getDbConfig().setIdType(IdType.AUTO);
            globalConfig.getDbConfig().setColumnLike(true);
            sqlSessionFactory.setGlobalConfig(globalConfig);
    
    最后的 MyBatisConfigComm.java完成示例:
    @Configuration
    @MapperScan(basePackages = "bertram.wang.domain.mapper.comm", sqlSessionFactoryRef = "sqlSessionFactoryComm", sqlSessionTemplateRef = "sqlSessionTemplateComm")
    public class MyBatisConfigComm {
        @Autowired
        MyMetaObjectHandler myMetaObjectHandler;
        @Autowired
        LogicSqlInjector logicSqlInjector;
        @Resource(name = "dsComm")
        DataSource dsComm;
        //配置事务管理器
        @Primary
        @Bean(name = "dsCommTransaction")
        PlatformTransactionManager dsMemberTransaction() {
            return new DataSourceTransactionManager(dsComm);
        } 
        
        @Bean
        SqlSessionFactory sqlSessionFactoryComm() {
            SqlSessionFactory sessionFactory = null;
            try {
                MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean();
                sqlSessionFactory.setDataSource(dsComm);
                sqlSessionFactory.setTypeAliasesPackage("bertram.wang.domain.entity.comm");
                sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/comm/*Mapper.xml"));
                MybatisConfiguration configuration = new MybatisConfiguration();
                configuration.setJdbcTypeForNull(JdbcType.NULL);
                configuration.setMapUnderscoreToCamelCase(true);
                sqlSessionFactory.setConfiguration(configuration);
                // 获得前配置的全局变量修改
                GlobalConfig globalConfig = GlobalConfigUtils.getGlobalConfig(configuration);
                globalConfig.setBanner(false);
                globalConfig.setMetaObjectHandler(myMetaObjectHandler);
                globalConfig.setSqlInjector(logicSqlInjector);
                globalConfig.getDbConfig().setDbType(DbType.MYSQL);
                globalConfig.getDbConfig().setIdType(IdType.AUTO);
                globalConfig.getDbConfig().setColumnLike(true);
                sqlSessionFactory.setGlobalConfig(globalConfig);
                
                sessionFactory =  sqlSessionFactory.getObject();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return sessionFactory;
        }
        
        @Bean
        SqlSessionTemplate sqlSessionTemplateComm() {
            return new SqlSessionTemplate(sqlSessionFactoryComm());
        }
    } 
    

    替换前面的这个文件即可。

    执行成功

    相关文章

      网友评论

        本文标题:SpringBoot + Vue 后台管理系统(五):mybat

        本文链接:https://www.haomeiwen.com/subject/qbxptctx.html