springboot整合mybatis-plus及功能模块类

1.SpringBoot整合Mybatis-plus

https://mp.baomidou.com/ 官网

是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

特点:

强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求

内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询

分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库

支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题

步骤1: 添加mybatis-plus的starter依赖

 <!--mybatis-plus启动器依赖
         无需再添加mybatis-starter
 -->
<dependency>
   <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-boot-starter</artifactId>
   <version>3.4.1</version>
</dependency>

<!--mysql驱动-->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
</dependency>

步骤2:使用MyBatis-plus的Generator

生成:实体类,controller,service,ServiceImpl,Mapper

a.添加生成器依赖
  <!--mybatisPlus 自动生成器-->
<dependency>
   <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-generator</artifactId>
   <version>3.4.0</version>
</dependency>

<!--mybatisPlus默认模板-->
<dependency>
   <groupId>org.apache.velocity</groupId>
   <artifactId>velocity-engine-core</artifactId>
   <version>2.2</version>
</dependency>
b.创建生成代码工具类

MybatisPlusCodeUtils.java,运行后将帮助我们自动生成代码

package com.woniu.util;

import com.baomidou.mybatisplus.core.config.GlobalConfig;

/**
* MyBatisPlusCode代码生成工具类
*/
public class MyBatisPlusCodeUtil {
   private static final String XML_PATH="/resources/mapper/";
   private static final String ENTITY_IGNORE_PREFIX="smbms_";

   /**
    * 启动方法
    * @param args
    */
   public static void main(String[] args) {
       try {
           generator("gp",//作者
                   "jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai",
                   "com.mysql.cj.jdbc.Driver",//数据库驱动
                   "root",//数据库帐号
                   "root",//数据库密码
                   "com.woniu",//项目最大的包名
                   "springboot-demo03",//项目名或项目模块名
                   "smbms_user,smbms_role");//要操作的表名,多个表名用逗号隔开
           System.out.println("mybaits代码生成成功");
       }catch (Exception e){
           e.printStackTrace();
       }
   }

   /**
    * Mybatis一键生成entity,mapper,mapper.xml,service,serviceImpl,controller
    * @param author            开发人员
    * @param url               驱动连接的URL
    * @param driverName        驱动名称
    * @param username          数据库连接用户名
    * @param password          数据库连接密码
    * @param parentPackage     父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名
    * @param projectModule     项目名
    * @param tableName         表名,多个表名逗号隔开
    */
   public static void generator(String author,
                                String url,
                                String driverName,
                                String username,
                                String password,
                                String parentPackage,
                                String projectModule,
                                String tableName) {
       AutoGenerator mpg = new AutoGenerator();
       mpg.setGlobalConfig(globalConfig(author,projectModule));//全局配置
       mpg.setDataSource(dataSourceConfig(url,driverName,username,password));//数据源配置
       mpg.setPackageInfo(packageConfig(parentPackage));//包配置
       mpg.setStrategy(strategyConfig(tableName));//策略配置
       mpg.setTemplate(templateConfig());//模板配置
       mpg.execute();
   }

   /**
    * 全局配置
    * @param author            开发人员
    * @param projectModule     项目模块名
    * @return                  GlobalConfig
    */
   private static GlobalConfig globalConfig (String author, String projectModule) {
       String projectPath = System.getProperty("user.dir");
       GlobalConfig globalConfig = new GlobalConfig();
       // 文件输出目录
       //如果要在项目中生成用这个
       // globalConfig.setOutputDir(projectPath + "\\src\\main\\java");
       //如果要在模块中生成用这个
       globalConfig.setOutputDir(projectPath + "\\" + projectModule + "\\src\\main\\java");
       // 添加作者信息
       globalConfig.setAuthor(author);
       //设置时间类型为Date  Java8新出的LocalDatetime -->并不是java.util.Date
       globalConfig.setDateType(DateType.TIME_PACK);
       // 生成文件后不默认打开
       globalConfig.setOpen(false);
       // 自定义service生成的名字,用于删除自动生成的I前缀
       globalConfig.setServiceName("%sService");
       // 自定义dao生成的名字,如果不指定默认为%sMapper
       //globalConfig.setMapperName("%sDao");
       return globalConfig;
   }

