27事务管理AOP

news2024/11/17 12:57:57

一、MySQL事务回顾

image-20230519095555441

二、Spring事务管理

Spring框架的第一大核心:IOC控制反转

image-20230519093354025 image-20230519095638521

在DeptServiceImpl下删除部门方法下新加一个删除员工信息的操作,注意:此时的id是部门id。

image-20230519094945355 image-20230519095242773

1、问题分析

image-20230519095758677

2、@Transactional-Spring事务管理

image-20230519100017409

一般是在Service实现类的方法上加Transactional注解


执行多次数据访问的增删改操作上需要用到事务

image-20230519101345091 image-20230519101246113 image-20230519101218784 image-20230519101511274 image-20230519102942049

三、Spring事务进阶

image-20230519103046587

1、rollbackFor

image-20230519103807812

Int i = 1/0 是属于运行时异常

image-20230519104208589 image-20230519110308309

这是service层,需要继续往上抛异常


image-20230519110226786 image-20230519110436516

默认情况下只有运行时异常才会进行事务回滚

2、propagation

image-20230519133216508 image-20230519133416156 image-20230519133437828 image-20230519133449823

因为我们需要解散部门时,无论成功还是失败,都要记录操作日志,所以需要用到@Transaction的REQUIRES_NEW的属性,来新建一个事务

image-20230519133808397

pojo/DeptLog

package com.itheima.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class DeptLog {
    private Integer id;
    private LocalDateTime createTime;
    private String description;
}

DeptServiceImple

package com.itheima.service.impl;

import com.itheima.mapper.DeptLogMapper;
import com.itheima.mapper.DeptMapper;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Dept;
import com.itheima.pojo.DeptLog;
import com.itheima.service.DeptLogService;
import com.itheima.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.logging.LogManager;

@Service
public class DeptServiceImpl implements DeptService {
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private EmpMapper empMapper;//  删除部门id的同时,需要删除与部门id关联的员工信息
    @Autowired
    private DeptLogService deptLogService;//  添加日志对象注入

//    @Autowired
//    private DeptLogMapper deptLogMapper;

    /*1、查询操作* */
    //        实现方法
    public List<Dept> list(){
        List<Dept> deptList = deptMapper.select();
        return deptList;
    }
    /*2、删除指定id
    * */

    @Transactional(rollbackFor = Exception.class)  //  交给了Spring进行事务管理,将所有异常进行事务处理
    @Override
    public void deleteById(Integer id) throws Exception{
        try {
            deptMapper.deleteById(id);  //  删除部门id

            int i = 1/0;
//            if (true){throw new Exception("出错了...");}
            empMapper.deleteById(id);    //  删除员工信息
        } finally {//        记录日志描述
            DeptLog deptLog = new DeptLog();
            deptLog.setCreateTime(LocalDateTime.now());
            deptLog.setDescription("执行了解散部门的操作,此次解散的部门id是"+id);
            deptLogService.insert(deptLog);

/**
 *可以不用写DeptLogService和DeptServiceImpl,直接写一个DeptLogMapper然后交给IOC控制器,再在
 * 这个实现类中注入DeptLogMapper的对象直接调用insert方法,在方法前加入
 * @Transactional(propagation = Propagation.REQUIRES_NEW)
 */
//            deptLogMapper.insert(deptLog);

        }
    }
    /*3、新增部门*/
    public void add(Dept dept){
        dept.setCreateTime(LocalDateTime.now());
        dept.setUpdateTime(LocalDateTime.now());
        deptMapper.insert(dept);
    }

    /*根据ID查询*/
    public Dept selectById(Integer id){
        Dept dept = deptMapper.selectById(id);
        return dept;
    }
    @Override
    /*更新部门名称*/
    public void update(Dept dept) {
        dept.setUpdateTime(LocalDateTime.now());
        dept.setCreateTime(LocalDateTime.now());
        deptMapper.update(dept);
    }
}

DpetLogService

package com.itheima.service;

import com.itheima.pojo.DeptLog;

public interface DeptLogService {
    void insert(DeptLog deptLog);
}

DeptLogServiceImpl

package com.itheima.service.impl;

import com.itheima.mapper.DeptLogMapper;
import com.itheima.pojo.DeptLog;
import com.itheima.service.DeptLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
public class DeptLogServiceImpl implements DeptLogService {

