2019/6/27
重载 (overloading):
- 方法重载是让类以统一的方式处理不同类型数据的一种手段。多个同名函数同时存在,具有不同的参数个数/类型。重载是一个类中多态性的一种表现。
- Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递给它们的不同参数个数和参数类型给它们的不同参数个数和参数类型给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性。
- 重载的时候,方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。
4)注意:重载的方法的返回值都是一样的,不能以返回值区分重载方法(但是返回值类型可以相同也可以不相同),而只能以“参数类型”和“类名”来区分。理由:java里允许调用一个有返回值的方法的时候不必将返回值赋给变量,这样JVM就不知道你调用的是有返回值的还是没返回值的.
具体规则如下:
- 被重载的方法必须改变参数列表(参数个数或类型或顺序不一样);
- 被重载的方法可以改变返回类型;
- 被重载的方法可以改变访问修饰符;
- 被重载的方法可以声明新的或更广的检查异常;
- 方法能够在同一个类中或者在一个子类中被重载。
- 无法以返回值类型作为重载函数的区分标准。
重写 (overriding):
- 父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写又称方法覆盖。
- 若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
- 子类函数的访问修饰权限不能少于父类的。
具体规则如下:
- 参数列表必须完全与被重写方法的相同;
- 返回类型必须完全与被重写方法的返回类型相同;
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。
- 父类的成员方法只能被它的子类重写。
- 声明为final的方法不能被重写。
- 声明为static的方法不能被重写,但是能够被再次声明。
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。
- 如果不能继承一个方法,则不能重写这个方法。
2019/6/24
8中基本数据类型:
- byte short int long 这四种基本数据类型数组默认值为0
- float double 这两种数组默认值是0.0
- char这种类型数组默认值为空格
- boolean类型数组默认值为false
- 引用数据类型的默认值是null例如String类型数组默认值为null
变量名为什么不能用数字开头,假设可以
String 123 = "数字开头";
int a = 123;
对于a来说,123是数字还是变量?
2019/3/22
https://blog.csdn.net/wuzhiwei549/article/details/80692278
2019/3/21
线程状态图
为什么使用多线程
1,发挥多核CPU的优势
2,防止阻塞
3, 分解任务,便于建模
创建多线程的方式
1,继承Thread类
看jdk源码可以发现,Thread类其实是实现了Runnable接口的一个实例,继承Thread类后需要重写run方法并通过start方法启动线程。继承Thread类耦合性太强了,因为java只能单继承,所以不利于扩展。
public class test {
public static void main(String[] args){
testThread testThread = new testThread();
testThread.start();
}
}
class testThread extends Thread {
@Override
public void run(){
....
}
}
2,实现Runnable接口
通过实现Runnable接口并重写run方法,并把Runnable实例传给Thread对象,Thread的start方法调用run方法再通过调用Runnable实例的run方法启动线程。所以如果一个类继承了另外一个父类,此时要实现多线程就不能通过继承Thread的类实现。
public class test {
public static void main(String[] args){
Thread thread = new Thread(new testThread());
thread.start();
}
}
class testThread implements Runnable {
@Override
public void run(){
....
}
}
3,实现Callable接口
通过实现Callable接口并重写call方法,并把Callable实例传给FutureTask对象,再把FutureTask对象传给Thread对象。它与Thread、Runnable最大的不同是Callable能返回一个异步处理的结果Future对象并能抛出异常,而其他两种不能。
public class test {
public static void main(String[] args){
FutureTask<Object> futureTask = new FutureTask<>(new testThread());
Thread thread = new Thread(futureTask);
thread.start();
try {
futureTask.get();
}catch (ExecutionException e){
...
}catch (InterruptedException e){
...
}
}
}
class testThread implements Callable<Object> {
@Override
public Object call() throws Exception{
try {
...
}catch (){
...
}
return new Object();
}
}
start()和run()的区别
start才会开始一个线程,才变现多线程的特性不同线程的run()方法里面的代码交替执行。如果只是调用run()方法,那么代码还是同步执行的,必须等待一个线程的run()方法里面的代码全部执行完毕之后,另外一个线程才可以执行其run()方法里面的代码。
Runnable接口和Callable接口的区别
实现Runnable接口的run方法返回值是void,Callable的call方法是有返回值的,是一个泛型,Future和FurtureTask配合来获取异步结果。
2019/3/19
分布式场景下spring boot 集成 shiro 实现分布式session和单点登录
良好地封装redisTemplate
https://blog.csdn.net/luckyxl029/article/details/80625461
https://blog.csdn.net/haoyuyang/article/details/80036989
https://blog.csdn.net/wohaqiyi/article/details/81410034
2019/3/11
HashMap和CurrentHashMap的区别
Java7的和Java8的HashMap, ConcurrentHashMap 原理及源码
为什么HashMap线程不安全
扩容的时候会出现环形链导致CPU占用率到100%
2019/3/4 晚上
2019/3/2 下午
排序算法相关
jdk中的TimSort
jdk中的快速排序
快速排序的优化
2019/3/2 上午
nginx的负载均衡策略
1,时间片轮询
2,权重
3,ipHash
2019/2/28 下午
多线程编程
wait,notify,notifyAll
sleep( ) 和 wait( ) 的区别
2019/2/28 上午
TCP 和 UDP 的区别
TCP | UDP |
---|---|
面向连接 | 面向无连接 |
可靠交付 | 不可靠交付 |
面向字节流(切割报文) | 面向报文 |
固定报头20字节 | 固定报头8字节 |
拥塞控制 | 没有拥塞控制 |
流量控制 | 没有流量控制 |
无界 | 有界 |
有序 | 无序 |
全双工通信 | 一对一,一对多,多对一,多对多交互通信 |
参考:
https://blog.csdn.net/liuyanfeier/article/details/52787037
IP头、TCP头、UDP头详解以及定义
PDU是什么?
PDU(协议数据单元)
协议数据单元PDU(Protocol Data Unit)是指对等层次之间传递的数据单位。 协议数据单元(Protocol Data Unit )物理层的 PDU是数据位(bit),数据链路层的 PDU是数据帧(frame),网络层的PDU是数据包(packet),传输层的 PDU是数据段(segment),其他更高层次的PDU是报文(message)。
2019/2/27 下午
HTTP和HTTPS的区别
端口号,HTTP 80端口,HTTPS 443端口
网络中常用协议端口号-
传输过程,HHTP明文传输,HTTPS加密传输(握手过程使用非对称加密,传输过程使用对称加密),SSL(Secure Sockets Laye),后改名为TTL(Transport Layer Security)
- 握手过程
TCP 帧格式
HTTP:三次握手
- 首先A向B发出连接请求报文段,这时首部中的同步位SYN=1,同时选择一个初始序号 seq=x。TCP规定,SYN报文段不能携带数据,但要消耗掉一个序号。这时,A进入SYN-SENT状态。【备注:序号指的是 TCP 报文段首部20字节里的序号,TCP 连接传送的字节流的每一个字节都按顺序编号,具体可以看看 TCP 可靠传输实现的原理】
- B收到请求后,向A发送确认。在确认报文段中把SYN和ACK位都置为1,确认号是ack=x+1,同时也为自己选择一个初始序号seq=y。请注意,这个报文段也不能携带数据,但同样要消耗掉一个序号。这时B进入SYN-RCVD状态。
- A收到B的确认后,还要向B给出确认。确认报文段的ACK置为1,确认号ack=y+1,而自己的序号seq=x+1。这时,TCP连接已经建立,A进入ESTABLISHED 状态,当B收到A的确认后,也会进入 ESTABLISHED 状态。
参考:
https://blog.csdn.net/Celeste7777/article/details/47728869
https://blog.csdn.net/xy010902100449/article/details/48274635
终止协议:四次挥手
TCP是全双工模式,当client发出FIN报文段时,只是表示client已经没有数据要发送了, client告诉server,它的数据已经全部发送完毕了;但是,这个时候client还是可以接受来server的数据;当server返回ACK报文段时,表示它已经知道client没有数据发送了,但是server还是可以发送数据到client的;当server也发送了FIN报文段时,这个时候就表示server也没有数据要发送了,就会告诉client,我也没有数据要发送了,如果收到client确认报文段,之后彼此就会愉快的中断这次TCP连接。
HTTPS:四次握手
公钥加密计算量太大,为了减少耗用的时间,每一次对话(session),客户端和服务器端都生成一个"对话密钥"(session key),用它来加密信息。由于"对话密钥"是对称加密,所以运算速度非常快,而服务器公钥只用于加密"对话密钥"本身,这样就减少了加密运算的消耗时间。
因此,SSL/TLS协议的基本过程是这样的:
- 客户端请求建立SSL连接,发送支持的加密方式以及一个随机数client random给服务器;
- 服务器选择其中的一种加密方式,并且再加上另外一个随机数server random,和数字证书(其中有公钥),发送给客户端;
- 客户端确认这个数字证书是有效的,并且再生成一个新的随机数,将这个随机数用服务器发送给它的数字证书中的公钥进行加密发送给服务器;
- 服务器收到客户端的回复,利用自己的私钥进行解密,获得这个随机数,然后通过将前面这三个随机数以及他们协商的加密方式,计算生成一个对称密钥。
参考:
https://blog.csdn.net/xiaoming100001/article/details/81109617
https://www.cnblogs.com/lovesong/p/5186200.html
https://www.cnblogs.com/jesse131/p/9080925.html
https://www.cnblogs.com/wqhwe/p/5407468.html
不同的非对称算法,不同的握手过程
HTTPS握手过程
老生常谈 get 和 post的区别
常见的标准答案:get参数长度限制,get参数放在url中,post参数放在Request body,post比较安全然鹅http都是明文传输的没什么安不安全。然鹅,GET 和 POST 方法没有实质区别,只是报文格式不同
报文格式上,不带参数时,最大区别就是第一行方法名不同
POST方法请求报文第一行是这样的: POST /uri HTTP/1.1 \r\n
GET方法请求报文第一行是这样的: GET /uri HTTP/1.1 \r\n
如果参数是 name=kamisama, age=22。
GET 方法报文是这样的
GET /index.php?name=kamisama&age=22 HTTP/1.1
Accept: /
Accept-Language: zh-cn
host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 12
Connection:close
POST 方法报文是这样的
POST /index.php HTTP/1.1
Accept: /
Accept-Language: zh-cn
host: localhost
Content-Type: application/x-www-form-urlencoded
Content-Length: 12
Connection:close
name=kamisama&age=22
两种方法本质上是 TCP 连接,没有差别,也就是说,如果我不按规范来也是可以的。我们可以在 URL 上写参数,然后方法使用 POST;也可以在 Body 写参数,然后方法使用 GET。当然,这需要服务端支持
GET和POST还有一个区别,简单的说:
GET产生一个TCP数据包;POST产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。并不是所有浏览器都会在POST中发送两次包,Firefox和Chrome就只发送一次,所以,header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 post 必然行为
参考文章:
GET 和 POST 报文上的区别
2019/2/26
我今天看HashSet源码的时候惊了,这TM不就是个HashMap的实例吗然后找了几篇文章看了一下
https://blog.csdn.net/HD243608836/article/details/80214413
https://blog.csdn.net/kazei2073/article/details/79759031
java关键字
Java泛型中的标记符含义:
E - Element (在集合中使用,因为集合中存放的是元素)
T - Type(Java 类)
K - Key(键)
V - Value(值)
N - Number(数值类型)
? - 表示不确定的java类型
S、U、V - 2nd、3rd、4th types
遇到<A>,<B>,<K,V>等,是用到了java中的泛型。 一般使用<T>来声明类型持有者名称,自定义泛型类时,类持有者名称可以使用T(Type) 如果是容器的元素可以使用E(Element),若键值匹配可以用K(Key)和V(Value)等, 若是<?>,则是默认是允许Object及其下的子类,也就是java的所有对象了。
所以说,如果是字每A,B,C,D...定义的,就是泛型,这里T只是名字上的意义而已T---type,E----Element
K----key, V----value
如果是?定义的,就是普通的Object或者其子类
举例说明:
Set<T> 表示 集合里 是 T类的实例
List<E> 表示 集合里 是 E类的实例
List<?> 表示 集合里的对象类型不确定,未指定
List 同 List<?> 是一样的。
2019/2/22
@Async
Async注解 异步调用官方实例
红黑树
红黑树插入节点
Java 8 新特性
Lambda
stream
java技巧
java技术栈
Java 8 开发的 4 大技巧
2019/2/21 上午
2019/2/19 下午
现有的几种消息队列技术选型
https://www.sojson.com/blog/48.html
https://blog.csdn.net/vtopqx/article/details/76382934
https://blog.csdn.net/qq_30764991/article/details/80573352
https://blog.csdn.net/weixin_43397326/article/details/83108361
2019/2/19 上午
Spring源码分析
https://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/#N1018E
https://blog.csdn.net/hotpots/article/details/78046943
https://blog.csdn.net/weixin_43397326/article/details/83108361
Spring Boot 入口类
run方法运行过程
Spring中涉及的设计模式
https://blog.csdn.net/caoxiaohong1005/article/details/80039656
建议和这两篇一起看
https://www.cnblogs.com/pony1223/p/7608955.html
https://www.cnblogs.com/geek6/p/3951677.html
2019/2/17 上午
spring boot 集成 rabbitMQ
1.pom添加spring-boot-starter-amqp依赖
2.config里配置
3.编写发送者,sender
4.编写接受者,receiver
rabbitMQ的几种模式,我参考官方文档实现的事例://www.greatytc.com/p/d53d674ad480
https://www.cnblogs.com/zhangweizhong/p/5713874.html
https://blog.csdn.net/Dome_/article/details/80028087
2019/2/16 下午
Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性。Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很好的检验。它的最终目标是打造一个高效、稳定、安全、易用的Web平台。
数据库分库分表中间件
接口优化思路
系统初始化时,预加载一些数据到redis---->消息队列,排队中状态----->请求出对----->客户端轮询是否请求成功。
2019/2/14 下午
高并发情况下的页面优化技术
页面缓存
常用的页面数据放在缓存里,例如商品页,商品详情页,像一些请求内容不会经常改变而且跟用户无关的页面,就放在缓存里,放个一两分钟,比如像用户信息页面这种每个人都不一样的页面,就还是用对象缓存叭。前后端分离,页面静态化简单来说就可以是html加上ajax
url缓存
对象缓存
放user对象之类的
2019/2/10 晚
分布式session一致性问题,个人理解和搜集资料
解决方案:
1,session同步
优点,不用改代码
缺点,性能垃圾
2,客户端储存,cookie里存session或者分发token给客户端(例如JWT)
优点,服务端不需要存session,顺便解决单点登录问题
缺点,占带宽,不安全,不方便控制生命周期
3,反向代理层做点小动作,拿用户ip,地区ip来做hash保证同一个浏览器用户的请求落在同一个web-server上
优点,只需要改nginx配置,不需要修改应用代码,负载均衡,只要hash属性是均匀的,多台web-server的负载是均衡的
缺点,反向代理就负责转发,尽量不要引入应用层业务属性
4,集中放在后端数据库或缓存,mongoDB或者redis
优点,没有安全隐患,可以水平扩展,数据库/缓存水平切分即可,web-server重启或者扩容都不会有session丢失,感觉现在都是这么做的
缺点,增加了一次网络调用,并且需要修改应用代码
2019/2/10以前
mybatis generator的generatorConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!--
可以用于加载配置项或者配置文件,在整个配置文件中就可以使用${propertyKey}的方式来引用配置项
resource:配置资源加载地址,使用resource,MBG从classpath开始找,比如com/myproject/generatorConfig.properties
url:配置资源加载地址,使用URL的方式,比如file:///C:/myfolder/generatorConfig.properties
注意,两个属性只能选址一个
另外,如果使用了mybatis-generator-maven-plugin,那么在pom.xml中定义的properties都可以直接在generatorConfig.xml中使用
<properties resource="" url="" />
-->
<!--<properties resource="db.properties"/>-->
<!--
在MBG工作的时候,需要额外加载的依赖包
location属性指明加载jar/zip包的全路径
-->
<classPathEntry
location="C:\Users\Semi\.m2\repository\mysql\mysql-connector-java\5.1.38\mysql-connector-java-5.1.38.jar"/>
<!--
context:生成一组对象的环境
id:必选,上下文id,用于在生成错误时提示
defaultModelType:指定生成对象的样式
1. conditional:类似hierarchical
2. flat:所有内容(主键,blob)等全部生成在一个对象中
3. hierarchical:主键生成一个XXKey对象(key class),Blob等单独生成一个对象,其他简单属性在一个对象中(record class)
targetRuntime:
1. MyBatis3:默认的值,生成基于MyBatis3.x以上版本的内容,包括XXXBySample
2. MyBatis3Simple:类似MyBatis3,只是不生成XXXBySample
introspectedColumnImpl:类全限定名,用于扩展MBG
-->
<context id="MyBatis" targetRuntime="MyBatis3">
<!--
自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表
一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖
-->
<property name="autoDelimitKeywords" value="false"/>
<!-- 生成的Java文件的编码 -->
<property name="javaFileEncoding" value="UTF-8"/>
<!-- 格式化Java代码 -->
<property name="javaFormatter" value="org.mybatis.generator.api.dom.DefaultJavaFormatter"/>
<!-- 格式化XML代码 -->
<property name="xmlFormatter" value="org.mybatis.generator.api.dom.DefaultXmlFormatter"/>
<!-- 不生成注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true"/>
<property name="suppressDate" value="true"/>
</commentGenerator>
<!-- JDBC连接配置 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/test"
userId="root"
password="123456"/>
<!--
Java类型处理器
用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl
注意一点,默认会先尝试使用Integer,Long,Short等来对应DECIMAL和NUMERIC数据类型
-->
<javaTypeResolver>
<!--
true:使用BigDecimal对应DECIMAL和 NUMERIC数据类型
false:默认
scale>0;length>18:使用BigDecimal
scale=0;length[10,18]:使用Long
scale=0;length[5,9]:使用Integer
scale=0;length<5:使用Short
-->
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--
Java模型创建器,是必须要的元素
负责:
1. key类(见context的defaultModelType)
2. java类
3. 查询类
targetPackage:生成的类要放的包,真实的包受enableSubPackages属性控制
targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,如果目录不存在,MBG不会自动建目录
-->
<javaModelGenerator targetPackage="com.study.springboot.mybatis.model"
targetProject="E:\WorkSpace\study\springboot\mybatis\src\main\java">
<!-- 自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field,而不是使用setter -->
<!--<property name="constructorBased" value="false"/>-->
<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
<property name="enableSubPackages" value="false"/>
<!--
是否创建一个不可变的类,如果为true
那么MBG会创建一个没有setter方法的类,取而代之的是类似constructorBased的类
-->
<!--<property name="immutable" value="false"/>-->
<!--
设置一个根对象
如果设置了这个根对象,那么生成的keyClass或者recordClass会继承这个类,在Table的rootClass属性中可以覆盖该选项
注意:
如果在key class或者record class中有root class相同的属性,MBG就不会重新生成这些属性了,包括:
1. 属性名相同,类型相同,有相同的getter/setter方法
-->
<!--<property name="rootClass" value="com._520it.mybatis.domain.BaseDomain"/>-->
<!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--
生成SQL map的XML文件生成器
注意,在Mybatis3之后,我们可以使用mapper.xml文件+Mapper接口(或者不用mapper接口)
或者只使用Mapper接口+Annotation,所以,如果javaClientGenerator配置中配置了需要生成XML的话,这个元素就必须配置
targetPackage/targetProject:同javaModelGenerator
-->
<sqlMapGenerator targetPackage="mapper"
targetProject="E:\WorkSpace\study\springboot\mybatis\src\main\resources">
<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!--
对于mybatis来说,即生成Mapper接口
注意,如果没有配置该元素,那么默认不会生成Mapper接口
targetPackage/targetProject:同javaModelGenerator
type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下)
1. ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中)不会生成对应的XML
2. MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中
3. XMLMAPPER:会生成Mapper接口,接口完全依赖XML
注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER
-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.study.springboot.mybatis.mapper"
targetProject="E:\WorkSpace\study\springboot\mybatis\src\main\java">
<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
<property name="enableSubPackages" value="false"/>
<!--
可以为所有生成的接口添加一个父接口,但是MBG只负责生成,不负责检查
<property name="rootInterface" value=""/>
-->
</javaClientGenerator>
<!--
选择一个table来生成相关文件,可以有一个或多个table,必须要有table元素
选择的table会生成一下文件:
1. SQL map文件
2. 生成一个主键类
3. 除了BLOB和主键的其他字段的类
4. 包含BLOB的类
5. 一个用户生成动态查询的条件类(selectByExample, deleteByExample)可选
6. Mapper接口(可选)
tableName(必要):要生成对象的表名,%表示通配,即为该数据库下的所有表生成xml文件
注意:大小写敏感问题.正常情况下,MBG会自动的去识别数据库标识符的大小写敏感度,在一般情况下
MBG会根据设置的schema,catalog或tablename去查询数据表,按照下面的流程:
1. 如果schema,catalog或tablename中有空格,那么设置的是什么格式,就精确的使用指定的大小写格式去查询
2. 否则,如果数据库的标识符使用大写的,那么MBG自动把表名变成大写再查找
3. 否则,如果数据库的标识符使用小写的,那么MBG自动把表名变成小写再查找
4. 否则,使用指定的大小写格式查询
另外,如果在创建表的时候,使用的""把数据库对象规定大小写,就算数据库标识符是使用的大写,在这种情况下也会使用给定的大小写来创建表名
这个时候,请设置delimitIdentifiers="true"即可保留大小写格式
可选:
1. schema:数据库的schema
2. catalog:数据库的catalog
3. alias:为数据表设置的别名,如果设置了alias,那么生成的所有的SELECT SQL语句中,列名会变成:alias_actualColumnName
4. domainObjectName:生成的domain类的名字,如果不设置,直接使用表名作为domain类的名字;可以设置为somepck.domainName,那么会自动把domainName类再放到somepck包里面
5. enableInsert(默认true):指定是否生成insert语句
6. enableSelectByPrimaryKey(默认true):指定是否生成按照主键查询对象的语句(就是getById或get)
7. enableSelectByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询语句
8. enableUpdateByPrimaryKey(默认true):指定是否生成按照主键修改对象的语句(即update)
9. enableDeleteByPrimaryKey(默认true):指定是否生成按照主键删除对象的语句(即delete)
10. enableDeleteByExample(默认true):MyBatis3Simple为false,指定是否生成动态删除语句
11. enableCountByExample(默认true):MyBatis3Simple为false,指定是否生成动态查询总条数语句(用于分页的总条数查询)
12. enableUpdateByExample(默认true)MyBatis3Simple为false,指定是否生成动态修改语句(只修改对象中不为空的属性)
13. modelType:参考context元素的defaultModelType,相当于覆盖
14. delimitIdentifiers:参考tableName的解释,注意,默认的delimitIdentifiers是双引号,如果类似MYSQL这样的数据库,使用的是`(反引号,那么还需要设置context的beginningDelimiter和endingDelimiter属性)
15. delimitAllColumns:设置是否所有生成的SQL中的列名都使用标识符引起来.默认为false,delimitIdentifiers参考context的属性
注意,table里面很多参数都是对javaModelGenerator,context等元素的默认属性的一个复写
-->
<table tableName="%"
enableCountByExample="false"
enableUpdateByExample="false"
enableDeleteByExample="false"
enableSelectByExample="false"
selectByExampleQueryId="false">
<!-- 参考javaModelGenerator的constructorBased属性 -->
<!--<property name="constructorBased" value="false"/>-->
<!-- 默认为false,如果设置为true,在生成的SQL中,table名字不会加上catalog或schema -->
<!--<property name="ignoreQualifiersAtRuntime" value="false"/>-->
<!-- 参考javaModelGenerator的immutable属性 -->
<!--<property name="immutable" value="false"/>-->
<!-- 指定是否只生成domain类,如果设置为true,只生成domain类,如果还配置了sqlMapGenerator,那么在mapper XML文件中,只生成resultMap元素 -->
<!--<property name="modelOnly" value="false"/>-->
<!-- 参考javaModelGenerator的rootClass属性 -->
<!--<property name="rootClass" value=""/>-->
<!-- 参考javaClientGenerator的rootInterface属性 -->
<!--<property name="rootInterface" value=""/>-->
<!-- 如果设置了runtimeCatalog,那么在生成的SQL中,使用该指定的catalog,而不是table元素上的catalog -->
<!--<property name="runtimeCatalog" value=""/>-->
<!-- 如果设置了runtimeSchema,那么在生成的SQL中,使用该指定的schema,而不是table元素上的schema -->
<!--<property name="runtimeSchema" value=""/>-->
<!-- 如果设置了runtimeTableName,那么在生成的SQL中,使用该指定的tablename,而不是table元素上的tablename -->
<!--<property name="runtimeTableName" value=""/>-->
<!--
注意,该属性只针对MyBatis3Simple有用
如果选择的runtime是MyBatis3Simple,那么会生成一个SelectAll方法,如果指定了selectAllOrderByClause,那么会在该SQL中添加指定的这个order条件
-->
<!--<property name="selectAllOrderByClause" value="age desc,username asc"/>-->
<!-- 如果设置为true,生成的model类会直接使用column本身的名字,而不会再使用驼峰命名方法,比如BORN_DATE,生成的属性名字就是BORN_DATE,而不会是bornDate -->
<!--<property name="useActualColumnNames" value="false"/>-->
<!--
generatedKey用于生成生成主键的方法
如果设置了该元素,MBG会在生成的<insert>元素中生成一条正确的<selectKey>元素,该元素可选
column:主键的列名
sqlStatement:要生成的selectKey语句,有以下可选项:
Cloudscape:相当于selectKey的SQL为:VALUES IDENTITY_VAL_LOCAL()
DB2 :相当于selectKey的SQL为:VALUES IDENTITY_VAL_LOCAL()
DB2_MF :相当于selectKey的SQL为:SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1
Derby :相当于selectKey的SQL为:VALUES IDENTITY_VAL_LOCAL()
HSQLDB :相当于selectKey的SQL为:CALL IDENTITY()
Informix :相当于selectKey的SQL为:select dbinfo('sqlca.sqlerrd1') from systables where tabid=1
MySql :相当于selectKey的SQL为:SELECT LAST_INSERT_ID()
SqlServer :相当于selectKey的SQL为:SELECT SCOPE_IDENTITY()
SYBASE :相当于selectKey的SQL为:SELECT @@IDENTITY
JDBC :相当于在生成的insert元素上添加useGeneratedKeys="true"和keyProperty属性
-->
<!--<generatedKey column="" sqlStatement=""/>-->
<!--
该元素会在根据表中列名计算对象属性名之前先重命名列名,非常适合用于表中的列都有公用的前缀字符串的时候
比如列名为:CUST_ID,CUST_NAME,CUST_EMAIL,CUST_ADDRESS等
那么就可以设置searchString为"^CUST_",并使用空白替换,那么生成的Customer对象中的属性名称就不是
custId,custName等,而是先被替换为ID,NAME,EMAIL,然后变成属性:id,name,email
注意,MBG是使用java.util.regex.Matcher.replaceAll来替换searchString和replaceString的
如果使用了columnOverride元素,该属性无效
-->
<!--<columnRenamingRule searchString="" replaceString=""/>-->
<!--
用来修改表中某个列的属性,MBG会使用修改后的列来生成domain的属性
column:要重新设置的列名
注意,一个table元素中可以有多个columnOverride元素
-->
<!--<columnOverride column="username">-->
<!-- 使用property属性来指定列要生成的属性名称 -->
<!--<property name="property" value="userName"/>-->
<!-- javaType用于指定生成的domain的属性类型,使用类型的全限定名 -->
<!--<property name="javaType" value=""/>-->
<!-- jdbcType用于指定该列的JDBC类型 -->
<!--<property name="jdbcType" value=""/>-->
<!--
typeHandler:用于指定该列使用到的TypeHandler,如果要指定,配置类型处理器的全限定名
注意,mybatis中,不会生成到mybatis-config.xml中的typeHandler
只会生成类似:where id = #{id,jdbcType=BIGINT,typeHandler=com._520it.mybatis.MyTypeHandler}的参数描述
-->
<!--<property name="jdbcType" value=""/>-->
<!-- 参考table元素的delimitAllColumns配置,默认为false -->
<!--<property name="delimitedColumnName" value=""/>-->
<!--
ignoreColumn设置一个MGB忽略的列,如果设置了改列,那么在生成的domain中,生成的SQL中,都不会有该列出现
column:指定要忽略的列的名字
delimitedColumnName:参考table元素的delimitAllColumns配置,默认为false
注意,一个table元素中可以有多个ignoreColumn元素
-->
<!--<ignoreColumn column="deptId" delimitedColumnName=""/>-->
</table>
</context>
</generatorConfiguration>
使用devtool和通用Mapper可能出现的问题
在使用 DevTools 时,通用Mapper经常会出现 class x.x.A cannot be cast to x.x.A。
同一个类如果使用了不同的类加载器,就会产生这样的错误,所以解决方案就是让通用Mapper和实体类使用相同的类加载器即可。
DevTools 默认会对 IDE 中引入的所有项目使用 restart 类加载器,对于引入的 jar 包使用 base 类加载器,因此只要保证通用Mapper的jar包使用 restart 类加载器即可。
在 src/main/resources 中创建 META-INF 目录,在此目录下添加 spring-devtools.properties 配置,内容如下:
restart.include.mapper=/mapper-[\w-\.]+jar
restart.include.pagehelper=/pagehelper-[\w-\.]+jar
使用这个配置后,就会使用 restart 类加载加载 include 进去的 jar 包。
Junit
spring boot 和 shiro 整合
参考
https://segmentfault.com/a/1190000014479154
//www.greatytc.com/p/ef0a82d471d2
//www.greatytc.com/p/3c51832f1051
spring boot 中 自定义catch shiro抛出的exception
运用@ControllerAdvice注解
@ControllerAdvice
@Slf4j
public class GlobalShiroExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler(UnauthorizedException.class)
@ResponseBody
public ServerResponse UnauthorizedException(UnauthorizedException e) {
log.info(e.toString());
return ServerResponse.createByErrorMessage("用户没有访问权限: "+e.getMessage());
}
}
单点登录 cas
https://blog.csdn.net/qq_39089301/article/details/80615348
https://yq.aliyun.com/articles/636281
https://www.cnblogs.com/wxj-106/p/8097880.html