首页 > 技术文章 > Java-个人杂记

torima 2021-08-17 15:35 原文

on duplicate key update

MYSQL特有语法,当INSERT已经存在的记录时,执行UPDATE

INSERT INTO `TABLE_NAME` (column1,column2,column3)
	VALUES(#{column1},#{column2},#{column3})
    ON DUPLICATE KEY UPDATE
    column1=values(column1),
    column2=values(column2),
    column3=values(column3)

@JsonProperty

常用于实体类的属性上,序列化的时候给属性重命名。大部分场景下Java对象的属性书写规范驼峰命名,但在数据库中一般为下划线

/**
 * Test实体类,对属性注释@JsonProperty
 */
@NoArgsConstructor
@AllArgsConstructor
@Data //getter、setter
@ToString
public class Test{
    @JsonProperty(value = "user_name")
    private String userName;
    @JsonProperty(value = "user_password")
    private String userPassword;
}

使用JSON.toJSONString()方法可以将Test对象序列化为JSON数据,JSON.parseObject()方法则是将JSON数据反序列化为Test对象

/**
 * Test对象转化为JSON字符串
 */
Test test = new Test("Xiaoming","123456");
String jsonStr = JSON.toJSONString(test);

/**
 * JSON字符串转化为Test对象,此处userName等价于user_name
 */
String jsonString = "{userName:'Xiaoming',userPassword:'123456'}";
//String jsonString = "{user_name:'Xiaoming',user_password:'123456'}";
Test test = JSON.paresObject(jsonString,Test.class);

#{} & ${}

  • #{ }是预编译处理,${ }是字符串替换。Mybatis在处理#{ }时,会将SQL中的#{ }替换为?号,调用PreparedStatement的set方法来赋值;在处理${}时,就是把${}替换成变量的值。使用#{}可以有效的防止SQL注入,提高系统安全性

  • 在Linux中的$用于充当占位符,就是被用来替换的;而SQL注入发生在编译的过程中,预编译的机制是在程序运行前对SQL语句进行数据库分析、编译和优化,对应的执行计划也会缓存下来并允许数据库以参数形式进行查询,运行时动态地把参数传给PreprareStatement,其后注入的参数不会再进行SQL编译

  • ${param}传递的参数会被当成SQL语句中的一部分,比如传递表名/字段名

    order by ${id}
    - 解析成的SQL为:
    order by id
    
  • #{param}传入的数据都当成一个字符串,会对传入的数据加双引号

    select * from table where name = #{name}
    - 解析成的SQL为:
    select * from table where name = "name"
    
  • ${param}和#{param}预处理的区别

    select * from user where name = #{name}
    select * from user where name = ${name}
    - name以zhangsan为例
    - #{}
    select * from user where name = ?
    - ${}
    select * from user where name = 'zhangsan'
    

浅拷贝和深拷贝

  • 浅拷贝和深拷贝的本质区别在于是否真正复制了一个对象实体,而不是对象的引用。(简单来说,假设B复制了A,修改A的时候,若B也发生了变化,则为浅拷贝;若B没有改变,则为深拷贝)

  • 浅拷贝(shallowCopy):相当于只是增加了一个指针指向了堆中已存在对象资源的内存地址

  • 深拷贝(deepCopy):增加了一个指针并且申请了一个新的内存空间,新指针指向新内存空间。在使用深拷贝的情况下,释放资源时不会出现浅拷贝释放同一个内存的错误

  • 浅复制:引用类型,仅仅是指针指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变

  • 深复制:在堆中开辟一块新的内存空间存放复制的对象

推荐阅读