    @Autowired
    private DeptLogMapper deptLogMapper;

//    开启一个新事务
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    @Override
    public void insert(DeptLog deptLog) {
        deptLogMapper.insert(deptLog);
    }
}

DeptLogMapper

package com.itheima.mapper;

import com.itheima.pojo.DeptLog;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Mapper
public interface DeptLogMapper {
    @Insert("insert into dept_log(create_time, description) VALUES (#{createTime},#{description})")
//    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void insert(DeptLog deptLog);
}

四、AOP基础-Spring框架的第二大核心

AOP概述

image-20230519144922918 image-20230519144936888

AOP快速入门

image-20230519160123162
package com.itheima.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Slf4j
@Component  // 交给IOC容器
@Aspect     // 表示这个是AOP类
public class TimeAspect {
//  当前共性功能应该加在哪些方法上
    @Around("execution(* com.itheima.service.*.*(..))") //切入点表达式
    public void recordTime(ProceedingJoinPoint joinPoint) throws Throwable {
//        1、获取方法运行开始时间
        long begin = System.currentTimeMillis();
//        2、运行原始方法,o是原始方法的返回值
        Object o = joinPoint.proceed();
//        3、获取方法结束运行结束时间
        long end = System.currentTimeMillis();
//        计算方法耗时
//        joinPoint.getSignature():原始方法的签名
        log.info(joinPoint.getSignature()+"方法耗时:{}ms",end-begin);
    }
}
image-20230519160259797

image-20230519160606985

image-20230519161148430

小结

image-20230519161318405

五、AOP基础-核心概念

AOP核心概念

image-20230519164857827

AOP执行流程

image-20230519164715406

小结

连接点JoinPoint能够被AOP所控制的方法
切入点PointCut实际被AOP控制的方法,通过切入点表达式
通知Advice将所有共性功能封装起来的方法
切面Aspect描述通知与切入点之间的对应关系
目标对象Target通知所对应的对象
image-20230519170101230

六、AOP进阶

image-20230519171259826

1、通知类型

image-20230519174120073 image-20230519174551031

切入点表达式抽取

image-20230519174957352 image-20230519175305641

小结

image-20230519175400903

2、通知顺序

image-20230523105728939 image-20230523110339906

3、切入点表达式

execution

image-20230523110701548 image-20230523113303585 image-20230523151557536 image-20230523151743153

MyAspect6.java

package com.itheima.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Component
@Slf4j
@Aspect
public class MyAspect6 {
//    @Pointcut("execution(public void com.itheima.service.impl.DeptServiceImpl.delete(java.lang.Integer))")
//    @Pointcut("execution(void com.itheima.service.DeptService.delete(java.lang.Integer))")//基于接口描述
//    @Pointcut("execution(void delete(java.lang.Integer))")包名.类名不建议省略,匹配的范围过大,影响匹配的效率
//    @Pointcut("execution(* com.itheima.service.DeptService.*(*))")//匹配返回值为任意,DeptService接口下所有方法任意类型的一个参数
//    @Pointcut("execution(* com..DeptService.get(*))")//匹配返回值为任意,com包下任意子包中DeptService接口/类下get方法,为任意类型的一个参数
    @Pointcut("execution(* com.itheima.service.DeptService.delete(java.lang.Integer)) ||"+
    "execution(* com.itheima.service.DeptService.list())")
  	//匹配前面一个或者后面任意一个
    public void pt(){}

    @Before("pt()")
    public void before(){
        System.out.println("before ...6");
    }
}

@annotation

image-20230523153020619

MyLog

package com.itheima.aop;

import lombok.extern.slf4j.Slf4j;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)//该注解表示注解的生命周期
@Target(ElementType.METHOD)//表示该注解作用在哪一部分
public @interface MyLog {
}

MyAspect7

package com.itheima.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@Aspect
public class MyAspect7 {
    @Pointcut("@annotation(com.itheima.aop.MyLog)")
    public void pc(){}

    @Before("pc()")
    public void func(){
        log.info("MyAspect7...");
    }
}
image-20230523160655953

只需要在想要匹配的方法上加@MyLog注解就可以调用通知方法

小结

image-20230523161211924

4、连接点

image-20230523162227036

MyAspect8

package com.itheima.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
@Slf4j
@Aspect
public class MyAspect8 {
    @Pointcut("execution(* com.itheima.service.DeptService.*(..))")
    public void pt(){}

