学习笔记2

学习笔记2


文章目录


前言

自己的从零开始


1、Gradle_“你的主机中的软件中止了一个已建立的连接”

1.排查ADB或Gradle端口
2.构建前关闭热点(临时解决)
3.关闭Hyper-V并移除相关的适配器


2、MySQL的两种模糊查询

1.like与sql通配符 和 正则表达式模糊查询。

2.like与SQL ,必须使用like关键字

SQL的通配符如下:

% 百分号: 替代匹配任意字符

_ 下划线:仅替代一个字符

[字符列] :字符列中任何一个单一字符

[^字符列] 或者[!字符列]: 不在字符列中的任何一个单一字符

用法如下:

select 字段列表 from 表名 where 字段 like ‘Ne%’; 表示:查询以Ne开头的数据

select 字段列表 from 表名 where 字段 like ‘%Ne%’; 表示:查询含有Ne的数据

select 字段列表 from 表名 where 字段 like ‘L_ve’; 表示:查询含有 L+某一个字符+ve的数据

select 字段列表 from 表名 where 字段 like ’[abc]%’; 表示:查询a/b/c开头的数据
示例:

    <select id="select" resultType="com.system.dto.DTO">
        select  *
        from t1
        left join t2 on (t1.id = t2.id)
        <where>
            <if test="dto.queryValue!=null and dto.queryValue!=''">
                (
                <![CDATA[    t1.name like CONCAT('%','%${dto.queryValue}%','%') ESCAPE '/' ]]>
                <![CDATA[ or t2.account like CONCAT('%','%${dto.queryValue}%','%') ESCAPE '/' ]]>
                ****************************************
                )
            </if>
        </where>
    </select>

3.正则表达式模糊查询 必须使用regexp关键字

. , 尖角符  ^ , 美元符 $ ,  字符集 [ ] ,  逻辑或 |  , 星号 * , 加号 + , 问号 ?,大括号 { }

语法如下:

select 字段列表 from 表名 where 字段 [not] regexp [binary] ‘正则表达式’;

用法如下:

select 字段列表 from 表名 where 字段 regexp ‘j.’ ; 表示:查询 j 开头且为两个字符的数据

select 字段列表 from 表名 where 字段 regexp ‘158[0-9]{9}’; 表示:查询 158开头,11位的电话号码

正则表达式的模式匹配比like 运算符的模式匹配更加强大、灵活。


3、VSCode中使用vetur插件格式化vue文件时,js代码会自动加上双冒号和分号

1.全局安装prettier

npm install --global prettier

2.新建.prettierrc.json配置文件放在vue项目的root目录下(也就是和README.md文件同一目录)

3.配置.prettierrc.json文件如下

{
    "singleQuote":true,//使用单引号而不是双引号,true就是对
    "semi":false//在语句结尾处打印分号,false就是不打印
}

4、后端将前端传来的json数据转对象@requestBody注解作用

1.@requestBody注解常用来处理content-type不是默认的application/x-www-form-urlcoded编码的内容,比如说:application/json或者是application/xml等。一般情况下来说常用其来处理application/json类型。

2.通过@requestBody可以将请求体中的JSON字符串绑定到相应的bean上,当然,也可以将其分别绑定到对应的字符串上。

前端post请求代码:


    let instance = axios.create()
    instance.defaults.baseURL = 'http://localhost:8080'
    let data = { name: 'zhangsan1', age: '21' }
    instance
      .post('/student/insert', data)
      .then((res) => {
        console.log('res=>' + res)
      })
      .catch((res) => {
        console.log('res=>' + res)
      })

后台controller层代码:
默认是form格式,主要是使用注解接收json格式

    @RequestMapping("insert")
    public Student insert(@RequestBody Student student) {
        return this.studentService.insert(student);
    }

5、MultipartFile相关知识(上传,存储)

MultipartFile类的注释说明:

1.一种可以接收使用多种请求方式来进行上传文件的代表形式。
想用spring框架来实现项目中的文件上传功能,则MultipartFile可能是最合适的选择,而这里提到的多种请求方式则可以通俗理解为以表单的形式提交

2.这个文件内容可以存储到内存中或者存储在磁盘的临时位置上。

3.无论发生哪种情况,用户都可以自由地拷贝文件内容到session存储中,或者以一种永久存储的形式进行存储,如果有需要的话。

