主要内容:
- Fastdfs怎么和业务集成
- 垂直分表?字段冗余?id一对一设计
文章目录
一.搭建Fastdfs微服务
1.项目结构搭建
hrm-fastdfs-parent
hrm-fastdfs-feign
hrm-fastdfs-server-2040
2.修改hrm-fastdfs-server-2040
2.1.注册到Eureka
2.2.集成Config客户端
2.3.集成Swagger
2.4.zuul配置fastdfs服务的路由
2.5.zuul整合fastdfs的swagger
2.6.集成Fastdfs实现文件上传
2.6.1.导入依赖
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.29-SNAPSHOT</version>
</dependency>
2.6.2.创建配置文件fast_client.conf
#指向tracker_server所在的服务器的ip
tracker_server = fastdfs所在的服务器ip:22122
2.6.3.FastDfsApiOpr工具
package cn.myllxy.util;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
public class FastDfsApiOpr {
public static String CONF_FILENAME = FastDfsApiOpr.class.getResource("/fdfs_client.conf").getFile();
/**
* 上传文件
*
* @param file
* @param extName
* @return
*/
public static String upload(byte[] file, String extName) {
try {
ClientGlobal.init(CONF_FILENAME);
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getTrackerServer();
StorageServer storageServer = null;
StorageClient storageClient = new StorageClient(trackerServer, storageServer);
String fileIds[] = storageClient.upload_file(file, extName, null);
System.out.println(fileIds.length);
System.out.println("组名:" + fileIds[0]);
System.out.println("路径: " + fileIds[1]);
return "/" + fileIds[0] + "/" + fileIds[1];
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
2.6.4.编写文件上传Controller层方法
@RestController
@RequestMapping("/fastdfs")
public class FastdfsController {
@PostMapping("/upload")
public AjaxResult upload(MultipartFile file) {
try {
String extName = FilenameUtils.getExtension(file.getOriginalFilename());
String filePath = FastDfsApiOpr.upload(file.getBytes(), extName);
return AjaxResult.me().setResultObj(filePath);
} catch (IOException e) {
e.printStackTrace();
return AjaxResult.me().setSuccess(false).setMessage("文件上传失败");
}
}
}
<!-- 更方便地获取文件后缀 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
2.6.5.前段对接上传
<el-upload
class="upload-demo"
action="http://localhost:1020/fastdfs/fastdfs/upload"
:on-preview="handlePreview"
:on-remove="handleRemove"
:on-success="handleSuccess"
:file-list="fileList"
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
<div class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
二.课程管理
1.RedisFeign集成Hystrix
这次使用的fallbackFactory相较于fallback能够返回程序运行异常:
@FeignClient(value = "redis-server", fallbackFactory = MyFallBackFactory.class)
public interface RedisFeignClient {
@PostMapping("/redis/set")
AjaxResult set(@RequestParam("key") String key, @RequestParam("value") String value);
@PostMapping("/redis/get/{key}")
AjaxResult get(@PathVariable("key") String key);
}
@Component
public class MyFallBackFactory implements FallbackFactory<RedisFeignClient> {
@Override
public RedisFeignClient create(Throwable throwable) {
return new RedisFeignClient() {
@Override
public AjaxResult set(String key, String value) {
return AjaxResult.me().setSuccess(false).setMessage("Redis发生错误:" + throwable.getMessage());
}
@Override
public AjaxResult get(String key) {
return AjaxResult.me().setSuccess(false).setMessage("Redis发生错误:" + throwable.getMessage());
}
};
}
}
使用如下:
List<CourseType> courseTypes = null;
//当调用get方法时会去redis中查对应key的数据,查不到就返回AjaxResult.me().setSuccess(false).setMessage("Redis发生错误:" + throwable.getMessage());是带有异常的
AjaxResult ajaxResult = redisFeignClient.get(RedisKeyConstant.CPURSE_TYPE);
if (ajaxResult.isSuccess() && null != ajaxResult.getResultObj()) {
String jsonFromRedis = ajaxResult.getResultObj().toString();
courseTypes = JSON.parseArray(jsonFromRedis, CourseType.class);
} else {
courseTypes = resetRedis();
}
2.添加等级名字
列表中有个字段需要跨数据库查询,为了提升查询效率,我们将其写在当前表中进行查询------------字段冗余
3.完成课程添加
需要注意的是课程详情id根据课程id来(在保存课程的时候将课程id赋值给课程详情id)