    @Before("pt()")
    public void before(JoinPoint joinPoint){
        log.info("before....");
    }

    @Around("pt()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("MyAspect8 around before...");

//        1、获取目标类名
        String className = joinPoint.getTarget().getClass().getName();
        log.info("目标类名:{}",className);

//        2、获取目标方法签名
        Signature signature = joinPoint.getSignature();
        log.info("目标方法签名:{}",signature);

//        3、获取目标方法名
        String signatureName = joinPoint.getSignature().getName();
        log.info("目标方法名:{}",signatureName);

//        4、获取目标方法运行参数
        Object[] args = joinPoint.getArgs();
        String arg = Arrays.toString(args);
        log.info("目标方法参数:{}",arg);


//        5、执行原始方法,获取返回值
        Object result = joinPoint.proceed();
        log.info("目标方法的返回值:{}",result);

        log.info("MyAspect8 after ...");
        return result;
    }

    @After("pt()")
    public void after(){
        log.info("after...");
    }
}

测试类

package com.itheima;

import com.itheima.service.DeptService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringbootAopQuickstart1ApplicationTests {
    @Autowired
    DeptService deptService;
    @Test
    public void test1(){
        deptService.delete(10);
    }
    @Test
    public void test2(){
        deptService.list();
    }
}

执行delete之后

image-20230523165601716

只有环绕通知才可以执行原始方法

前置通知在原始方法执行前运行,后置通知在原始方法执行后运行

七、AOP案例

image-20230523171728414

image-20230523172429155

1、准备工作

<!--AOP依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
    <version>2.7.1</version>
</dependency>
-- AOP案例
-- 操作日志表
create table operate_log(
                            id int unsigned primary key auto_increment comment 'ID',
                            operate_user int unsigned comment '操作人ID',
                            operate_time datetime comment '操作时间',
                            class_name varchar(100) comment '操作的类名',
                            method_name varchar(100) comment '操作的方法名',
                            method_params varchar(1000) comment '方法参数',
                            return_value varchar(2000) comment '返回值',
                            cost_time bigint comment '方法执行耗时, 单位:ms'
) comment '操作日志表';

sql表格对应的实体类

package com.itheima.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class OperateLog {
    private Integer id; //ID
    private Integer operateUser; //操作人ID
    private LocalDateTime operateTime; //操作时间
    private String className; //操作类名
    private String methodName; //操作方法名
    private String methodParams; //操作方法参数
    private String returnValue; //操作方法返回值
    private Long costTime; //操作耗时
}

2、编码

image-20230524154418945

LogAspect.java

package com.itheima.aop;

import com.alibaba.fastjson.JSONObject;
import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import com.itheima.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

@Component
@Slf4j
@Aspect //切面类
public class LogAspect {
    @Autowired//用于获取jwt令牌
    private HttpServletRequest httpServletRequest;
    @Autowired
    private OperateLogMapper operateLogMapper;

    @Around("@annotation(com.itheima.anno.Log)")//切点表达式
    public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {
//        1、获取操作人ID,当前登录员工id,这一步需要用到jwt令牌,在Header中
        String jwt = httpServletRequest.getHeader("token");
//        解析jwt令牌
        Claims claims = JwtUtils.parseJwt(jwt);
        Integer operateUser  = (Integer) claims.get("id");

//        2、操作时间
        LocalDateTime operateTime = LocalDateTime.now();

//        3、操作类名
        String className = joinPoint.getTarget().getClass().getName();

//        4、操作方法名
        String methodName = joinPoint.getSignature().getName();

//        5、操作方法参数
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);

//         获取方法开始时间
        long begin = System.currentTimeMillis();
//        6、操作方法返回值,转换为json格式的字符串保存起来
        Object result = joinPoint.proceed();
        String returnValue = JSONObject.toJSONString(result);
//        获取结束时间
        long end = System.currentTimeMillis();

//        7、操作耗时
        long costTime = end - begin;

//        将日志内容插入到表中
        OperateLog operateLog = new OperateLog(null,operateUser,operateTime,className,methodName,methodParams,returnValue,costTime);
        operateLogMapper.insert(operateLog);

        log.info("AOP操作日志:{}",operateLog);
        return result;//返回的是执行方法的返回值
    }
}

OperateLogMapper

package com.itheima.mapper;

