Daily-Blog项目后台日志(下)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: Daily-Blog项目后台日志(下)

菜单列表


需求 :


展示菜单列表,不需要进行分页。可以正对菜单名做模糊查询,也可以根据菜单状态进行查询。菜单要按照父菜单id 和 OrderNum进行排序


接口

image-20230329110738310.png


实现


//todo 菜单列表
@GetMapping("/list")
public ResponseResult getAll(String status,String menuName){
    return menuService.getAll(status,menuName);
}
/*
展示菜单列表,不需要进行分页。可以正对菜单名做模糊查询,也可以根据菜单状态进行查询。
菜单要按照父菜单id 和 OrderNum进行排序
 */
@Override
public ResponseResult getAll(String status, String menuName) {
    //1. 按要求查询出所有的菜单
    LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Menu::getDelFlag,SystemConstants.NOT_DELETE);
    wrapper.like(Objects.nonNull(menuName),Menu::getMenuName,menuName);
    wrapper.like(Objects.nonNull(status),Menu::getStatus,status);
    //2. 按照父菜单 和 orderNum进行排序
    wrapper.orderByAsc(Menu::getParentId);
    wrapper.orderByAsc(Menu::getOrderNum);
    List<Menu> list = list(wrapper);
    List<MenuVo> menuVos = BeanCopyUtils.copyBeanList(list, MenuVo.class);
    //3. 封装为Vo,然后在放到集合中返回
    return ResponseResult.okResult(menuVos);
}


新增菜单


接口

注意: 这里的接口路径应该是:system/menuimage-20230329114721619.png


实现


//todo 新增菜单
@PostMapping
public ResponseResult addMenu(@RequestBody Menu menu){
    return menuService.addMenu(menu);
}


//todo 新增菜单 或者按钮
@Override
public ResponseResult addMenu(Menu menu) {
    if(ObjectUtils.isEmpty(menu.getIcon())){
       return ResponseResult.errorResult(AppHttpCodeEnum.ICON_NOT_NULL);
    }
    if(ObjectUtils.isEmpty(menu.getMenuName())){
        return ResponseResult.errorResult(AppHttpCodeEnum.MENU_NAME_NOT_NULL);
    }
    if(ObjectUtils.isEmpty(menu.getPath())){
        return ResponseResult.errorResult(AppHttpCodeEnum.PATH_NOT_NULL);
    }
    save(menu);
    return ResponseResult.okResult();
}


修改菜单


需求:


不能将自己的上级菜单设置自己


1 系统管理 0 1 system 1 M 0 0 system 0 2021-11-12 10:46:19 0 系统管理目录 0


接口

查询对应的菜单信息image-20230329121149241.png


更新菜单接口

image-20230329121228032.png


实现

查询所要修改的信息



         


//todo 根据id查询对应信息
@Override
public ResponseResult selectById(Long id) {
    Menu menu = getById(id);
    MenuVo menuVo = BeanCopyUtils.copyBean(menu, MenuVo.class);
    return ResponseResult.okResult(menuVo);
}

修改,要求 不能使父菜单设置成为自己本身


@PutMapping
public ResponseResult updateMenu(@RequestBody Menu menu){
    return menuService.updateMenu(menu);
}


//todo 更新菜单
//不能让菜单的父菜单 == 菜单本身
@Override
public ResponseResult updateMenu(Menu menu) {
    System.out.println(menu);
    if(menu.getParentId().equals(menu.getId())){
        return ResponseResult.errorResult(AppHttpCodeEnum.PARENT_NOT_SELF);
    }
    LambdaQueryWrapper<Menu> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Menu::getId,menu.getId());
    remove(wrapper);
    save(menu);
    return ResponseResult.okResult();
}


删除菜单


要求 : 不能删除有子菜单的,逻辑删除



@DeleteMapping("/{id}")
public ResponseResult deleteById(@PathVariable Long id){
    return menuService.deleteById(id);
}
//todo 根据id删除菜单
//不能删除有子菜单的父菜单
@Override
public ResponseResult deleteById(Long id) {
    //查询是否有父菜单
    Menu menu = getById(id);
    List<Menu> list = list();
    for(Menu children: list) {
        if (children.getParentId().equals(id)) {
            System.out.println("不能删除!");
            return ResponseResult.errorResult(AppHttpCodeEnum.CHILDREN_NOT_NULL);
        }
    }
    UpdateWrapper<Menu> wrapper= new UpdateWrapper<>();
    wrapper.eq("id",id);
    wrapper.set("del_flag",SystemConstants.DELETE);
    update(wrapper);
    return ResponseResult.okResult();
}


