JAVA框架/工具推荐

1:mybatis-plus

推荐理由:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer2005、SQLServer 等多种数据库
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 XML 热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
  • 内置 Sql 注入剥离器:支持 Sql 注入剥离,有效预防 Sql 注入攻击

案例

 // 配置查询条件
        EntityWrapper accountWrapper = new EntityWrapper<>();
        accountWrapper
                .like(!StringUtils.isBlank(account),
                        "alipay_account", account)
                .like(!StringUtils.isBlank(name), "alipay_name", name)
                .like(!StringUtils.isBlank(aging), "aging", aging)
                .eq(null != isOpen, "is_open", isOpen)
                .eq("is_delete", 0);

        Page page = this.selectPage(new Page<>(query.getCurrent(), query.getSize()), accountWrapper);

2:lombok

推荐理由:Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。

Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。

example:


    org.projectlombok
    lombok
    1.16.20
    provided

Lombok有哪些注解
@Setter
@Getter
@Data
@Log(这是一个泛型注解,具体有很多种形式)
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@NonNull
@Cleanup
@ToString
@RequiredArgsConstructor
@Value
@SneakyThrows
@Synchronized

3:spring中的restTemplate

Spring RestTemplate 是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程Http服务的方法,能够大大提高客户端的编写效率,

结合spring cloud ribbon和fegin起到很好的效果,同时使用httpClient工具的不可维护性的问题,httpClient得到的response需要大量的json解析,使得系统维护麻烦。

example:

package com.fahui.core.live.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.fahui.common.exceptions.LawBizException;
import com.fahui.core.live.beans.channel.*;
import com.fahui.core.live.beans.vod.video.GetRequest;
import com.fahui.core.live.beans.vod.video.GetResponse;
import com.fahui.core.live.constants.LiveConstant;
import com.fahui.core.live.service.IFhLiveService;
import com.fahui.core.service.entity.FhLiveChannel;
import com.fahui.core.service.service.IFhLiveChannelService;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

/**
 * @Description:
 * @author:CAIYJ
 * @Date:2018/7/21 10:14
 */
@Service
public class FhLiveServiceImpl implements IFhLiveService {

    @Autowired
    private IFhLiveChannelService liveChannelService;

    @Autowired
    @Qualifier("wyRestTemplate")
    private RestTemplate restTemplate;

    private static String prfixUrl = "https://vcloud.163.com";

    @Override
    public VodVideoListResponse vodVideoList(VodVideoListRequest request) throws Exception {
        BaseResponseGeneric response = restTemplate.exchange(prfixUrl+"/app/vodvideolist",
                HttpMethod.POST,
                new HttpEntity<>(request),
                new ParameterizedTypeReference>() {
                }).getBody();
        checkResponseGeneric(response);
        return response != null ? response.getRet() : null;
    }

    @Override
    public boolean setCallback(SetCallbackRequest request) throws Exception {
        BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/record/setcallback", request, BaseResponse.class);
        checkResponse(response);
        return true;
    }

    @Override
    public boolean merge(MergeRequest request) throws Exception {
        BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/video/merge", request, BaseResponse.class);
        checkResponse(response);
        return true;
    }

    @Override
    public boolean resetRecord(ResetRecordRequest request) throws Exception {
        BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/channel/resetRecord", request, BaseResponse.class);
        checkResponse(response);
        return true;
    }

    @Override
    public TransCodeAddressResponse transCodeAddress(TransCodeAddressRequest request) throws Exception {
        BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/transcodeAddress", request, BaseResponse.class);
        checkResponse(response);
        TransCodeAddressResponse transCodeAddressResponse = new TransCodeAddressResponse();
        BeanUtils.populate(transCodeAddressResponse, response.getRet());
        return transCodeAddressResponse;
    }

    @Override
    public CallbackQueryResponse callbackQuery() throws Exception {
        BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/record/callbackQuery", null, BaseResponse.class);
        checkResponse(response);
        CallbackQueryResponse callbackQueryResponse = new CallbackQueryResponse();
        BeanUtils.populate(callbackQueryResponse, response.getRet());
        return callbackQueryResponse;
    }

    @Override
    public boolean setupRecordInfo(SetupRecordInfoRequest request) throws Exception {
        if (null == request) {
            return false;
        }
        BaseResponse response = restTemplate.postForObject(prfixUrl+"/app/channel/setupRecordInfo", request, BaseResponse.class);
        checkResponse(response);
        QueryWrapper ew = new QueryWrapper<>();
        ew.eq(StringUtils.isNotEmpty(request.getCid()), "cid", request.getCid());
        FhLiveChannel liveChannel = new FhLiveChannel();
        BeanUtils.copyProperties(liveChannel, request);
        liveChannelService.update(liveChannel, ew);
        return true;
    }