import com.itheima.pojo.OperateLog;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface OperateLogMapper {
    @Insert("insert into operate_log (operate_user, operate_time, class_name, method_name, method_params, return_value, cost_time) " +
            "values (#{operateUser}, #{operateTime}, #{className}, #{methodName}, #{methodParams}, #{returnValue}, #{costTime});")
    public void insert(OperateLog operateLog);

}

注意

image-20230524155552227

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/563679.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

想用Python做副业?看这一篇就够了

大家好&#xff0c;我是耿直。 随着人工智能、大数据、物联网的广泛应用&#xff0c;与之紧密关联的Python技术开始受到人们的极大关注。各行业对Python技术服务的需求量呈指数级暴增&#xff0c;尤以爬虫技术服务为甚&#xff0c;供不应求早已成为常态。 而近两年受到各种不…

Springboot +spring security,实现RememberMe和实现原理分析

一.简介 我们在登录网站的时候&#xff0c;除了让你输入用户名和密码&#xff0c;还会有个勾选框&#xff1a; 记住我。 比如下面这个截图&#xff1a; Spring Security 也提供了这个功能&#xff0c;今天来实践下。 二.创建项目 如何创建一个SpringSecurity项目&#xff0…

【精】MySQL5.7没有row_number()函数如何组内排序和求分组topN

当我们遇到一些需求&#xff0c;比如组内分组排序&#xff0c;分组topN等&#xff0c;很容易想到用row_number()函数 ​在MySQL8.0版本中支持row_number函数&#xff0c;本文不做讨论&#xff0c;如果是MySQL5.7版本&#xff0c;要怎么写SQL呢&#xff1f; 测试表&#xff1a;…

Three.js教程:点、线、网格模型介绍

推荐&#xff1a;将 NSDT场景编辑器 加入你的3D工具链 其他系列工具&#xff1a; NSDT简石数字孪生 点、线、网格模型介绍 经过前面几章学习相信你对点模型Points、线模型Line、网格模型Mesh已经有了大致了解&#xff0c;本节课就对点、线、网格模型模型进行简单总结。 点模型…

阿里大佬随手甩出一份覆盖全网的微服务架构笔记,让我涨薪60%

在这个凡事皆互联的时代&#xff0c;越来越多的人和物成为互联网上的节点&#xff0c;不断扩充着互联网这张大网的边界。节点即价值&#xff0c;更多的节点意味着更大的价值。 微服务在这个互联网时代依旧是最火热的技术之一&#xff0c;在当下互联网企业不懂微服务是不行的&a…

软件测试人员如何为项目的质量保障兜底?看完你就明白了...

上线前层层保障 01文档管理 关键词&#xff1a;需求文档、设计文档、测试文档 1.需求和设计产出方为产品、开发&#xff0c;测试需要做好流程监督&#xff0c;这里重点说下测试文档。 2.测试文档&#xff0c;从业务领域来说&#xff0c;一般有测试计划、测试用例、业务总结文…

环信新鲜出炉的 React-UIKIT 库初体验,瞬间实现即时通讯功能!

一、前言 为了加快即时通讯需求产品开发速度&#xff0c;将更多的时间放在关系核心业务逻辑的处理上&#xff0c;环信正式推出可扩展&#xff0c;易使用的 React 版本的 UIKIT 库 此 UIKit 库 是基于 环信 Web SDK 开发的的 UI 组件库&#xff0c;它提供了常用的 UI 组件、包含…

【尚好房项目实战】:第一章项目架构介绍

编译软件&#xff1a;IntelliJ IDEA 2019.2.4 x64 操作系统&#xff1a;win10 x64 位 家庭版 Maven版本&#xff1a;apache-maven-3.6.3 Mybatis版本&#xff1a;3.5.6 spring版本&#xff1a;5.3.1 文章目录 前言尚好房项目实战系列文章目录一、项目介绍二、核心技术点三、项目…

次氯酸消毒剂制备中的全氟醚橡胶密封耐腐蚀电动阀门解决方案

摘要&#xff1a;次氯酸作为是一种新型消毒剂&#xff0c;近年来广泛应用于医疗卫生机构、公共卫生场所和家庭的一般物体表面、医疗器械、医疗废物等。由于次氯酸的酸性和强氧化性&#xff0c;使得次氯酸生产制备过程中会给流量调节阀门带来腐蚀并影响寿命和控制精度&#xff0…