角色列表


接口


image-20230330191331750.png


实现


//todo 获取角色列表
@GetMapping("/list")
public ResponseResult getList(int pageNum, int pageSize,String roleName,String status){
    return roleService.getList(pageNum,pageSize,roleName,status);
}


* 获取所有的角色, 需要可以根据角色名 and 状态 模糊查询
 * @param pageNum 页数
 * @param pageSize 每页大小
 * @param roleName 角色名
 * @param status 状态
 * @return 封装返回
 */
@Override
public ResponseResult getList(int pageNum, int pageSize, String roleName, String status) {
    //1. 先查询出未删除的
    LambdaQueryWrapper<Role> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(Role::getDelFlag, SystemConstants.NOT_DELETE);
    //2. 按照求排序
    wrapper.orderByAsc(Role::getRoleSort);
    //3. 进行模糊查询
    wrapper.like(Objects.nonNull(roleName),Role::getRoleName,roleName);
    wrapper.like(Objects.nonNull(status),Role::getStatus,status);
    //4. 分页
    Page<Role> page = new Page<>(pageNum,pageSize);
    page(page,wrapper);
    //5. 封装返回
    List<Role> records = page.getRecords();
    List<RoleVo> roleVos = BeanCopyUtils.copyBeanList(records, RoleVo.class);
    PageVo pageVos = new PageVo(roleVos,page.getTotal());
    return ResponseResult.okResult(pageVos);
}


改变角色状态


接口

image-20230330194015196.png


实现


/**
 * 这里注意, 前端接口中的请求体 中定义的id 不是和数据库中对应的 而使roleId
 * @param roleDto
 * @return
 */
@PutMapping("/changeStatus")
public ResponseResult changeStatus(@RequestBody RoleDto roleDto){
    System.out.println("----------"+ roleDto);
    return roleService.changeStatus(roleDto);
}


/**
 * 改变角色状态
 * @param roleDto 封装角色id 和状态
 * @return
 */
@Override
public ResponseResult changeStatus(RoleDto roleDto) {
    UpdateWrapper<Role> wrapper = new UpdateWrapper<>();
    wrapper.eq("id",roleDto.getRoleId());
    wrapper.set("status",roleDto.getStatus());
    update(wrapper);
    Role byId = getById(roleDto.getRoleId());
    return ResponseResult.okResult();
}


新增角色

接口

image-20230330200602548.png


响应格式:


image-20230330200905395.png


实现新增接口

image-20230330191955499.png


实现


/**
 * 获取菜单下拉树列表
 */
@GetMapping("/treeselect")
public ResponseResult treeselect() {
    //复用之前的selectMenuList方法。方法需要参数,参数可以用来进行条件查询,而这个方法不需要条件,所以直接new Menu()传入
    List<Menu> menus = menuService.selectMenuList(new Menu());
    List<MenuTreeVo> options =  SystemConverter.buildMenuSelectTree(menus);
    return ResponseResult.okResult(options);
}

获取子菜单


public class SystemConverter {
    private SystemConverter() {
    }
    public static List<MenuTreeVo> buildMenuSelectTree(List<Menu> menus) {
        List<MenuTreeVo> MenuTreeVos = menus.stream()
                .map(m -> new MenuTreeVo(null, m.getId(), m.getMenuName(), m.getParentId()))
                .collect(Collectors.toList());
        List<MenuTreeVo> options = MenuTreeVos.stream()
                .filter(o -> o.getParentId().equals(0L))
                .map(o -> o.setChildren(getChildList(MenuTreeVos, o)))
                .collect(Collectors.toList());
        return options;
    }
    /**
     * 得到子节点列表
     */
    private static List<MenuTreeVo> getChildList(List<MenuTreeVo> list, MenuTreeVo option) {
        List<MenuTreeVo> options = list.stream()
                .filter(o -> Objects.equals(o.getParentId(), option.getId()))
                .map(o -> o.setChildren(getChildList(list, o)))
                .collect(Collectors.toList());
        return options;
    }
}