   /**
    * 数据源设置
    * @param url           驱动连接的URL
    * @param driverName    驱动名称
    * @param username      数据库连接用户名
    * @param password      数据库连接密码
    * @return              DataSourceConfig
    */
   private static DataSourceConfig dataSourceConfig (String url,
                                                     String driverName,
                                                     String username,
                                                     String password) {
       DataSourceConfig dataSourceConfig = new DataSourceConfig();
       dataSourceConfig.setUrl(url);
       dataSourceConfig.setDriverName(driverName);
       dataSourceConfig.setUsername(username);
       dataSourceConfig.setPassword(password);
       return dataSourceConfig;
   }

   /**
    * 包配置
    * @param parentPackage       父包名,最大的包名
    * @return                  PackageConfig
    */
   private static PackageConfig packageConfig(String parentPackage) {
       // 包配置
       PackageConfig packageConfig = new PackageConfig();
       // 包名
       packageConfig.setParent(parentPackage);
       //各个包目录起名
       packageConfig.setEntity("entity");
       packageConfig.setMapper("mapper");
       packageConfig.setXml("mapper");
       packageConfig.setService("service");
       return packageConfig;
   }

   /**
    * 策略配置
    * @param tableName     数据库表名称,多个用英文逗号隔开
    * @return              StrategyConfig
    */
   private static StrategyConfig strategyConfig (String tableName) {
       // 策略配置
       StrategyConfig strategyConfig = new StrategyConfig();
       // 表名驼峰命名
       strategyConfig.setNaming(NamingStrategy.underline_to_camel);
       // 字段驼峰命名
       strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
       // 设置去除表前缀
       strategyConfig.setTablePrefix(ENTITY_IGNORE_PREFIX);
       // 设置实体类的lombok(此处看个人使用,如果不使用lombok,那么在生成之后再去添加构造方法等等)
       strategyConfig.setEntityLombokModel(true);
       //strategyConfig.setRestControllerStyle(true);
       // scanner("表名,多个英文逗号分割").split(",")
       strategyConfig.setInclude((tableName).split(","));
       // 驼峰生成方法
       strategyConfig.setControllerMappingHyphenStyle(true);
       return strategyConfig;
   }

   /**
    * 模板配置项
    * @return  TemplateConfig
    */
   private static TemplateConfig templateConfig () {
       TemplateConfig templateConfig = new TemplateConfig();
       templateConfig.setXml(ConstVal.TEMPLATE_XML);
       //不生成mapper.xml文件
       templateConfig.setXml(null);
       //不生成service
       //templateConfig.setService(null);
       //不生成service实现类
       //templateConfig.setServiceImpl(null);
       //不生成controller类
       templateConfig.setController(null);
       return templateConfig;
   }
}
c.使用MyBatisPlus-CRUD
  • 查询列表

@RestController
public class UserController {
   @Autowired
   private UserService userService;

   @GetMapping("/list")
   public List<User> getUserList(){
       //QueryWrapp 包装器,用于封装查询条件 ,如果为null则表示不限条件
       List<User> userList = userService.list(null);
       return userList;
   }
}
  • 根据Id查询

@GetMapping("/getById/{id}")
public User getUserById(@PathVariable("id") Integer id){
   //QueryWrapp 包装器,用于封装查询条件 ,如果为null则表示不限条件
   User user = userService.getById(id);
   return user;
}
  • 分页查询

    MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能

首先,添加分页拦截器配置

@Configuration
public class MyBatisPlusConfig {

   //配置分页插件

   /**
    * 防止 修改与删除时对全表进行操作
    *
    * @return
    */
   @Bean
   public BlockAttackInnerInterceptor blockAttackInnerInterceptor() {
       return new BlockAttackInnerInterceptor();
   }


   /**
    * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题
    */
   @Bean
   public MybatisPlusInterceptor mybatisPlusInterceptor() {
       MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
       interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
       return interceptor;
   }