    @Override
    public GetResponse getVideo(GetRequest request) throws Exception {
        BaseResponseGeneric response = restTemplate.exchange(prfixUrl+"/app/vod/video/get",
                HttpMethod.POST,
                new HttpEntity<>(request),
                new ParameterizedTypeReference>() {
                }).getBody();
        checkResponseGeneric(response);
        return response != null ? response.getRet() : null;
    }

    private void checkResponseGeneric(BaseResponseGeneric response) throws Exception {
        if (null == response) {
            throw new LawBizException(602, "查询失败", null);
        } else {
            switch (response.getCode()) {
                case 200:
                    return;
                default:
                    throw new LawBizException(response.getCode(), response.getMsg(), null);
            }
        }
    }

    private void checkResponse(BaseResponse response) throws Exception {
        if (null != response) {
            switch (response.getCode()) {
                case 200:
                    return;
                default:
                    throw new LawBizException(response.getCode(), response.getMsg(), null);
            }
        } else {
            throw new LawBizException(602, "查询失败", null);
        }
    }
}

 

4:hibernate-validator

理由:

1:使用注解的形式将参数校验与业务代码分离

2:定义通用的validator,切面的形式切入到业务代码中

3:结合spring boot中的全局异常捕捉,系统原理繁琐的入参校验

package com.fahui.liquidation.receiver.bean.po.example;

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.*;
import java.util.Date;
import java.util.List;


/**
 * @Description:
 * @author:CAIYJ
 * @Date:2018/8/13 11:34
 */
@Data
public class  ConstraintExample {

    private Integer id;

    //---------------------------------------------Bean Validation 中内置的 constraint-------------------------------------
    /**
     * 被注释的元素必须不为 null(任何对象的value不能为null)_
     */
    @NotNull
    private String name;

    /**
     * 被注释的元素必须为 true
     */
    @AssertTrue
    private Boolean assertTrue;

    /**
     * 被注释的元素必须为 false
     */
    @AssertFalse
    private Boolean assertFalse;

    /**
     * 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
     */
    @Min(11)
    private Integer min;

    /**
     * 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
     */
    @Max(60)
    private Integer max;

    /**
     * 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
     */
    @DecimalMin("11")
    private String decimalMin;

    /**
     * 注释的元素必须是一个数字,其值必须小于等于指定的最大值
     */
    @DecimalMax("60")
    private String decimalMax;

    /**
     * 被注释的元素的大小必须在指定的范围内
     */
    @Size(min = 11, max = 60, message = "大小在11-60之間")
    private String size;

    /**
     * 被注释的元素必须是一个数字,其值必须在可接受的范围内
     */
    @Digits(integer = 11, fraction = 60, message = "范围在11-60之间")
    private Integer digits;

    /**
     * 被注释的元素必须是一个过去的日期
     */
    @Past(message = "被注释的元素必须是一个过去的日期")
    private Date past;

    /**
     * 被注释的元素必须是一个将来的日期
     */
    @Future(message = "被注释的元素必须是一个将来的日期")
    private Date future;

    @Pattern(regexp = "^[0-9]{4}-[0-9]{2}-[0-9]{2}$", message = "出生日期格式不正确")
    private String birth;

    //---------------------------------------------Hibernate Validator 附加的 constraint-------------------------------------

    /**
     * 被注释的元素必须是电子邮箱地址
     */
    @Email(message = "须是电子邮箱地址")
    private String email;

    /**
     * 被注释的字符串的大小必须在指定的范围内
     */
    @Length(min = 11, max = 60, message = "字符串长度在11-60之间")
    private String length;

    /**
     * 被注释的字符串的必须非空(集合对象的元素不为0,即集合不为空,也可以用于字符串不为null)
     */
    @NotEmpty
    private List notEmpty;

    @Range(min = 18, max = 30, message = "年龄限制在18-30岁之间")
    private Integer age;

    /**
     * 被注释的字符串的必须非空
     */
    @NotBlank(message = "字符必须非空")
    private String notBlank;

  
}
package com.fahui.validator.example;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

/**
 * @Description:不能存在空字符串
 * @author:CAIYJ
 * @Date:2018/8/16 16:57
 */
public class CannotContainSpacesValidator implements ConstraintValidator {
    private int len;

    /**
     * 初始参数,获取注解中length的值
     */
    @Override
    public void initialize(CannotContainSpaces arg0) {
        this.len = arg0.length();
    }