添加角色


@PostMapping
public ResponseResult AddRole(@RequestBody RoleDto roleDto){
    return roleService.AddRole(roleDto);
}
@Override
public ResponseResult AddRole(RoleDto roleDto) {
    Role role = BeanCopyUtils.copyBean(roleDto, Role.class);
    save(role);
    return ResponseResult.okResult();
}


修改角色信息


接口

信息回显

image-20230402121643054.png


加载角色菜单树请求

image-20230402122531724.png


进行修改

image-20230402125750495.png


实现

实现信息回显

/**
 * 根据id获取需要修改的角色信息
 * @param id 角色id
 * @return
 */
@Override
public ResponseResult getRoleById(Long id) {
    Role role = getById(id);
    RoleVo roleVo = BeanCopyUtils.copyBean(role, RoleVo.class);
    return ResponseResult.okResult(roleVo);
}

实现权限树的回显


/**
 * 回显对应id的角色的权限树
 * @param id
 * @return
 */
@GetMapping("/roleMenuTreeselect/{id}")
public ResponseResult roleMenuTreeSelect(@PathVariable Long id){
    //1. 先查寻对应角色的权限id集合, 然后,将id集合一一对应查询出对应的权限集合
    List<Menu> menus = menuService.selectMenuList(new Menu());
    LambdaQueryWrapper<RoleMenu> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(RoleMenu::getRoleId,id);
    List<RoleMenu> list = roleMenuService.list(wrapper);    //对应的id集合
    List<Long> ids = new ArrayList<>();
    for(RoleMenu menu : list){
        Long menuId = menu.getMenuId();
        ids.add(menuId);
    }
    List<MenuTreeVo> menuTreeVos = SystemConverter.buildMenuSelectTree(menus);
    RoleMenuTreeSelectVo vo = new RoleMenuTreeSelectVo(ids, menuTreeVos);
    return ResponseResult.okResult(vo);
}

实现信息修改


/**
 * 进行修改 ,注意关联对应的菜单树信息
 * @param role 传入对应的信息
 * @return
 */
@Override
public ResponseResult updateRole(Role role) {
    updateById(role);
    //删除之前的菜单关系
    LambdaQueryWrapper<RoleMenu> roleMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
    roleMenuLambdaQueryWrapper.eq(RoleMenu::getRoleId,role.getId());
    roleMenuService.remove(roleMenuLambdaQueryWrapper);
    //重新建立菜单关系
    //还需要将角色和对应的菜单权限信息添加
    Long[] menuIds = role.getMenuIds();
    for(Long id : menuIds){
        roleMenuService.save(new RoleMenu(role.getId(),id));
    }
    return ResponseResult.okResult();
}


删除角色


接口&实现


@DeleteMapping("/{id}")
public ResponseResult deleteRole(@PathVariable Long id){
    return roleService.deleteRole(id);
}


/**
 * 根据id删除角色信息, 注意还要删除对应的角色关联的菜单
 * 还有就是逻辑删除
 * @param id 角色id
 * @return
 */
@Override
public ResponseResult deleteRole(Long id) {
    UpdateWrapper<Role> wrapper = new UpdateWrapper<>();
    wrapper.eq("id",id);
    wrapper.set("del_flag",SystemConstants.DELETE);
    update(wrapper);
    //删除对应的关联信息
    LambdaQueryWrapper<RoleMenu> roleMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();
    roleMenuLambdaQueryWrapper.eq(RoleMenu::getRoleId,id);
    roleMenuService.remove(roleMenuLambdaQueryWrapper);
    return ResponseResult.okResult();
}


用户列表


接口

image-20230402133128250.png


image-20230402133613323.png


实现


//todo 后台获取用户列表
@GetMapping("/list")
public ResponseResult list(int pageNum ,int pageSize,String userName,String status,String phonenumber){
    return userService.listAll(pageNum,pageSize,userName,status,phonenumber);
}
JAVA