   /**
    * ConfigurationCustomizer,这里引用的是MyBatisPlus自定义的一个和MyBatis同名的接口,com.baomidou.mybatisplus.spring.boot.starter.ConfigurationCustomizer,
    * 因此必须使用MyBatisPlus的ConfigurationCustomizer才行
    *
    * @return
    */
   @Bean
   public ConfigurationCustomizer configurationCustomizer() {
       return new ConfigurationCustomizer() {
           @Override
           public void customize(MybatisConfiguration configuration) {
               configuration.setCacheEnabled(true);
               configuration.setMapUnderscoreToCamelCase(true);
               configuration.setCallSettersOnNulls(true);
               configuration.setJdbcTypeForNull(JdbcType.NULL);
           }
       };
   }
}

执行分页查询

 @GetMapping("/list")
   public Page<User> getUserList(){
       Page<User> page = new Page<>(1,5);
       //注意:传入的page与对象与返回的page对象是同一个
       Page<User> pageInfo = userService.page(page,null);
       return pageInfo;
   }
  • 按条件查询的分页:

UserController:

@GetMapping("/list")
public Page<User> getUserList(@RequestParam(name="pageNum",defaultValue = "1") Integer pageNum, @RequestParam(name="pageSize",defaultValue = "5") Integer pageSize,
                              User user){
    Page<User> page = userService.getPage(pageNum,pageSize,user);
    return page;
}

UserServiceImpl业务实现类

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Autowired
    private UserMapper userMapper;
    /**
     * 执行分页带条件查询
     * @param pageNum
     * @param pageSize
     * @param user
     * @return
     */
   public Page<User> getPage(Integer pageNum, Integer pageSize, User user) {
        //创建分页对象
        Page<User> page = new Page<>(pageNum,pageSize);

        //QueryWrapp查询包装器
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        if(user.getUserCode()!=null && !user.getUserCode().equals("")) {
            wrapper.like("userCode", user.getUserCode()); //默认为and关系
        }

        if(user.getGender()!=null) {
            wrapper.eq("gender", user.getGender());
        }

       // wrapper.or().eq("gender",user.getGender());
        wrapper.orderByAsc("id"); //查询中的排序列

        page = userMapper.selectPage(page,wrapper);
        return page;
    }
}

2.SpringBoot实战-2

2-1 消息转换器配置

SpringMVC中xml与配置类实现消息转换器配置

HttpMessageConverter接口

      |-StringHttpMessageConverter 实现类  [字符串消息转换器]

@ResponseBody

Pojo对象--> JSON格式 -->消息转换器 [Jackson,Fastjson]

如果使用fastjson 需要单独添加依赖,SpringBoot默认使用Jackson消息转换,不需要添加依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.74</version>
</dependency>

在WebMvcConfig配置类中添加消息转换器


@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {

    /**
     * 配置SpringBoot消息转换器
     * @param converters
     */
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        List<HttpMessageConverter<?>> result = new ArrayList<>(converters.size());

        //配置Jackson消息转换器
        MappingJackson2HttpMessageConverter converter =
                new MappingJackson2HttpMessageConverter();
        //设置转换器配置信息
        MediaType mediaType = MediaType.valueOf("application/json;charset=UTF-8");
        List<MediaType> mediaTypeList = new ArrayList<>();
        mediaTypeList.add(mediaType);
        converter.setSupportedMediaTypes(mediaTypeList);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd E"));
        converter.setObjectMapper(objectMapper);
        result.add(converter);


        //配置fasterJSON消息转换
        //使用FastJson作为HTTP的序列化和反序列工具
        // 1.定义Converter转换器对象
        // FastJsonHttpMessageConverter converter2 =
        //         new FastJsonHttpMessageConverter();
        // // 2.1设置转换器的配置信息
        // FastJsonConfig config = new FastJsonConfig();
        // config.setSerializerFeatures(
        //         //List字段如果为null,输出为[],而非null
        //         SerializerFeature.WriteNullListAsEmpty,
        //         //字符类型字段如果为null,输出为"",而非null
        //         // SerializerFeature.WriteNullStringAsEmpty,
        //         //Boolean字段如果为null,输出为falseJ,而非null
        //         SerializerFeature.WriteNullBooleanAsFalse,
        //         //消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
        //         SerializerFeature.DisableCircularReferenceDetect,
        //         //是否输出值为null的字段,默认为false。
        //         SerializerFeature.WriteMapNullValue,
        //         SerializerFeature.WriteDateUseDateFormat
        // );
        // // 2.2设置编码,处理中文乱码
        // converter2.setDefaultCharset(Charset.forName("UTF-8"));
        // config.setCharset(Charset.forName("UTF-8"));
        // // 3.将设置添加到转换器中
        // converter2.setFastJsonConfig(config);
        // result.add(converter2);

        //配置编码转换
        result.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));
        //清除转换器,添加
        converters.clear();
        //添加转换器列表
        converters.addAll(result);

    }
}