电影票房之数据分析(Hive)--第1关

电影票房之数据分析&#xff08;Hive&#xff09; 第1关&#xff1a;统计2020年上映的电影中&#xff0c;当前总票房最高的10部电影 本关任务 基于EduCoder平台提供的初始数据集&#xff0c;统计 2020 年上映的电影中&#xff0c;当前总票房最高的 10 部电影。 编程要求 本…

论文阅读:GLOBAL PROTOTYPE ENCODING FOR INCREMENTALVIDEO HIGHLIGHTS DETECTION

摘要&#xff1a; 视频亮点检测 (VHD) 是计算机视觉中的一个活跃研究领域&#xff0c;旨在在给定原始视频输入的情况下定位最吸引用户的片段。然而&#xff0c;大多数 VHD 方法都是基于封闭世界假设&#xff0c;即预先定义固定数量的高亮类别&#xff0c;并且所有训练数据都是…

IDEA刷新太慢,非得强制reload from disk

IDEA刷新太慢&#xff0c;每次 reload from disk才能最新代码咋办。 比如我用 IDEA开发代码&#xff0c;但我用github desktop 等第三方客户端软件提交代码的&#xff0c;但是 IDEA显示还是未提交的代码。此时&#xff0c;必须强制reload from disk才跟得上磁盘改变。 安装这个…

校园能耗监测管理系统是什么?有什么作用?

随着全球气候变化和环境问题的日益严重&#xff0c;校园能耗监测管理系统成为了可持续发展的重要手段。校园能耗监测管理系统可以对校园的能源使用情况进行实时监测、统计和分析&#xff0c;进而优化能源使用&#xff0c;降低能源消耗和运营成本&#xff0c;为绿色校园建设提供…

单链表相交编程题——java实现

题目&#xff1a; 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xf…

抖音账号矩阵系统源码开发功能模块分析

抖音账号矩阵系统源码是一款基于PHP语言开发的混剪工具&#xff0c;可以方便地将多个抖音账号的视频素材进行混剪&#xff0c;生成一个新的视频。该工具使用了多线程、协程和异步编程等技术&#xff0c;可以显著提高处理速度&#xff0c;并且支持自动去重和自动合成背景音乐等功…

报名开源之夏,与 StarRocks 一起畅游代码的海洋!

开源之夏是由中科院软件所“开源软件供应链点亮计划”发起并长期支持的一项暑期开源活动&#xff0c;旨在鼓励在校学生积极参与开源软件的开发维护&#xff0c;培养和发掘更多优秀的开发者&#xff0c;促进优秀开源软件社区的蓬勃发展&#xff0c;助力开源软件供应链建设。 202…

YOLOV5使用(一)

yolov5的工程使用(以人员检测为案例) 使用ubuntu为案例 docker run --gpus all -it -p 6007:6006 -p 8889:8888 --name my_torch -v $(pwd):/app easonbob/my_torch1-pytorch:22.03-py3-yolov5-6.0使用端口映射功能也就是说打开jupyter lab的指令是 http://localhost:8889/l…

flutter系列之:做一个下载按钮的动画

文章目录 简介定义下载的状态定义DownloadButton的属性让DownloadButton的属性可以动态变化定义downloadController定义DownloadButton的细节总结 简介 我们在app的开发过程中经常会用到一些表示进度类的动画效果&#xff0c;比如一个下载按钮&#xff0c;我们希望按钮能够动态…

AI歌手:新晋挑战者还是未来主流的替代者?

AI歌手&#xff1a;新晋挑战者还是未来主流的替代者&#xff1f; 近日&#xff0c;一款名为“AI孙燕姿”的AI歌手火遍全网&#xff0c;其翻唱的林俊杰的《她说》、周杰伦的《爱在西元前》、赵雷的《成都》等歌曲让网友纷纷表示&#xff1a;“听了一晚上&#xff0c;出不去了。…

《信息技术时代》期刊简介及投稿要求

《信息技术时代》&#xff08;半月刊&#xff09;本刊是由国家新闻总署批准&#xff0c;深圳湾科技发展有限公司主管主办的信息类期刊&#xff0c;国内统一刊号CN&#xff1a;44-1536/TN&#xff0c;国际标准刊号ISSN&#xff1a;1671-153x。本刊旨在为全集团的信息工作者提供交…