/**
 * 进行用户列表查询
 * 要求: 1. 能够进行分页展示 2. 可以通过用户名 进行模糊查询 3. 可以通过手机号、状态进行查询
 * @param pageNum 当前页
 * @param pageSize 分页大小
 * @param userName 用户名
 * @param phonenumber 手机号
 * @return
 */
@Override
public ResponseResult listAll(int pageNum, int pageSize, String userName, String status,String phonenumber) {
    // 可以通过用户名 进行模糊查询
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    //可以通过手机号、状态进行查询
    wrapper.like(StringUtils.hasText(userName),User::getUserName,userName);
    wrapper.eq(StringUtils.hasText(status),User::getStatus,status);
    wrapper.eq(StringUtils.hasText(phonenumber),User::getPhonenumber,phonenumber);
    // 能够进行分页展示
    Page<User> page = new Page<>(pageNum,pageSize);
    page(page,wrapper);
    List<User> records = page.getRecords();
    List<UserVo> userVos = BeanCopyUtils.copyBeanList(records, UserVo.class);
    PageVo pageVo = new PageVo(userVos,page.getTotal());
    return ResponseResult.okResult(pageVo);
}


新增用户


需求分析


1.首先要返回所有的角色列表(状态正常,没有删除的 )

2.用户输入密码存储时需要进行加密存储

3.相关信息不能为空

4.相关用户名、手机号、邮箱…不能相同


接口

查询角色列表

image-20230402135245059.png


添加用户


image-20230402140509829.png

实现


/**
 * 新增用户
 1. 首先要返回所有的角色列表(状态正常,没有删除的    )
 2. 用户输入密码存储时需要进行加密存储
 3. 相关信息不能为空
 4. 相关用户名、手机号、邮箱...不能相同
 * @param userDto
 * @return
 */
@Override
@Transactional
public ResponseResult addUser(User userDto) {
    //对数据进行非空判断 要求用户名 密码 等都不为空
    if(!StringUtils.hasText(userDto.getUserName())){
        ResponseResult.errorResult(AppHttpCodeEnum.USERNAME_NOT_NULL);
    }
    if(!StringUtils.hasText(userDto.getPassword())){
        ResponseResult.errorResult(AppHttpCodeEnum.PASSWORD_NOT_NULL);
    }
    if( !StringUtils.hasText(userDto.getEmail())){
        ResponseResult.errorResult(AppHttpCodeEnum.EMAIL_NOT_NULL);
    }
    if( !StringUtils.hasText(userDto.getNickName())){
        ResponseResult.errorResult(AppHttpCodeEnum.NICKNAME_EXIST);
    }
    //判断数据库中是否存在用户
    if(usernameExist(userDto.getUserName())){
        //用户已经存在
        ResponseResult.errorResult(USERNAME_EXIST);
    }
    if(nickNameExist(userDto.getNickName())){
        //昵称存在
        ResponseResult.errorResult(NICKNAME_EXIST);
    }
    if(phoneNumberExist(userDto.getPhonenumber())){
        //昵称存在
        ResponseResult.errorResult(PHONENUMBER_EXIST);
    }
    if(EmailExist(userDto.getEmail())){
        //昵称存在
        ResponseResult.errorResult(EMAIL_EXIST);
    }
    //密码加密处理
    System.out.println("-------------" + userDto.getPassword());
    userDto.setPassword(passwordEncoder.encode(userDto.getPassword())); //设置加密之后的密码
    save(userDto);  
    //添加对应的角色用户信息关系
    List<Long> roleIds = userDto.getRoleIds();
    for (Long roleId : roleIds){
        userRoleService.save(new UserRole(userDto.getId(),roleId));
    }
    return ResponseResult.okResult();
}


修改用户


接口

回显信息

image-20230402150040611.png


更新

image-20230402150017375.png


实现

获取信息


/**
 * 回显要删除的用户信息
 * 需要回显用户关联的角色状态
 * @param id 用户id
 * @return
 */
@Override
public ResponseResult getUserById(Long id) {
    //1. 查询用户信息回显
    User user = getById(id);
    //2. 查询角色信息
    List<Role> roles = roleService.list();
    //3. 查询用户角色管理信息
    LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(UserRole::getUserId,id);
    List<UserRole> list = userRoleService.list(wrapper);
    List<Long> ids = new ArrayList<>();
    for(UserRole userRole : list){
        ids.add(userRole.getRoleId());
    }
    UserUpdateDataVo vo = new UserUpdateDataVo(ids, roles, user);
    return ResponseResult.okResult(vo);
}