针对日期 Date类型实体类字段

  /**
     * 出生日期
     */
    @JsonFormat(pattern="yyyy-MM-dd")  //Jackson 将Date日期类型转换为Json串时
    @JSONField(format = "yyyy-MM-dd") //fastjson 将Date日期类型转换为Json串时
    private Date birthday;

2-2 类型转换器

User里面的birthday属性是一个Date对象类型,提交的日期是一个字符串类型,这个时候就需要进行类型转换

第一种方式就是在user类的属性上添加注解 @DateTimeFormat(pattern = "yyyy-mm-dd")

第二种方式就是我们自己要自定义一个类型转换器

@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
    // 注册类型 转换器
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new Converter<String, Date>() {
            @Override
            public Date convert(String source) {
                try {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    Date date = sdf.parse(source);
                    return date;
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
    }
}
  • 如果将String转LocaleDate或LocaleDateTime

 registry.addConverter(new Converter<String, LocalDateTime>(){
     @Override
     public LocalDateTime convert(String source) {
         System.out.println("String转LocalDateTime.............");
         if(source.trim().length() ==0 ){
             return null;
         }
         try {
             //先尝试先尝试
             // 格式ISO : 2019-07-15T16:00:00
             return LocalDateTime.parse(source);
         } catch (Exception e) {
             //  e.printStackTrace();
             return LocalDateTime.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
         }
     }
 });

//添加String转换LocalDate格式
registry.addConverter(new Converter<String, LocalDate>(){
    @Override
    public LocalDate convert(String source) {
        System.out.println("String转LocalDate.............");
        if(source.trim().length() ==0 ){
            return null;
        }
        try {
            //先尝试先尝试
            return LocalDate.parse(source);
        } catch (Exception e) {
            //  e.printStackTrace();
            return LocalDate.parse(source, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        }
    }
});

2-3 文件上传

编写上传文件表单

<form action="toadd" method="post" enctype="multipart/form-data">
    <p>用户名:<input type="text" name="userCode" /></p>
    <p>密码:<input type="text" name="userPassword" /></p>
    <p>日期:<input type="datetime-local" name="birthday" /></p>
    <p>文件1:<input type="file" name="uploadfile" /></p>
    <p>文件2:<input type="file" name="uploadfile" /></p>
    <p> <input type="submit" value="提交" /></p>
</form>

处理上传文件请求:

@PostMapping("/toadd")
public String toAdd(User user,  @RequestParam("uploadfile") List<MultipartFile> files,
                    HttpServletRequest request) throws FileNotFoundException {
    System.out.println(user);
   
    //上传文件的路径
    String uploadPath = ResourceUtils.getURL("classpath:").getPath()+"static/pic/";
    System.out.println(uploadPath);
    
    //如果上传文件目录不存在,则创建
    File uploadDir = new File(uploadPath);
    if(!uploadDir.exists()){
        uploadDir.mkdirs();
    }

    //执行批量上传
    for(int i=0;i<files.size();i++){
        MultipartFile file = files.get(i);
        if (file.isEmpty()) {
            return "上传第" + (i+1) + "个文件失败";
        }

        //重命名文件名,随机
        String originalFilename = file.getOriginalFilename();
        String ext = originalFilename.substring(originalFilename.lastIndexOf("."));
        String newFileName = UUID.randomUUID().toString().replace("-","")+ext;

        //生成目标File对象
        File targetFile = new File(uploadPath+newFileName);
        try {
            //拷贝文件
            file.transferTo(targetFile);
        } catch (IOException exception) {
            exception.printStackTrace();
            return "上传第" + (i+1) + "个文件失败";
        }
    }

    // user.setIdpicpath("pic/"+newFileName);

    //写入user 到数据库

    return "上传文件OK!";
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值