    @Override
    public boolean isValid(String str, ConstraintValidatorContext constraintValidatorContext) {
        if (str != null) {
            if (str.indexOf(" ") < 0) {
                return true;
            }
        } else {
            constraintValidatorContext.disableDefaultConstraintViolation();//禁用默认的message的值
            //重新添加错误提示语句
            constraintValidatorContext
                    .buildConstraintViolationWithTemplate("字符串不能为空").addConstraintViolation();
        }
        return false;
    }
}

5:fastjson

理由:使用该jar中的消息转换,可以全局解决返给前端数据的问题

 /**
     * 增加消息转换器,将返回消息中的 null 转成空字符串
     *
     * @param converters
     */
    @Override
    protected void configureMessageConverters(List> converters) {
        FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
        FastJsonConfig fjc = new FastJsonConfig();
        //1、序列化重点
        fjc.setSerializerFeatures(SerializerFeature.BrowserCompatible);
        //是否输出值为null的字段,默认为false
        fjc.setSerializerFeatures(SerializerFeature.WriteMapNullValue,
                // Boolean字段如果为null,输出为false,而非null
                SerializerFeature.WriteNullBooleanAsFalse,
                // 字符类型字段如果为null,输出为”“,而非null
                SerializerFeature.WriteNullStringAsEmpty,
                // Number类型为空则输出0
                SerializerFeature.WriteNullNumberAsZero,
                // 禁止循环引用
                SerializerFeature.DisableCircularReferenceDetect,
                // List为空则输出[]
                SerializerFeature.WriteNullListAsEmpty);
//        fjc.setSerializeFilters((ValueFilter) (o, s, source) -> {
//            if (source instanceof Date) {
//                return ((Date) source).getTime() + "";
//            }
//            return source;
//        });
        fastJsonConverter.setFastJsonConfig(fjc);
        List mediaTypes;
        mediaTypes = Arrays.asList(
                MediaType.APPLICATION_JSON_UTF8,
                MediaType.TEXT_PLAIN,
                MediaType.TEXT_HTML,
                MediaType.TEXT_XML,
                MediaType.APPLICATION_OCTET_STREAM);
        fastJsonConverter.setSupportedMediaTypes(mediaTypes);
        fastJsonConverter.setDefaultCharset(Charset.forName("UTF-8"));
        converters.add(fastJsonConverter);
    }

6:swagger

理由:你懂得。最讨厌写word版本的接口文档了。。。

example:

    @ApiOperation(value = "删除角色信息", notes = "删除角色信息", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    @RequestMapping(value = "remove/{id}")
    public BaseRestVO remove( @PathVariable Long id) throws Exception {
        roloService.removeById(id);
        return BaseRestVO.success("删除成功");
    }

7:ELK

理由:一般大型系统是一个分布式部署的架构,不同的服务模块部署在不同的服务器上,问题出现时,大部分情况需要根据问题暴露的关键信息,定位到具体的服务器和服务模块,构建一套集中式日志系统,可以提高定位问题的效率。

一个完整的集中式日志系统,需要包含以下几个主要特点:

  • 收集-能够采集多种来源的日志数据
  • 传输-能够稳定的把日志数据传输到中央系统
  • 存储-如何存储日志数据
  • 分析-可以支持 UI 分析
  • 警告-能够提供错误报告,监控机制

ELK提供了一整套解决方案,并且都是开源软件,之间互相配合使用,完美衔接,高效的满足了很多场合的应用。目前主流的一种日志系统。(es是个好东西)

8:hutool

理由:

Hutool是Hu + tool的自造词,前者致敬我的“前任公司”,后者为工具之意,谐音“糊涂”,寓意追求“万事都作糊涂观,无所谓失,无所谓得”的境界。

Hutool是一个Java工具包,也只是一个工具包,它帮助我们简化每一行代码,减少每一个方法,让Java语言也可以“甜甜的”。Hutool最初是我项目中“util”包的一个整理,后来慢慢积累并加入更多非业务相关功能,并广泛学习其它开源项目精髓,经过自己整理修改,最终形成丰富的开源工具集。(抄自作者简介),当然类似的也有Apache的commons包等

9:spring boot相关的starter和spring cloud

spring官网

springcloud中文官网

本人改过spring-data-elasticsearch,深知spring社区对elasticsearch封装的有多好。同时也是经历过原生elasticsearch java api代码转变到spring-data-elasticsearch的过程

10:sharding-jdbc

http://shardingsphere.apache.org/

你可能感兴趣的:(JAVA框架/工具推荐)