进行修改


/**
 * 更新用户信息
 * @param user 用户信息
 * @return
 */
@Override
@Transactional
public ResponseResult updateUser(User user) {
    updateById(user);
    LambdaQueryWrapper<UserRole> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(UserRole::getUserId,user.getId());
    userRoleService.remove(wrapper);
    //添加对应的角色用户信息关系
    List<Long> roleIds = user.getRoleIds();
    for (Long roleId : roleIds){
        userRoleService.save(new UserRole(user.getId(),roleId));
    }
    return ResponseResult.okResult();
}


删除用户


接口&实现


image-20230402144510809.png


/**
 * 逻辑删除用户
 * @param id
 * @return
 */
@Override
public ResponseResult deleteUser(Long id) {
    UpdateWrapper<User> wrapper = new UpdateWrapper<>();
    wrapper.eq("id",id);
    wrapper.set("del_flag", SystemConstants.DELETE);
    update(wrapper);
    return ResponseResult.okResult();
}


分类查询


接口


image-20230402162209400.png

实现


//todo 获取所有分类,并分页展示
@GetMapping("list")
public ResponseResult listAll(int pageNum ,int pageSize,CategoryVo categoryVo){
    return categoryService.listAllPage(pageNum,pageSize,categoryVo);
}


/**
 * 分页导出所有分类
 * @param pageNum 页码
 * @param pageSize 分页大小
 * @return
 */
@Override
public ResponseResult listAllPage(int pageNum, int pageSize,CategoryVo categoryVo) {
    //先获取所有可用的分类
    LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
    //进行模糊查询
    queryWrapper.like(Objects.nonNull(categoryVo.getName()),Category::getName,categoryVo.getName());
    queryWrapper.like(Objects.nonNull(categoryVo.getStatus()),Category::getStatus,categoryVo.getStatus());
    //判断是否可用
    queryWrapper.eq(Category::getStatus, SystemConstants.CATEGORY_STATUS);//没有被禁用的
    queryWrapper.eq(Category::getDelFlag,SystemConstants.CATEGORY_NOTDEL);//没有被删除的
    //进行分页处理
    Page<Category> page = new Page<>(pageNum,pageSize);
    page(page,queryWrapper);
    //按照响应格式返回
    List<Category> records = page.getRecords();
    List<CategoryVo> list = BeanCopyUtils.copyBeanList(records, CategoryVo.class);
    PageVo pageVo = new PageVo(list,page.getTotal());
    return ResponseResult.okResult(pageVo);
}


新增分类


接口

image-20230402162430663.png


实现


/**
 * 新增分类
 * @param categoryVo
 * @return
 */
@Override
public ResponseResult addCategory(CategoryVo categoryVo) {
    Category category = BeanCopyUtils.copyBean(categoryVo, Category.class);
    save(category);
    return ResponseResult.okResult();
}


修改分类


接口

image-20230402162935277.png


修改



image-20230402163345281.png实现


/**
 * 根据id获取分类信息
 */
@Override
public ResponseResult getCategoryById(Long id) {
    Category byId = getById(id);
    CategoryVo categoryVo = BeanCopyUtils.copyBean(byId, CategoryVo.class);
    return ResponseResult.okResult(categoryVo);
}
/**
 * 更新分类
 * @param categoryVo
 * @return
 */
@Override
@Transactional
public ResponseResult updateCategory(CategoryVo categoryVo) {
    Category category = BeanCopyUtils.copyBean(categoryVo, Category.class);
    updateById(category);
    return ResponseResult.okResult();
}


删除分类


接口& 实现


/**
 * 逻辑删除分类
 * @param id
 * @return
 */
@Override
public ResponseResult deleteCategory(Long id) {
    UpdateWrapper<Category> wrapper = new UpdateWrapper<>();
    wrapper.eq("id",id);
    wrapper.set("del_flag",SystemConstants.DELETE);
    update(wrapper);
    return ResponseResult.okResult();
}


友链列表


接口

image-20230402163637266.png



