本文针对写项目时用到的知识点进行总结
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>${mybatis-plus.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://jiacloud.ml:3306/yygh_hosp?characterEncoding=utf-8&useSSL=false
spring.datasource.username=用户名
spring.datasource.password=密码
# mybatis-plus
#mybatis-plus
mybatis-plus.mapper-locations=classpath:xml放的位置
mybatis-plus.type-aliases-package=要扫描的包
第一步:继承BaseMapper
@Mapper//将其注册到spring容器中
public interface UserMapper extends BaseMapper<User>{}
第二部:在启动类上加上扫描包路径
@SpringBootApplication
@MapperScan("com.test.mapper")
public class SpringBootMybatisPlusApplication {}
第三步:新建Mybatis-plus配置类
@Configuration
public class MyBatisPlusConfig {
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor(){
return new PaginationInterceptor();
}
}
第四步:编写服务层接口Service
//继承通用IService
public interface UserService extends IService<User> {}
第五步:编写Service实现
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {}
//ServiceImpl中已经注入了baseMapper,所以继承后可以直接调用baseMapper
第六步:编写Controller
@RestController
public class UserController{
//注入service
@AutoWired
private UserService userService;
//编写服务
}
分页查询的实现
public List<User> UserPage(long page,long limit,String username){
//创建page对象
Page<User> page = new Page<>(page,limit);
//构造条件查询
QueryWrapper<User> qw = new QueryWrapper<>();
qw.eq("username",username);
Page<User> pageDate= userService.page(page,qw);
return pageDate.getRecords();
}
@TableName:数据库表相关
@TableId:表主键标识
@TableField:表字段标识
@TableLogic:表字段逻辑处理注解(逻辑删除)
@TableId(type= IdType.ID_WORKER_STR)
@TableField(exist = false):表示该属性不为数据库表字段,但又是必须使用的。
@TableField(exist = true):表示该属性为数据库表字段。
@TableField(condition = SqlCondition.LIKE):表示该属性可以模糊搜索。
@TableField(fill = FieldFill.INSERT):注解填充字段 ,生成器策略部分也可以配置!
逻辑删除
#配置可配可不配
mybatis-plus:
global-config:
db-config:
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
@TableLogic
private Integer isDeleted;
主键自增
@TableId(type = IdType.AUTO)
private Long id;
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-mongodbartifactId>
dependency>
spring.data.mongodb.host=数据库地址
spring.data.mongodb.port=端口号
spring.data.mongodb.database=使用的数据库
spring.data.mongodb.authentication-database=要验证的数据库名称
spring.data.mongodb.username=用户名
spring.data.mongodb.password=密码
## 这里的用户名和密码要填写的是验证的数据库用户名和密码,而不是使用的数据库
第一步:创建pojo对象
@Document("User")//标明由mongo来维护该表
public class User {
@Id//指定为表的ID
private String id;
}
第二部:编写Repository用来操作数据库
public interface UserRepository extends MongoRepository<User,String>{}
第三步:在Service实现类中注入Repository进行数据库增删改查
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@AutoWired
private UserRepository userRepository;
}
创建pojo对象后直接在Service实现中注入MongoTemplate
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@AutoWired
private MongooTemplate mongoTemplate;
}
MongoRepository的缺点是不够灵活,MongoTemplate正好可以弥补不足。
如果使用MongoRepository操作数据库
Spring Data提供了对mongodb数据访问的支持,我们只需要继承MongoRepository类,按照Spring Data规范就可以了
例如根据id查询数据库中User表信息
//这样可以直接调用,规则就是find表名By字段名,后面还可以接And,如findUserByIdAndName()就表示根据ID和name进行查询
User user = userRepository.findUserById();
分页查询
public Page<User> getUserList(User user, int page, int limit) {
//创建pageable page从0开始
Pageable pageable = PageRequest.of(page-1,limit);
//创建Example对象,模糊查询,忽略大小写
ExampleMatcher matcher = ExampleMatcher.matching().withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING).withIgnoreCase(true);
Example<Schedule> example = Example.of(user,matcher);
Page<Schedule> all = scheduleRepository.findAll(example, pageable);
return all;
}
MongoTemplate聚合操作(重难点)
//根据id,name查询后通过sex进行分组后根据年龄进行排序后进行分页
public List<User> getUserListPage(int page,int limit,String id, String name) {
Criteria criteria = Criteria.where("id").is(id).and("name").is(name);
//根据日期进行分组
Aggregation agg= Aggregation.newAggregation(
Aggregation.match(criteria),//匹配条件
Aggregation.group("sex")//分组字段
.first("sex").as("性别")
//号源统计
//排序
Aggregation.sort(Sort.Direction.DESC,"age"),
//分页
Aggregation.skip((page-1)*limit),
Aggregation.limit(limit)
);
AggregationResults<User> aggregate = mongoTemplate.aggregate(agg, User.class, User.class);
return aggregate.getMappedResults();
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-pool2artifactId>
<version>2.6.0version>
dependency>
spring.redis.host=服务地址
spring.redis.port=端口
spring.redis.database= 所用数据库
#过期时间
spring.redis.timeout=1800000
spring.redis.password=密码
#最大连接数
spring.redis.lettuce.pool.max-active=20
#生成池最大等待数(负数表示没限制)
spring.redis.lettuce.pool.max-wait=-1
#最大阻塞等待时间(负数表示没限制)
spring.redis.lettuce.pool.max-idle=5
spring.redis.lettuce.pool.min-idle=0
第一步:编写Redis配置文件,开启缓存
@Configuration
@EnableCaching//开启缓存
public class RedisConfig {
/**
* 自定义key规则
* @return
*/
@Bean
public KeyGenerator keyGenerator() {
return (target, method, params) -> {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
return sb.toString();
};
}
/**
* 设置RedisTemplate规则
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
//序列号key value
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* 设置CacheManager缓存规则
* @param factory
* @return
*/
@Bean
public CacheManager cacheManager(RedisConnectionFactory factory) {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//解决查询缓存转换异常的问题
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 配置序列化(解决乱码的问题),过期时间600秒
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofSeconds(600))
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
.disableCachingNullValues();
RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}
第二步:在方法上使用注解进行缓存
//根据id查询用户信息,然后将其返回
//vule表示命名,keyGenerator表示名字生成规则
@Cacheable(value = "user",keyGenerator = "keyGenerator")//key的命名
public List<User> findChlidData(Long id) {
QueryWrapper<User> qw = new QueryWrapper<>();
qw.eq("id",id);
List<User> users = baseMapper.selectList(qw);
return users;
}
@Cacheable
@Cacheable 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存
@CachePut
@CachePut 的作用 主要针对方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发真实方法的调用
@CacheEvict
@CachEvict 的作用 主要针对方法配置,能够根据一定的条件对缓存进行清空
SpEL上下文数据
EasyExcel是一个基于Java的简单、省内存的读写Excel的开源项目。在尽可能节约内存的情况下支持读写百M的Excel。
<dependency>
<groupId>com.alibabagroupId>
<artifactId>easyexcelartifactId>
<version>2.1.1version>
dependency>
@Data
public class UserEeVo {
@ExcelProperty(value = "id",index = 0)
private Long id;
@ExcelProperty(value = "名称",index = 1)
private String name;
@ExcelProperty(value = "年龄",index = 2)
private int age;
@ExcelProperty(value = "性别",index = 3)
private int sex;
}
@Override
public void exportData(HttpServletResponse response) {
try {
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
String fileName = URLEncoder.encode("用户列表", "UTF-8");
//导出文件名字
response.setHeader("Content-disposition", "attachment;filename="+ fileName + ".xlsx");
//调用查询数据库信息
List<User> userList = dictMapper.selectList(null);
//创建导出用的list集合,根据数据库查询到的数量进行定义长度
List<UserEeVo> userVoList = new ArrayList<>(userList.size());
for(User user : userList) {
UserEeVo userVo = new UserEeVo();
//使用工具将user中的数据拷贝到Uservo中
BeanUtils.copyBean(user, userVo, UserEeVo.class);
//将数据添加到list集合
userVoList.add(userVo);
}
//调用输出方法将数据变成excel输出
EasyExcel.write(response.getOutputStream(), UserEeVo.class).sheet("用户列表").doWrite(userVoList);
} catch (IOException e) {
e.printStackTrace();
}
}
第一步:创建监听器
@Component
public class UserListener extends AnalysisEventListener<UserEeVo> {
@Autowired
private UserMapper userMapper ;
@Override
//每行每行读取
public void invoke(UserEeVo userEeVo, AnalysisContext analysisContext) {
User user =new User();
//将vo中数据拷贝到user类中
BeanUtils.copyProperties(userEeVo,user);
//设置逻辑删除值
user.setIsDeleted(0);
//将数据插入数据库
userMapper.insert(user);
}
@Override
//读取后运行
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
}
}
@Override
public void importExport(MultipartFile file) {
try {
//将export中数据上传到数据库,调用read方法,传入文件和类型还有监听器,进行处理
EasyExcel.read(file.getInputStream(),UserEeVo.class,userListener).sheet().doRead();
} catch (IOException e) {
e.printStackTrace();
}
}
我本次写项目用到了nacos注册中心,Feign服务调用和GateWay三个模块,下面对每个作用和使用进行总结
Nacos 是用来发现、配置和管理微服务的管理平台
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
#nacos地址默认地址未8848
nacos:
config:
server-addr: 127.0.0.1:8848
#配置服务名字
spring:
application:
name: user
@SpringBootApplication
//配置包扫描
@ComponentScan(basePackages = "com.jiaboke")
//开启发现客户端
@EnableDiscoveryClient
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class,args);
}
}
下载官方安装包,解压,找到bin目录,window运行startup.cmd
脚本进行启动,Linux运行startup.sh进行启动。然后就可以访问
127.0.0.1:8848/nacos进行服务的查看和管理(默认用户:nacos,密码:nacos)
Spring Cloud Feign提供的声明式服务绑定功能来实现对该服务接口的调用
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
@SpringBootApplication
@ComponentScan(basePackages = "com.jiaboke")
//开启服务发现
@EnableDiscoveryClient
//开启服务调用支持
@EnableFeignClients(basePackages = "com.jiaboke")
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceHospApplication.class,args);
}
}
@RestController
@Api(tags = "用户管理")
@RequestMapping("admin/user")
public class UserController {
//注入service
@Autowired
private UserService userService;
@ApiOperation(value = "根据id查询用户")
@GetMapping("selectUserById/{id}")
public User selectUserById(@PathVariable String id){
//调用service方法查询到用户信息,将其返回
return userService.selectById(id);
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>user-parentartifactId>
<groupId>com.jiaboke.usergroupId>
<version>1.0version>
parent>
<modelVersion>4.0.0modelVersion>
<version>1.0version>
<artifactId>service-user-clientartifactId>
<packaging>jarpackaging>
<name>service-user-clientname>
<description>service-user-clientdescription>
<dependencies>
<dependency>
<groupId>com.jabokegroupId>
<artifactId>common-utilartifactId>
<version>1.0version>
dependency>
<dependency>
<groupId>com.jiabokegroupId>
<artifactId>modelartifactId>
<version>1.0version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
<scope>provided scope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
<scope>provided scope>
dependency>
dependencies>
project>
//服务提供者名字
@FeignClient(value = "user")
//将其注册到Spring托管
@Repository
public interface UserFeignClient {
//根据id获取用户信息
@GetMapping("admin/user/selectUserById/{id}")
User selectUserById(@PathVariable("id") Long id);
}
<dependency>
<groupId>com.jiaboke.usergroupId>
<artifactId>service-user-clientartifactId>
<version>1.0version>
dependency>
public class UserTestServiceImpl implements UserTestService{
@Autowired
private UserFeignClient userFeignClient;
public User UserTest(String id){
return userFeignClient.selectUserById(id);
}
}
Spring cloud gateway是spring官方基于Spring 5.0、Spring Boot2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供简单、有效和统一的API路由管理方式,Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是替代Netflix Zuul,其不仅提供统一的路由方式,并且还基于Filer链的方式提供了网关基本的功能,例如:安全、监控/埋点、限流等
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
dependencies>
# 服务端口
server.port=80
# 服务名
spring.application.name=service-gateway
# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
#使用服务发现路由
spring.cloud.gateway.discovery.locator.enabled=true
#设置路由id
spring.cloud.gateway.routes[0].id=user
#设置路由的uri
spring.cloud.gateway.routes[0].uri=lb://user
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[0].predicates= Path=/*/user/**
@SpringBootApplication
public class ServiceGateWayApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceGateWayApplication.class,args);
}
}
什么是跨域?
浏览器从一个域名的网页去请求另一个域名的资源时,域名、端口、协议任一不同,都是跨域
跨域的解决方法
第一种:在controller类上添加@CrossOrigin就可以了,不过该方法有个弊端,你每写一个controller都要进行添加,所以就有第二种方法
第二种:在gateway中统一进行解决,方法代码如下
//处理跨域,代码较为固定,不多做解释用到粘贴复制就行
@Configuration
public class CorsConfig {
@Bean
public CorsWebFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedMethod("*");
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config);
return new CorsWebFilter(source);
}
}
这个是springboot提供的邮箱服务,我的项目用来发送验证码等消息(原本想用短信服务,但是个人注册不了阿里云的短信服务就出此下策)
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-mailartifactId>
<version>2.2.1.RELEASEversion>
dependency>
#配置邮箱服务
spring.mail.host=smtp.qq.com#用的QQ邮箱,根据你选择的邮箱进行修改
spring.mail.username=[email protected]##邮箱
spring.mail.password= XXXXXXXX #QQ邮箱的授权码
spring.mail.properties.mail.smtp.ssl.enable=true#开启ssl支持,不是所有邮箱都需要,根据需要填写
@Component
public class MyEmailUtils {
@Autowired
private JavaMailSender javaMailSender;
/**
* 普通邮件发送
* @param from 发送者
* @param to 接受人
* @param subject 邮件主题
* @param content 内容
*/
public Boolean myEmail(String from,String to,String subject,String content){
SimpleMailMessage message = new SimpleMailMessage();
//邮件发送人
message.setFrom(from);
//邮件接收人
message.setTo(to);
//邮件主题
message.setSubject(subject);
//邮件内容
message.setText(content);
//发送邮件
try {
javaMailSender.send(message);
return true;
}catch (Exception e){
return false;
}
}
/**
*
* @param from 发件人
* @param to 收件人
* @param subject 主题
* @param content 内容
* @param html 是否开启html支持
*/
public void myEmailHtml(String from,String to,String subject,String content,Boolean html){
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
//发件人
helper.setFrom(from);
//收件人
helper.setTo(to);
//主题
helper.setSubject(subject);
//内容,是否开启html支持
helper.setText(content,html);
//发送
javaMailSender.send(mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
System.out.println("发送失败");
}
}
}
public class MyConde {
private static final String SYMBOLS = "0123456789";
/**
* Math.random生成的是一般随机数,采用的是类似于统计学的随机数生成规则,其输出结果很容易预测,因此可能导致被攻击者击中。
* 而SecureRandom是真随机数,采用的是类似于密码学的随机数生成规则,其输出结果较难预测,若想要预防被攻击者攻击,最好做到使攻击者根本无法,或不可能鉴别生成的随机值和真正的随机值。
*/
private static final Random RANDOM = new SecureRandom();
public static String generateVerCode() {
char[] nonceChars = new char[6];
for (int i = 0; i < nonceChars.length; i++) {
nonceChars[i] = SYMBOLS.charAt(RANDOM.nextInt(nonceChars.length));
}
return new String(nonceChars);
}
}
@Autowired
private MyEmailUtils myEmailUtils;
public Boolean sendCode(String email,String code){
String text= "尊敬的用户,您好:\n本次请求的邮件验证码为 "+ code+ " ,本验证码5分钟内有效,请及时输入。(请勿泄露此验证码如非本人操作,请忽略该邮件。\n(这是一封自动发送的邮件,请不要直接回复)";
//
return myEmailUtils.myEmail("[email protected]", email, "预约挂号验证码", text);
}
验证码过期时间设置是使用Readis来实现的,每次生成验证码都将验证码存到Readis中并设置过期时间,在验证的地方从readis中取出来跟用户输入进行比较
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-bus-amqpartifactId>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
dependency>
dependencies>
@Configuration
public class MQConfig {
@Bean
public MessageConverter messageConverter(){
return new Jackson2JsonMessageConverter();
}
}
public class MqConst {
/**
* 订单
*/
//交换机名称
public static final String EXCHANGE_DIRECT_ORDER = "exchange.direct.order";
//路由键名称
public static final String ROUTING_ORDER = "order";
//队列
public static final String QUEUE_ORDER = "queue.order";
@Service
public class RabbitService {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 发送消息
* @param exchange 交换机
* @param routingKey 路由键
* @param message 消息
*/
public boolean sendMessage(String exchange, String routingKey, Object message) {
rabbitTemplate.convertAndSend(exchange, routingKey, message);
return true;
}
}
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>rabbit-utilsartifactId>
dependency>
#rabbitMQ
spring.rabbitmq.host=ip地址
spring.rabbitmq.port=端口号
spring.rabbitmq.username=用户名
spring.rabbitmq.password=密码
spring.rabbitmq.virtual-host=主机名
rabbitService.sendMessage(MqConst.EXCHANGE_DIRECT_ORDER, MqConst.ROUTING_ORDER, orderMqVo);
@Component
public class HospitalReceiver {
@Autowired
private RabbitService rabbitService;
@RabbitListener(bindings = @QueueBinding(
value = @Queue(value = MqConst.QUEUE_ORDER, durable = "true"),
exchange = @Exchange(value = MqConst.EXCHANGE_DIRECT_ORDER),
key = {MqConst.ROUTING_ORDER}
))
public void receiver(OrderMqVo orderMqVo, Message message, Channel channel) throws IOException {
//对订单进行处理
}
}
我做的项目还有几个技术每写出来比如说微信登录,微信支付和退款,阿里云的OSS存储等等,因为这些东西都比较固定,需要的时候直接翻阅官方文档即可,没有总结的必要,而且是中国企业开发的,文档也比较友好,因此就不再进行总结