4.这种临时性的存储在请求结束之后将会被清除掉。

MultipartFile常用方法解析:

首先MultipartFile是一个接口,并继承自InputStreamSource,且在InputStreamSource接口中封装了getInputStream方法,该方法的返回类型为InputStream类型,这也就是为什么MultipartFile文件可以转换为输入流。通过以下代码即可将MultipartFile格式的文件转换为输入流。

multipartFile.getInputStream();

1.getName方法

getName方法获取的是前后端约定的传入文件的参数的名称

2.getOriginalFileName方法

getOriginalFileName方法获取的是文件的完整名称,包括文件名称+文件拓展名。

3.getContentType方法

getContentType方法获取的是文件的类型,注意是文件的类型,不是文件的拓展名。

4.isEmpty方法

isEmpty方法用来判断传入的文件是否为空,如果为空则表示没有传入任何文件。

5.getSize方法

getSize方法用来获取文件的大小,单位是字节。

6.getBytes方法

getBytes方法用来将文件转换成一种字节数组的方式进行传输,会抛出IOException异常。

7.getInputStream方法

getInputStream方法用来将文件转换成输入流的形式来传输文件,会抛出IOException异常。

8.transferTo方法

transferTo方法用来将接收文件传输到给定目标路径,会抛出IOException、IllegalStateException异常。

MultipartFile的一些使用技巧:

1.我们在使用MultipartFile作为参数传递的时候,可以将MultipartFile声明为一个数组,这样就能支持多文件传输,如果只需要传输一个文件,则去掉数组就好了。

2.可以根据MultipartFile的getSize方法来获取到传输文件的大小,这样就能限定传输过来的文件的大小了。

MultipartFile存本地文件代码:

    @RequestMapping("/fileUploadTest")
    public String fileUploadTest(@RequestParam("file") MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            return "false";
        }
        String fileName = file.getOriginalFilename();
        //第一次new File是用相对路径,需要获取到绝对路径再new一次File
        //path直接写自己本地存储路径 如 "D:\\fileSave" 
        File dest = new File(new File(path).getAbsolutePath() + "/" + fileName);
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            file.transferTo(dest); // 保存文件
            return "true";
        } catch (Exception e) {
            e.printStackTrace();
            return "false";
        }
    }


6、UUID生成代码

因为java中有UUID这个工具类,专门来生成UUID,在java.util包中,直接调用方法即可

简单的生成代码:把生成的UUID简单的处理了一下

import java.util.UUID;

public class Uuid {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            //注意replaceAll前面的是正则表达式
            String uuid = UUID.randomUUID().toString().replaceAll("-","");
            System.out.println(uuid);
//            System.out.println(uuid.length());
        }
    }
}

7、Mysql错误:check the manual that corresponds to your MySQL server version for the right syntax

错误信息为:

check the manual that corresponds to your MySQL server version for
the right syntax

解决方法有两个:

1.在数据库表冲突字段前后加 `符号(Tab键上面那个键),就不会再报语法错误了;

2.修改数据库表中冲突字段名称,修改为和 SQL语句关键字不冲突的其他名称。


8、表单验证rule和清除验证

1.验证rule

        <el-form
          :model="form"
          :rules="rules"
          ref="form"
        >
        **********************
        </el-form>
        **********************        

用validator可以写方法向后台验证

export default {
  data() {
      var valid = (rule, value, callback) => {
      valid().then((res) => {
        if (res.result === 0) {
          callback()
        } else {
          if (rule.field == '***') {
            callback(new Error('当前***已存在'))
          }
        }
      })
    }
    return {
      form: {
        id: '',
        name: '',
      },
      rules: {
        name: [{ required: true, message: '请输入名称', trigger: 'blur' }, 
        { required: true, validator: valid, trigger: 'blur' },]
      },
    }
}}

2.清除验证

有时候取消对话框或者表单但是上次的验证信息还在,提示报错。
把下面代码的form改成自己的就可以,要放在每次点击按钮的方法里。
每次打开都是清空状态。

this.$refs['form'].resetFields()

9、后端使用json格式将数据返回给前端

使用springmvc的@RestController注解

public class Result {
    private static final int SUCCESS = 200;
    private static final int FAILED = 500;
    private int code;
    private String message;
    private Object data;
     public Result(int code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
   public static Result ok(Object data) {
        return new Result(SUCCESS, "success", data);
    }

@RestController
@RequestMapping("/order")
public class SysOrderController {
@RequestMapping("/login")
public Result login() {
   Result result=new Result();
   result.setMessage("登录成功");
   result.setSuccess(true);
   Map<String,String>map=new hashMap<>();
   map.put("content","i am content")
        return Result.ok(map);
    }
}

@RestController是@ResponseBody和@Controller的组合注解

@Controller是用来响应页面的,如果是string类型的方法,则springmvc会跳转到相应的页面(视图)

@ResponseBody是用来响应数据的,如果是对象类型的方法,则springmvc会将结果对象转成json格式输出给前端

本例中使用的是@RestController注解,所以springmvc会将返回的对象Result自动转json返回给前端(底层默认是使用jsckson来实现数据格式转换的)

public Result add(@RequestBody WegoUser user){} @RequestBody是将前端传来的json数据转对象。默认不用加(springmvc会自动完成数据的封装)


10、webstrom,IDEA等 更改连接远程gitlab仓库的账号与密码

1.控制面板凭证管理器
2.找到Windows凭证
3.普通凭证找到git的账号密码修改,注意多项目的情况下 向下仔细查找。


11、el-tree树节点默认选择第一个

this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。

this.$nextTick(()=>{ });

****************************************************
                <el-tree
                    :data="tree1"
                    :props="props"
                    @node-click="tree1Click"
                    :expand-on-click-node="false"
                    :highlight-current="true"
                    ref="tree1"   //绑定该树
                    node-key="id"    //务必加id
                > </el-tree>

****************************************************
    //初始化查询
    async loadData() {
      await this.queryTree1().catch(error => {
      });
      await this.queryTree2().catch(error => {
      });
      //在取值渲染结束后用this.$nextTick操作
      //默认选中第一个
      this.$nextTick(()=>{
        let firstNode=this.tree1[0];//拿到第一个节点的数据
        this.$refs.tree1.setCurrentKey(firstNode.id);//设定当前选定状态
        this.tree1Click(firstNode);//触发第一个节点的相关操作
      });
    }
****************************************************    

12、IDEA中的搜索快捷键

Ctrl+N按名字搜索类: 全局搜索类(包括自己写的和依赖的);

Ctrl+Shift+N按文件名搜索文件: 与Ctrl + N 一样,只不过是匹配全局所有类型的文件;

Ctrl+H: 鼠标放在类上,查看类的继承关系;

Ctrl+Alt+B查看子类方法实现: 鼠标放在类上,ctrl+alt+b;

Alt+F7: 查找类或方法在哪被使用;

Ctrl+F/Ctrl+Shift+F: 按照文本的内容查找,不加 shift 代表搜索本类或文件中,加上 shift 代表全局搜索;

Shift+Shift: 搜索idea中的任何东西;


13、element-ui 表格中 el-table-column 添加 icon

<el-table :data="tableData">
    <el-table-column prop="type" label="类型"></el-table-column>
    <el-table-column prop="name" label="名称"></el-table-column>
    <el-table-column prop="intro" label="简介"></el-table-column>
    <el-table-column prop="address" label="地址"></el-table-column>
    <el-table-column prop="phone"label="电话">
        <template slot-scope="scope">
            <i class="el-icon-share"></i>
            {{scope.row.phone}}
        </template>
    </el-table-column>
</el-table>

14、mySQL批量替换语句

update 表名 set 指定字段 =replace(指定字段,‘要替换的字符串’,‘想要的字符串’) where 条件

例如:

update level set remark =replace(remark,'1''2')

多个语句可以直接写个.sql 文件。
分行写命令,命令之间加分号,导入数据库运行。
先txt文本写好,改sql 后缀即可。


15、FreeMarker的IF语句

if 指令

<#if item.score?? >
  <#if item.score == -1>
    <w:t>不适用</w:t>
    <#elseif item.score == 1>
    <w:t>符合</w:t>
    <#elseif item.score == 0.5>
    <w:t>部分符合</w:t>
    <#elseif item.score == 0>
    <w:t>不符合</w:t>
    </#if>
<#else>
  <w:t>${(item.score)!}</w:t>
</#if>


16、JavaScript Array map() 、filter() 处理用法

    //生成标准的版本数组
    generateData(pid){
      return this.profession.filter(p=>p.pId==pid).map(m=>{
        return {
          id: m.id,
          name: m.standardVersion,
        }
      })
    },

17、json.stringify()与json.parse()的区别

它们的作用是相对的,
JSON.stringify()将对象a变成了字符串c,
JSON.parse()将字符串c还原成对象a。

let arr = [1,2,3];
JSON.stringify(arr);//'[1,2,3]'
typeof JSON.stringify(arr);//string

let string = '[1,2,3]';
console.log(JSON.parse(string))//[1,2,3]
console.log(typeof JSON.parse(string))//object

JSON.parse()需要注意一点,将JSON字符串转换成对象,字符串必须符合JSON格式,即键值都必须使用双引号包裹:

let a = '["1","2"]';
let b = "['1','2']";
console.log(JSON.parse(a));// Array [1,2]
console.log(JSON.parse(b));// 报错

二、JSON.stringify()的几种妙用
1.判断数组是否包含某对象,或者判断对象是否相等。

//判断数组是否包含某对象
let data = [
    {name:'echo'},
    {name:'听风是风'},
    {name:'天子笑'},
    ],
    val = {name:'天子笑'};
JSON.stringify(data).indexOf(JSON.stringify(val)) !== -1;//true

//判断两数组/对象是否相等
let a = [1,2,3],
    b = [1,2,3];
JSON.stringify(a) === JSON.stringify(b);//true

2.让localStorage/sessionStorage可以存储对象。

localStorage/sessionStorage默认只能存储字符串,而实际开发中,我们往往需要存储的数据多为对象类型,那么这里我们就可以在存储时利用json.stringify()将对象转为字符串,而在取缓存时,只需配合json.parse()转回对象即可。

//存
function setLocalStorage(key,val){
    window.localStorage.setItem(key,JSON.stringify(val));
};
//取
function getLocalStorage(key){
    let val = JSON.parse(window.localStorage.getItem(key));
    return val;
};
//测试
setLocalStorage('demo',[1,2,3]);
let  a = getLocalStorage('demo');//[1,2,3]

3.实现对象深拷贝

实际开发中,如果怕影响原数据,我们常深拷贝出一份数据做任意操作,其实使用JSON.stringify()与JSON.parse()来实现深拷贝是很不错的选择。

//深拷贝
function deepClone(data) {
    let _data = JSON.stringify(data),
        dataClone = JSON.parse(_data);
    return dataClone;
};
//测试
let arr = [1,2,3],
    _arr = deepClone(arr);
arr[0] = 2;
console.log(arr,_arr)//[2,2,3]  [1,2,3]

三、JSON.stringify()与toString()的区别

这两者虽然都可以将目标值转为字符串,但本质上还是有区别的,比如

let arr = [1,2,3];
JSON.stringify(arr);//'[1,2,3]'
arr.toString();//1,2,3

其次,JSON.stringify()的受众更多是对象,而toString()虽然可以将数组转为字符串,但并不能对{name:‘天子笑’}这类对象实现你想要的操作,它的受众更多是数字。


18、union和union all的用法

作用

将两个select的结果作为一个整体显示出来。

满足条件:
1、两个select查询的列的数量必须相同;
2、务必查询语句的列顺序要相同;
3、每个列的数据类型需要相似;

区别

union all是将两个select语句的结果求并集。 
union是将union all的结果下再去除重复数据

语法

select * from user1    |       select * from user1
	union 			   |		union all
select * from user2    |       select * from user2

sql语句示例

      SELECT
        cesc.standard_id,
        cesc.extendclass_id,
        cesc.profession_id,
        se.p_id AS securityclass_id  
      FROM
        tool_check_standard_extendclass_securityclass cesc
      LEFT JOIN tool_check_securityclass se ON cesc.securityclass_id = se.id
      WHERE
        cesc.securityclass_id LIKE '%$%'
        
      UNION ALL
      
        SELECT
          cesc.standard_id,
          cesc.extendclass_id,
          cesc.securityclass_id,
          cesc.profession_id    
        FROM
          tool_check_standard_extendclass_securityclass cesc
        WHERE
          cesc.securityclass_id NOT LIKE '%$%'

19、js根据json数据中的某一个属性来给数据分组的方法

let arr = [
{"Group":1,"Groupheader":"质量管理","Leftimg":"","Left":"","Min":"","Right":"","Rightimg":""},
{"Group":1,"Groupheader":"","Leftimg":"","Left":"","Min":"质量巡检","Right":"","Rightimg":""},
{"Group":2,"Groupheader":"设备管理","Leftimg":"","Left":"","Min":"","Right":"","Rightimg":""},
{"Group":2,"Groupheader":"","Leftimg":"","Left":"","Min":"设备专业点检","Right":"","Rightimg":""},
{"Group":2,"Groupheader":"","Leftimg":"","Left":"","Min":"设备日检","Right":"","Rightimg":""},
{"Group":2,"Groupheader":"","Leftimg":"","Left":"","Min":"设备周检","Right":"","Rightimg":""},
{"Group":2,"Groupheader":"","Leftimg":"","Left":"","Min":"设备月检","Right":"","Rightimg":""}];
  
let map = {},
 dest = [];
for(let i = 0; i < arr.length; i++){
 let ai = arr[i];
 if(!map[ai.Group]){
  dest.push({
   Group: ai.Group,
   data: [ai]
  });
  map[ai.Group] = ai;
 }else{
  for(let j = 0; j < dest.length; j++){
   let dj = dest[j];
   if(dj.Group == ai.Group){
    dj.data.push(ai);
    break;
   }
  }
 }
}
console.log(JSON.stringify(dest));

20、js循环遍历数组(对象)

for…of循环

因为是es6引入到新特性中的,借鉴c ++,java,c#和python语言,引入for…of循环,作为遍历所有数据结构的统一方法。

var arr = ['a', 'b', 'c', 'd'];
for (let a of arr) {
console.log(a); // a b c d
}

21、IDEA插件 Free Mybatis plugin

free-idea-mybatis是一款增强idea对mybatis支持的插件,主要功能如下:
1.生成POJO类,mapper,xml文件
2.快速从xml跳转到mapper及从mapper跳转xml
3.mybatis自动补全及语法错误提示


22、@GetMapping和@PostMapping注解的区别

1 @RequestMappingMap

使用@RequestMappingComments 将 URL Map 到整个类或特定的处理程序方法上。 类级别的 Comments将特定的请求路径(或路径模式)Map 到表单控制器上,其他方法级别的 Comments 使特定的 HTTP 方法请求方法(“ GET”,“POST”等)的主 Map 范围变窄。 @RequestMapping默认情况下 Map 了所有 HTTP 方法。使用@RequestMapping(method=GET)或@GetMapping缩小 Map 范围。

@RequestMapping有8个属性。

value:指定请求的实际地址。
method:指定请求的method类型(GET,POST,PUT,DELETE)等。
consumes:指定处理请求的提交内容类型(Context-Type)。
produces:指定返回的内容类型,还可以设置返回值的字符编码。
params:指定request中必须包含某些参数值,才让该方法处理。

2 由@RequestMapping 变体组成

@GetMapping

用于将HTTPGET请求映射到特定处理程序方法的注释。具体来说,@GetMapping是一个作为快捷方式的组合注释@RequestMapping(method = RequestMethod.GET)。

@PostMapping

@PostMapping是一个组合注解,是@RequestMapping(method = RequestMethod.POST)的缩写用于将HTTP POST请求映射到特定处理程序方法的注释。

类似的还有
@PutMapping
@DeleteMapping
@PatchMapping

@PostMapping和@GetMapping都可以用@RequestMapping代替,如果怕在映射的时候出错,可以统一写@RequestMapping,当然这样写的话也有缺点,还是建议分开写。

但是请求方式需要服务端保持一致,客户端是POST,服务端一定需要是POST。


23、关于spring boot无法自动注入bean问题

使用@Autowired注解无法自动注入bean 在所引用的类添加上@Repository注解


24、关于spring-boot-starter-parent版本找不到问题

在 maven settings.xml 中修改阿里云镜像

<mirror>
    <id>alimaven</id>
    <name>aliyun maven</name>
    <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
    <mirrorOf>central</mirrorOf>       
</mirror>

然后IDEA 清除缓存/重启


25、 el-table 表格行内数据应用

<el-table-column
        label=""
        prop=""
      />    
 <template slot-scope="{ row }">在此处引用各种组件--row.数据</template> 
</el-table-column>

示例:

   <el-table v-loading="loading" :data="planList">
      <el-table-column
        label="工作内容"
        align="center"
        prop="workContent"
      />
      <el-table-column
        label="起始时间"
        align="center"
        prop="startDate"
        width="180"
      >
        <template slot-scope="{ row }">
          <el-date-picker
            v-model="row.startDate"
            type="date"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
            placeholder="选择起始日期"
            @change="change"
          >
          </el-date-picker>
        </template>
      </el-table-column>
      <el-table-column
        label="完成时间"
        align="center"
        prop="endDate"
        width="180"
      >
        <template slot-scope="{ row }">
          <el-date-picker
            v-model="row.endDate"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
            type="date"
            placeholder="选择完成日期"
            @change="change"
          >
          </el-date-picker>
        </template>
      </el-table-column>
      <el-table-column
        label="人员安排"
        align="center"
        prop="executor"
        width="180"
      >
        <template slot-scope="{ row }">
          <el-select
            v-model="row.executor"
            placeholder="请选择人员"
            filterable
            clearable
            :style="{ width: '100%' }"
          ></el-select>
        </template>
      </el-table-column>
      <el-table-column label="里程碑成果" align="center" prop="achievements" />
    </el-table>

   planList: [
        {
          workContent: "sss",
          startDate: "2021-4-27",
          endDate: "2021-6-12",
          executor: "当前",
          achievements: "检测报告",
        },
        {
          workContent: "sssss",
          startDate: "2021-4-27",
          endDate: "2021-6-12",
          executor: "当前",
          achievements: "检测报告",
        },
      ],

26、element 表单一行多列

    <el-form
      ref="planForm"
      :model="planForm"
      :rules="rules"
      size="medium"
      label-width="100px"
    >
      <el-row>
        <el-col span="5">
          <el-form-item label="项目名称" prop="planName" :inline="true">
            <span>{{ planForm.planName }} </span>
          </el-form-item>
        </el-col>
        <el-col span="5">
          <el-form-item label="检验编号" prop="examineNum" :inline="true">
            <span>{{ planForm.examineNum }} </span>
          </el-form-item>
        </el-col>
        <el-col span="5">
          <el-form-item label="样品名称" prop="sampleName" :inline="true">
            <span>{{ planForm.sampleName }} </span>
          </el-form-item>
        </el-col>
      </el-row>
      </el-form>

27、element 表单里镶嵌表格 某一行数据用法

scope.$index 非常关键 指表格数据的第几个
还可以验证表格

<template slot-scope="scope">
 <el-form-item
  :prop="'planList.' + scope.$index + '.planFormulateStart'"
  :rules="formContentRules.startDate"
  >
 </el-form-item>
</template>
        <el-table-column
          label="起始时间"
          align="center"
          prop="planFormulateStart"
          width="280"
        >
          <template slot-scope="scope">
            <el-form-item
              :prop="'planList.' + scope.$index + '.planFormulateStart'"
              :rules="formContentRules.startDate"
            >
              <el-date-picker
                v-model="scope.row.planFormulateStart"
                type="date"
                placeholder="选择起始日期"
                format="yyyy-MM-dd"
                value-format="yyyy-MM-dd"
                @change="change(scope.row)"
                :picker-options="pickerOptions"
              >
              </el-date-picker>
            </el-form-item>
          </template>
        </el-table-column>

      formContentRules: {
        startDate: [
          { required: true, message: "请选择起始日期", trigger: "change" },
        ],
      },

28、后台不同模块的实例类引用

在要引用模块的 pom.xml 里 配置依赖

<dependencies>
       <dependency>
            <groupId>com.ruoyi</groupId>
            <artifactId>ruoyi-system</artifactId>
        </dependency>
</dependencies>

29、ON DUPLICATE KEY UPDATE 主键唯一,插入或更新

ON DUPLICATE KEY UPDATE 前 就是插入语句,若主键已经存在就执行更新。
注意:主键也要写进去插入语句,否则无法判断。
ON DUPLICATE KEY UPDATE 后 就是更新语句,不用跟插入语句那样一一对应

    <insert id="insertPlan" parameterType="domain.NmpaProjectPlan" useGeneratedKeys="false" keyProperty="projectId">
        insert into project_plan
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="projectId != null">project_id,</if>
            <if test="planFormulateStart != null">plan_formulate_start,</if>
            <if test="planFormulateFinish != null">plan_formulate_finish,</if>
            <if test="planCreateDate != null">plan_create_date,</if>
            <if test="planFormulateUser != null">plan_formulate_user,</if>
            <if test="createBy != null">create_by,</if>
            <if test="createTime != null">create_time,</if>
            <if test="delFlag != null">del_flag,</if>
         </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="projectId != null">#{projectId},</if>
            <if test="planFormulateStart != null">#{planFormulateStart},</if>
            <if test="planFormulateFinish != null">#{planFormulateFinish},</if>
            <if test="planCreateDate != null">#{planCreateDate},</if>
            <if test="planFormulateUser != null">#{planFormulateUser},</if>
            <if test="createBy != null">#{createBy},</if>
            <if test="createTime != null">#{createTime},</if>
            <if test="delFlag != null">#{delFlag},</if>
         </trim>
        ON DUPLICATE KEY UPDATE
        <trim suffixOverrides=",">
            <if test="planFormulateStart != null">plan_formulate_start = #{planFormulateStart},</if>
            <if test="planFormulateFinish != null">plan_formulate_finish = #{planFormulateFinish},</if>
            <if test="planCreateDate != null">plan_create_date = #{planCreateDate},</if>
            <if test="planFormulateUser != null">plan_formulate_user = #{planFormulateUser},</if>
            <if test="updateBy != null">update_by = #{updateBy},</if>
            <if test="updateTime != null">update_time = #{updateTime},</if>
            <if test="delFlag != null">del_flag = #{delFlag},</if>
        </trim>
    </insert>

30、界面内CSS写法

在所在标签上 class=“自己命名”

!important 提高优先级

.自己命名{
  .el-date-editor {
    width: 180px !important;
  }
  .el-input {
    width: 180px !important;
  }
}

31、前端多个不同类型数据传后端Map接收

后台转换:

字符串:JSON.toJSONString(map.get("字符串名"));
数组: (List) map.get("数组名");
自定义类:JSON.parseObject(JSON.toJSONString(map.get("传过来的数据list")), 自定义类.class);

前端:


     let planMembers = [];
     let planList = {};
     let params = {
        planMembers: planMembers,
        planList: planList,
      };
      save().then((res)=>{
          //代码处理
      })

后端: ProjectPlan为自定义类

 @PostMapping("/save")
    public AjaxResult save(@RequestBody Map map) {
    //map数据转成自定义类 ProjectPlan
        ProjectPlan plan = JSON.parseObject(JSON.toJSONString(map.get("planList")), ProjectPlan.class);
        List<Map> list = (List<Map>) map.get("planMembers");
        List<ProjectPlan> ProjectPlans = new ArrayList<>();
        for (Map map1 : list) {
           ProjectPlan ProjectPlan = JSON.parseObject(JSON.toJSONString(map1), ProjectPlan.class);
            ProjectPlans.add(ProjectPlan);
        }
       System.out.println(plan);
       System.out.println(ProjectPlans);
    }

32、IDEA 导入依赖还报错缺少jar包

重新加载一下Maven项目
在这里插入图片描述


33、字符串语句关键词替换

替换关键词 例如空格’ '替换成/

//    StringBuffer buffer = new StringBuffer();
//    buffer.append(nmpaProject.getProjectPath());

    public String replaceSpace(StringBuffer str) {
        StringBuffer str1 = new StringBuffer();
        char[] arr  = str.toString().toCharArray();
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == ' '){
                str1.append("/");
            }
            else {
                str1.append(arr[i]);
            }
        }
        return str1.toString();
    }

34、mkdir()和mkdirs()区别

mkdirs()可以建立多级文件夹, mkdir()只会建立一级的文件夹,

new File("/tmp/one/two/three").mkdirs();
  执行后, 会建立tmp/one/two/three四级目录

new File("/tmp/one/two/three").mkdir();
  则不会建立任何目录, 因为找不到/tmp/one/two目录, 结果返回false


35、IDEA设置添加作者时间信息

在设置里找到,如图所示:

/**
*@author: 某某某
*@Date: ${DATE} ${TIME}
*/

在这里插入图片描述


36、




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值