@GetMapping("/list")
public ResponseResult getAllLink(int pageNum ,int pageSize ,String name ,String status){
    return linkService.getAll(pageNum,pageSize,name,status);
}


@Override
public ResponseResult getAll(int pageNum, int pageSize, String name, String status) {
    LambdaQueryWrapper<Link> wrapper = new LambdaQueryWrapper<>();
    wrapper.like(StringUtils.hasText(name),Link::getName,name);
    wrapper.eq(StringUtils.hasText(status),Link::getStatus,status);
    Page<Link> page = new Page<>(pageNum,pageSize);
    page(page,wrapper);
    PageVo pageVo = new PageVo(page.getRecords(),page.getTotal());
    return ResponseResult.okResult(pageVo);
}


新增友链


接口

image-20230402164805566.png


@PostMapping
public ResponseResult addLink(@RequestBody Link link){
    return ResponseResult.okResult(linkService.save(link));
}

修改友链

@GetMapping("/{id}")
public ResponseResult getLinkById(@PathVariable Long id){
    Link byId = linkService.getById(id);
    return ResponseResult.okResult(byId);
}
@PutMapping
@Transactional
public ResponseResult updateLink(@RequestBody Link link){
    linkService.updateById(link);
    return ResponseResult.okResult();
}


删除友链


@DeleteMapping("/{id}")
public ResponseResult deleteLink(@PathVariable Long id){
    UpdateWrapper<Link> wrapper = new UpdateWrapper<>();
    wrapper.eq("id",id);
    wrapper.set("del_flag", SystemConstants.DELETE);
    linkService.update(wrapper);
    return ResponseResult.okResult();
}
相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
7天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
25 1
|
3月前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
125 1
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
|
3月前
|
开发框架 .NET Docker
【Azure 应用服务】App Service .NET Core项目在Program.cs中自定义添加的logger.LogInformation,部署到App Service上后日志不显示Log Stream中的问题
【Azure 应用服务】App Service .NET Core项目在Program.cs中自定义添加的logger.LogInformation,部署到App Service上后日志不显示Log Stream中的问题
|
3月前
|
XML Java Maven
logback在springBoot项目中的使用 springboot中使用日志进行持久化保存日志信息
这篇文章详细介绍了如何在Spring Boot项目中使用logback进行日志记录,包括Maven依赖配置、logback配置文件的编写,以及实现的日志持久化和控制台输出效果。
logback在springBoot项目中的使用 springboot中使用日志进行持久化保存日志信息
|
3月前
|
数据可视化 Java API
如何在项目中快速引入Logback日志并搭配ELK使用
如何在项目中快速引入Logback日志并搭配ELK使用
|
3月前
|
开发框架 .NET API
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
150 0
|
3月前
|
监控 程序员 数据库
分享一个 .NET Core Console 项目中应用 NLog 写日志的详细例子
分享一个 .NET Core Console 项目中应用 NLog 写日志的详细例子
|
2天前
|
XML 安全 Java
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
64 30
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
|
29天前
|
XML JSON Java
Logback 与 log4j2 性能对比:谁才是日志框架的性能王者?
【10月更文挑战第5天】在Java开发中,日志框架是不可或缺的工具,它们帮助我们记录系统运行时的信息、警告和错误,对于开发人员来说至关重要。在众多日志框架中,Logback和log4j2以其卓越的性能和丰富的功能脱颖而出,成为开发者们的首选。本文将深入探讨Logback与log4j2在性能方面的对比,通过详细的分析和实例,帮助大家理解两者之间的性能差异,以便在实际项目中做出更明智的选择。
176 3
|
29天前
|
存储 缓存 关系型数据库
MySQL事务日志-Redo Log工作原理分析
事务的隔离性和原子性分别通过锁和事务日志实现,而持久性则依赖于事务日志中的`Redo Log`。在MySQL中,`Redo Log`确保已提交事务的数据能持久保存,即使系统崩溃也能通过重做日志恢复数据。其工作原理是记录数据在内存中的更改,待事务提交时写入磁盘。此外,`Redo Log`采用简单的物理日志格式和高效的顺序IO,确保快速提交。通过不同的落盘策略,可在性能和安全性之间做出权衡。
1607 14