Day2 今日总结
遇到的问题
1.泛型类不够了解定义和使用
泛型是一个未知的数据类型,当我们不确定使用什么数据类型的时候,可以使用泛型
泛型可以接收任意的数据类型,可以使用Integer,String,Student…
创建对象的时候确定泛型的数据类型
定义泛型类
public class BaseID<T> {
//主键
protected T id;
public T getId() {
return id;
}
public void setId(T id) {
this.id = id;
}
}
id可能为long也可能为String
使用泛型类
//不写泛型默认为object类型
BaseID baseId1=new BaseID<>();
//使用Long数据类型
BaseID<Long> baseId2=new Base<>();
//使用String数据类型
BaseID<String> baseId3=new Base<>();
2.@JsonFormat的详细用法
注解@JsonFormat主要是后台到前台的时间格式的转换
注解@DateTimeFormat主要是前后到后台的时间格式的转换
@DateTimeFormat 和 @JsonFormat 可将日期信息在JSON格式和java.util.Date对象之间转换
@DateTimeFormat (pattern = “yyyy-MM-dd HH:mm:ss”)
前台写"yyyy-MM-dd HH:mm:ss"的JSON格式传入后台(即发送post请求),后台转化为时间格式
@JsonFormat(shape=JsonFormat.Shape.STRING, pattern=“yyyy_MM-dd HH:mm:ss”)
后台将LocalDateTime时间格式传递到前台转化为"yyyy_MM-dd HH:mm:ss"时间格式
主要记住JSONFormat
3.枚举类型的用法没记牢
public enum Season{
STRING,
SUMMER,
AUTUMM,
WINTER,
}
1.SPRING的类型就是枚举Season本身
Season=Season.SPRING;
2.枚举类型转化为字符串,调用name()
String seasonName = Season.SPRING.name();
3.字符串转化为枚举类型,用Season.valueOf()
Season s = Season.valueOf(seasonName);
主要记住这三个语法
使用枚举的好处:
1.让数值看的更直观,圈定在一个范围当中。
2.不会笔误。一旦定义好,引用的时候不会写错
3.不会有歧义,避免理解不一致
4.连接池的作用
- 基本原理:在内部对象池中,维护一定数量的数据库连接,并对外暴露数据库连接的获取和返回方法。
如外部使用者可通过getConnection方法获取数据库连接,使用完毕后再通过releaseConnection方法将连接返回,注意此时的连接并没有关闭,而是由连接池管理器回收,并为下一次使用做好准备。
2.作用
①资源重用
由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统消耗的基础上,增进了系统环境的平稳性(减少内存碎片以级数据库临时进程、线程的数量)
②更快的系统响应速度
数据库连接池在初始化过程中,往往已经创建了若干数据库连接置于池内备用。此时连接池的初始化操作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接初始化和释放过程的时间开销,从而缩减了系统整体响应时间。
③新的资源分配手段
对于多应用共享同一数据库的系统而言,可在应用层通过数据库连接的配置,实现数据库连接技术。
④统一的连接管理,避免数据库连接泄露
在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用的连接,从而避免了常规数据库连接操作中可能出现的资源泄露
总结:
复用连接:因为Java连接数据库是非常耗费时间的,每次查询都重新连接数据库那样性能非常低下,换成连接池以后,无需每次数据库操作都连接数据库,完成性能的提升
推荐druid
原因:
1.性能也很高(性能比SpringBoot官方集成的连接池HikariCP略低)
2.扩展能力较强
3.具备SQL拦截功能
4.具备数据统计分析能力,如慢SQL分析
spring.datasource.druid.stat-view-servlet.enabled=true
spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
spring.datasource.druid.stat-view-servlet.login-username=druid
spring.datasource.druid.stat-view-servlet.login-password=druid
spring.datasource.druid.stat-view-servlet.allow=
spring.datasource.druid.stat-view-servlet.deny=
```xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.23</version>
</dependency>
本地登录api
http://localhost:8080/druid/login.html
5.md5加密作用/为什么要加盐值?
一般来说会使用md5算法来加密
用commens-codec库
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>
例子
// 密码加自定义盐值,确保密码安全
String saltPwd = pwd + "_ykd2050";
// 生成md5值,并转为大写字母
String md5Pwd = DigestUtils.md5Hex(saltPwd).toUpperCase();
加盐的作用是防止撞库(建立一个大型的数据库,把日常常用的密码,用md5加密成密文,从其他数据库得到的密文与这个数据库进行匹配,从而得到原来密码)
md5加密特点:1.长度固定 2.易计算 3.细微性 4.不可逆性
记住这种加密用法
6.MyBatis中的@Param注解不理解
在理解@Param时,多次提到JavaBean,不知道这个是什么。 新的问题在12已解决
作用:用注解来简化xml配置的时候(比如Mybatis的Mapper.xml中的sql参数引入),@Param注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中(一般通过#{}的方式,${}会有sql注入的问题)。
实例说明:
1,使用@Param注解
Mapper接口方法:
public int getUsersDetail(@Param("userid") int userid);
对应Sql Mapper.xml文件:
<select id="getUserDetail" statementType="CALLABLE" resultMap="baseMap">
Exec WebApi_Get_CustomerList #{userid}
</select>
说明:
当你使用了使用@Param注解来声明参数时,如果使用 #{} 或 ${} 的方式都可以,当你不使用@Param注解来声明参数时,必须使用 #{}方式。如果使用 ${} 的方式,会报错。
2,不使用@Param注解
不使用@Param注解时,最好传递 Javabean。在SQL语句里就可以直接引用JavaBean的属性,而且只能引用JavaBean存在的属性。
Mapper接口方法:
public int getUsersDetail(User user);
对应Sql Mapper.xml文件:
<!--这里直接引用对象属性即可,不需要对象.属性的方式-->
<select id="getUserDetail" statementType="CALLABLE" resultMap="baseMap">
Exec WebApi_Get_CustomerList #{userid}
</select>
补充:
dao层方法只有一个参数时不用加@param;
多个入参时于需要在入参前加@param注解给参数命名
因为java没有保存行参的记录,java在运行的时候会把List queryAll(int offset,int limit);中的参数变成这样:queryAll(int arg0,int arg1),这样我们就没有办法去传递多个参数。所以需要使用@Param注解给方法参数命名,然后在xml文件的该dao层方法对应的sql语句中就可以正常使用@Param注解的参数名。
总结:
1.dao层方法上只有一个参数时可以不加@Param,有多个参数时需要加@Param给参数命名。
2.如果用@Param注解时,可以用#{},${}两种方式传参,如果不用@Param,只能用#{}这种方式传参
3.如果是参数类型是JavaBean,可以不使用@Param注解,在传参时直接引用对象属性,不需要 对象.属性 的方式(用这种方式会报错)。如果给JavaBean使用@Param注解,则必须使用 对象.属性 的方式。
7.为什么DAO类中DO类参数不需要加@Param,其他类型参数要加
没必要加,加了反而麻烦
详情见6
8.@Mapper的作用
- 为了把mapper这个DAO交給Spring容器管理
- 为了不再写mapper映射文件;
- 自动为这个ImgDao接口生成一个实现类,让别的类进行引用。
总结:
1.@Mapper一定要有,不然MyBatis找不到DAO类
2.mapper把这个DAO交给Spring容器管理
3.自动为DAO生成了一个实现类,让别打类引用
9.@Autowired是实例化,为何不直接new
依赖注入的主要目的是让容器去产生一个对象的实例,然后交给spring容器管理,在整个生命周期中使用他们,更加方便灵活,
@Autowired是根据类型进行自动装配,并且是从容器中获取实例并进行注入,我们称之为依赖注入。而new()是直接创建一个新的对象。
这个是他们最本质的区别,一个是从spring容器获取,一个是直接创建新对象。即Autowired是全局实例,而new创建的是仅可以在当前类使用
使用@autowired的另外一个优势: 避免重复创建实例
@autowired注入一个对象, 可以重复使用. 打个比方, 如果业务层有两个类都用到了用一个类, 此时使用new的话得创建两个对象实例, 但是使用@autowired注入的对象可以在不同的类之间使用, 这就避免创建重复的对象, 也就减轻了垃圾回收(GC)的压力
总结:
@Autowired可以根据类型自动匹配,并且是从 Spring容器中获得相应实例,并进行注入,这就是依赖注入,使用@Autowired注入的对象可以在不同的类中使用,避免了重复创建实例。而new是直接创建了一个新的对象,只能在当前类中使用,在不同的类中就需要创建多个对象,增加了垃圾回收的压力
10.@service只会用,不知道作用
@Service注解用于类上,标记当前类是一个service类,加上该注解会将当前类自动注入到spring容器中,不需要再在applicationContext.xml文件定义bean了。
自我总结:
@service只作用于类上,标记当前类是一个service类,自动将类注入到Spring容器中
11.JSON库
1.@JsonProperty("")自定义json输出时候字段名称
2.@JsonIngore用来忽略某些字段,可以添加在属性上,也可以添加在getter、setter上效果一样
3.@JsonIngoreProperties(ignoreUnknown = true)添加在类上忽略类上不存在的字段
@JsonIgnoreProperties(value={""})标注哪个属性不用转化为json
4.@JsonInclude(Include.NON_NULL)当属性的值为空(null或者"")时,不进行序列化,可以减少数据传输,添加在类上
5.JsonFormat见2
12.Java 之 Serializable 序列化和反序列化的概念(不完全懂)
Java序列化是指把Java对象转换为字节序列的过程,而Java反序列化是指把字节序列恢复为Java对象的过程。
2、为什么要实现对象的序列化和反序列化?
(1)我们创建的Java对象被存储在Java堆中,当程序运行结束后,这些对象会被JVM回收。但在现实的应用中,可能会要求在程序运行结束之后还能读取这些对象,并在以后检索数据,这时就需要用到序列化。
(2)当Java对象通过网络进行传输的时候。因为数据只能够以二进制的形式在网络中进行传输,因此当把对象通过网络发送出去之前需要先序列化成二进制数据,在接收端读到二进制数据之后反序列化成Java对象。
13.在解决@Param注解时,不知道什么是JavaBean
什么是JavaBean?
JavaBean是一个遵循特定写法的Java类,它通常具有如下特点:
1.这个Java类必须具有一个无参的构造函数
2.属性必须私有化。
3.私有化的属性必须通过public类型的方法(getter、setter)暴露给其它程序,并且方法的命名也必须遵守一定的命名规范(峰驼命名法)。
知道了JavaBean的特点,很容易就理解了原来我们在项目中常写的model类就是JavaBean
解决方法
面向CSDN