-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsearch.xml
More file actions
82 lines (82 loc) · 66 KB
/
search.xml
File metadata and controls
82 lines (82 loc) · 66 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title><![CDATA[Rocket MQ]]></title>
<url>%2F2019%2F09%2F03%2FRocket%20MQ%2F</url>
<content type="text"><![CDATA[当前公司使用的消息中间件为Rocket MQ,但是说实话,我对Rocket MQ的认知也仅限于调用他们封装好的接口(比如说Sendmessage这种方法名,太常见了吧),我也看了他们封装了什么东西在里面,讲实话,我没看出他们封装的有多高级,跟网上的差不多吧一些策略之类的东西,我这种写业务的从来不会去深究,只管调用好就好,这大概是初级程序员经常干的事。但是人还是要上进的呀,写一篇笔记,这也算是系统的学习一下Rocket MQ了。 Rocket MQ由什么构成?NameServer首先从命名上面看,肯定是做命名相关的活,服务治理之类的,有点像zookeeper,没错,其实Rocket MQ最开始就是使用zookeeper的,后来才自己做了实现。 作用: 维护Broker的地址列表,维护Broker的存活状态(Broker启动的时候会在NameServer进行注册)。 维护Topic和Topic对应队列的地址列表,Broker每次发送心跳过来时都会将Topic的信息带过来。 总结:维护Broker和Topic等信息,通过netty来进行长连接来保持Producer和Consumer跟Broker的通信,与此同时还提供心跳检测、数据更新查询等常规服务。 主要实现类: NamesrvStartUp:NameServer启动类 NamesrcController:NameServer控制类,主要负责NameServer的生命周期(启动、初始化、停止) RouteInfoManager:存放Topic队列信息,Broker地址列表等一系列数据结构,并提供对应的数据变更接口。 DefaultRequestProcessosr:处理Broker发过来的所有消息,封装了对netty包的处理和部分对NameServer存储的数据查询和删除。 NameServer启动流程 Producer消息生产者,主要是业务产生消息。 Producer由用户进行分布式部署,Producer会将消息通过负载均衡(轮询队列Roundbin,每个队列接收平均额消息量)发送到Broker集群,发送低延时,支持快速失败。 支持发送延迟消息(可以指定时刻、指定延迟间隔),指定为消息类型为延迟消息后,该消息发送到broker,需要等待延迟时间过后,才能背Consumer消费。 可设置MessageQueueSelector来决定消息放到哪个Queue里。 Broker消息中转角色,负责存储消息,转发消息。 Broker是具体提供业务的服务器,单个Broker节点与所有的NameServer节点保持长连接及心跳,并会定时将Topic信息注册到NameServer,底层的通信、连接都是基于netty所实现的。 Broker负责消息存储,以Topic为维度支持轻量级的队列,单机可以支撑上万队列规模(除了写demo,估计没人会使用单机模式)支持消息推拉模型。 Consumer消息消费者,负责消费消息,后台业务异步消费。 Push方式,通过长轮询实现,由Consumer维护Treemap,保存所有接收到的消息的列表,并实现类似于时间窗口的算法来做流控;PushConsumer会判断获取但还未处理消息个数、消息总大小、Offset的跨度,任何一个值超过设定的大小就隔一段时间再拉取消息,从而达到流量控制的目的。此外ProcessQueue还可以辅助实现顺序消费的逻辑。push方式推出Consume时,必须显示调用shutdown()告知broker记录offset等信息。 Pull方式,需要自己维护从Broker的队列上读取消息的offset,并存储到本地,从而保障当Consumer挂掉重启之后能狗重新接着源地址消费消息。 从原理上讲,pull方式应该是不支持broadcast消息方式的,除非Broker通过session获取连接到其中的所有Consumer,并为未消费的consumer保留消息等待消费。 Consumer只负责消费消息,当消费消息失败的时候,会将消息写回Broker,并设置其Topic为SCHEDULE_TOPIC_XXXX(同样会做落盘处理)。 关键特性尽管Rocket MQ生来就是为了分布式系统所设计的消息中间件,消息的顺序问题,消息的重复消费问题。 消息有序Rocket MQ是如何保证消息的顺序性呢?在介绍生产的者的时候我这边就介绍了一下,Rocket MQ会通过轮询所有队列的方式来决定消息将被发送到哪个队列(负载均衡策略)。Rocket MQ会通过MessageQueueSelector()所实现的算法来选择同一个队列,默认提供了两种实现:随机/Hash ,若你不想使用他提供的算法,你可以根据实际的业务来决定。 业务如何实现消费有序若要实现严格的顺序消费(即全面考虑,网络延迟、数据丢失等方面),可以实现的方式便是应答 ACK+顺序在前先发送,也就是: 保证*生产者—MQServer—消费者 *是一对一的关系 这样虽然保证了消息的顺序消费,与此同时,也会出现其他的问题:吞吐量不够、更多的异常处理(一但消费端出现问题,将会阻塞整个流程) 消息重复Rocket MQ不保证消息不重复,若你的业务需要严格的保证不重复消息,需要在业务端去重。 消费端处理消息的业务逻辑保持幂等性。 保证每条消息都有唯一编号且保证消息处理成功,其次去重表的日志显的尤为重要。]]></content>
<categories>
<category>中间件</category>
</categories>
<tags>
<tag>MQ</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Thymeleaf模版引擎]]></title>
<url>%2F2018%2F09%2F17%2FThymeleaf%E6%A8%A1%E7%89%88%E5%BC%95%E6%93%8E%2F</url>
<content type="text"><![CDATA[JSP Velocity Freemaker Thymeleaf 应该是我们在日常生活中最常用的四种模版引擎了,今天我们要说的猪脚是Thymeleaf,为什么呢,spring]]></content>
<tags>
<tag>前端</tag>
</tags>
</entry>
<entry>
<title><![CDATA[SpringBoot-配置文件]]></title>
<url>%2F2018%2F08%2F28%2FSpringBoot-%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6%2F</url>
<content type="text"><![CDATA[Spring Boot 允许通过外部配置让你在不同的环境使用同一应用程序的代码,简单说就是可以通过配置文件来注入属性或者修改默认的配置。 配置文件YAML配置文件SpringBoot使用一个全局的配置文件,配置文件名是固定的: application.properties application.yml 配置文件的作用:修改SpringBoot自动配置的默认值,SpringBoot在底层都自动配置好。 YAML(YAML Ain’t Markup Language) 标记语言: 以前的配置文件,大多都使用的是 **xxxx.xml**文件。 YAML:**以数据为中心**,比json xml等更适合做配置文件。 YAML:配置例子12server: port: 8081 XML:123<server> <port>8081</port></server> YAML语法基本语法k:(空格)v:表示一对键值对(空格必须有)。 以空格的缩进来控制层级关系,只要是左对齐的一列数据,都是同一个层级的。 123server: port: 8081 path: /hello 属性和值也是大小写敏感。 值的写法字面量:普通的值(数字,字符串,布尔)k: v:字面直接来写。 字符串默认不用加上单引号或者双引号 “ “:双引号,不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思 name: "zhangsan \n lisi" 输出:zhangsan 换行 lisi‘ ‘:单引号,会转义特殊字符,特殊字符最终只是一个普通的字符串数据 name: ‘zhangsan \n lisi’ 输出:zhangsan \n lisi对象 Map(属性和值)(键值对)k: v:在下一行来写对象的属性和值的关系,要注意缩进 对象还是k: v的方式 123friends: lastName: zhangsan age: 20 行内写法: 1friends: {lastName: zhangsan,age: 18} 数组(List Set)用- 值表示数组中的一个元素 1234pets: - cat - dog - pig 行内写法 1pets: [cat,dog,pig] 配置文件值注入配置文件 123456789101112person: lastName: hello age: 18 boss: false birth: 2017/12/12 maps: {k1: v1,k2: 12} lists: - lisi - zhaoliu dog: name: 小狗 age: 12 javaBean: 1234567891011121314151617181920/** * 将配置文件中配置的每一个属性的值,映射到这个组件中 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定; * prefix = "person":配置文件中哪个下面的所有属性进行一一映射 * * 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能; * */@Component@ConfigurationProperties(prefix = "person")public class Person { private String lastName; private Integer age; private Boolean boss; private Date birth; private Map<String,Object> maps; private List<Object> lists; private Dog dog; 我们可以导入配置文件处理器,以后编写配置就有提示了 123456<!--导入配置文件处理器,配置文件进行绑定就会有提示--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> properties配置文件在idea中默认utf-8可能会乱码@Value获取值和@ConfigurationProperties获取值比较 @ConfigurationProperties @Value 功能 批量注入配置文件中的属性 一个个指定 松散绑定(松散语法) 支持 不支持 SpEL 不支持 支持 JSR303数据校验 支持 不支持 复杂类型封装 支持 不支持 配置文件yml还是properties他们都能获取到值; 如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value; 如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties; 配置文件注入值数据校验123456789101112131415161718192021222324@Component@ConfigurationProperties(prefix = "person")@Validatedpublic class Person { /** * <bean class="Person"> * <property name="lastName" value="字面量/${key}从环境变量 配置文件中获取值/#{SpEL}"></property> * <bean/> */ //lastName必须是邮箱格式 @Email //@Value("${person.last-name}") private String lastName; //@Value("#{11*2}") private Integer age; //@Value("true") private Boolean boss; private Date birth; private Map<String,Object> maps; private List<Object> lists; private Dog dog; @PropertySource&@ImportResource&@Bean@PropertySource:加载指定的配置文件; 1234567891011121314151617181920212223242526272829/** * 将配置文件中配置的每一个属性的值,映射到这个组件中 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定; * prefix = "person":配置文件中哪个下面的所有属性进行一一映射 * * 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能; * @ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值; * */@PropertySource(value = {"classpath:person.properties"})@Component@ConfigurationProperties(prefix = "person")//@Validatedpublic class Person { /** * <bean class="Person"> * <property name="lastName" value="字面量/${key}从环境变量 配置文件中获取值/#{SpEL}"></property> * <bean/> */ //lastName必须是邮箱格式 // @Email //@Value("${person.last-name}") private String lastName; //@Value("#{11*2}") private Integer age; //@Value("true") private Boolean boss; @ImportResource:导入Spring的配置文件,让配置文件里面的内容生效; Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别; 想让Spring的配置文件生效,加载进来;@ImportResource标注在一个配置类上 12@ImportResource(locations = {"classpath:beans.xml"})导入Spring的配置文件让其生效 不来编写Spring的配置文件 1234567<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="helloService" class="com.atguigu.springboot.service.HelloService"></bean></beans> SpringBoot推荐给容器中添加组件的方式,推荐使用全注解的方式 1 配置类@Configuration——>Spring配置文件 2 使用@Bean给容器中添加组件 12345678910111213141516/** * @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件 * * 在配置文件中用<bean><bean/>标签添加组件 * */@Configurationpublic class MyAppConfig { //将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名 @Bean public HelloService helloService02(){ System.out.println("配置类@Bean给容器中添加组件了..."); return new HelloService(); }} 配置文件占位符随机数12${random.value} ${random.int} ${random.long}${random.int(10)} ${random.int[1024,65536]} 占位符获取之前配置的值,如果没有可以是用:指定默认值123456789person.last-name=张三${random.uuid}person.age=${random.int}person.birth=2017/12/15person.boss=falseperson.maps.k1=v1person.maps.k2=14person.lists=a,b,cperson.dog.name=${person.hello:hello}_dogperson.dog.age=15 Profile多Profile文件我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml 默认使用application.properties的配置 yml支持多文档块方式12345678910111213141516171819server: port: 8081spring: profiles: active: prod---server: port: 8083spring: profiles: dev---server: port: 8084spring: profiles: prod #指定属于哪个环境 激活指定profile1 在配置文件中指定 spring.profiles.active=dev 2 命令行: java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev; 可以直接在测试的时候,配置传入命令行参数 3 虚拟机参数; -Dspring.profiles.active=dev配置文件加载位置springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件 –file:./config/ –file:./ –classpath:/config/ –classpath:/ 优先级由高到底,高优先级的配置会覆盖低优先级的配置 SpringBoot会从这四个位置全部加载主配置文件,互补配置 我们还可以通过spring.config.location来改变默认的配置文件位置 项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置; java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar –spring.config.location=G:/application.properties 外部配置加载顺序SpringBoot也可以从以下位置加载配置; 优先级从高到低;高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置 1.命令行参数 所有的配置都可以在命令行上进行指定 java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar –server.port=8087 –server.context-path=/abc 多个配置用空格分开; –配置项=值 2.来自java:comp/env的JNDI属性 3.Java系统属性(System.getProperties()) 4.操作系统环境变量 5.RandomValuePropertySource配置的random.*属性值 由jar包外向jar包内进行寻找; 优先加载带profile 6.jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件 7.jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件 再来加载不带profile 8.jar包外部的application.properties或application.yml(不带spring.profile)配置文件 9.jar包内部的application.properties或application.yml(不带spring.profile)配置文件 10.@Configuration注解类上的@PropertySource 11.通过SpringApplication.setDefaultProperties指定的默认属性 所有支持的配置加载来源 参考官方文档 自动配置原理配置文件到底能写什么?怎么写?自动配置原理 配置文件能配置的属性参照 自动配置原理:1) SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration 2) @EnableAutoConfiguration 作用: 利用EnableAutoConfigurationImportSelector给容器中导入一些组件? 可以查看selectImports()方法的内容 List configurations = getCandidateConfigurations(annotationMetadata,attributes);获取候选的配置 1234SpringFactoriesLoader.loadFactoryNames()扫描所有jar包类路径下 META-INF/spring.factories把扫描到的这些文件的内容包装成properties对象从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中 将 类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798# Auto Configureorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\org.springframework.boot.autoconfigure.mobile.DeviceResolverAutoConfiguration,\org.springframework.boot.autoconfigure.mobile.DeviceDelegatingViewResolverAutoConfiguration,\org.springframework.boot.autoconfigure.mobile.SitePreferenceAutoConfiguration,\org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\org.springframework.boot.autoconfigure.reactor.ReactorAutoConfiguration,\org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration,\org.springframework.boot.autoconfigure.security.SecurityFilterAutoConfiguration,\org.springframework.boot.autoconfigure.security.FallbackWebSecurityAutoConfiguration,\org.springframework.boot.autoconfigure.security.oauth2.OAuth2AutoConfiguration,\org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\org.springframework.boot.autoconfigure.social.SocialWebAutoConfiguration,\org.springframework.boot.autoconfigure.social.FacebookAutoConfiguration,\org.springframework.boot.autoconfigure.social.LinkedInAutoConfiguration,\org.springframework.boot.autoconfigure.social.TwitterAutoConfiguration,\org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration,\org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration,\org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration,\org.springframework.boot.autoconfigure.web.HttpEncodingAutoConfiguration,\org.springframework.boot.autoconfigure.web.HttpMessageConvertersAutoConfiguration,\org.springframework.boot.autoconfigure.web.MultipartAutoConfiguration,\org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration,\org.springframework.boot.autoconfigure.web.WebClientAutoConfiguration,\org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration,\org.springframework.boot.autoconfigure.websocket.WebSocketAutoConfiguration,\org.springframework.boot.autoconfigure.websocket.WebSocketMessagingAutoConfiguration,\org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration 每一个这样的 xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置 3) 每一个自动配置类进行自动配置功能 4) 以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理 12345678910111213141516171819202122232425262728@Configuration //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件@EnableConfigurationProperties(HttpEncodingProperties.class) //启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中@ConditionalOnWebApplication //Spring底层@Conditional注解(Spring注解版),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是否是web应用,如果是,当前配置类生效@ConditionalOnClass(CharacterEncodingFilter.class) //判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true) //判断配置文件中是否存在某个配置 spring.http.encoding.enabled;如果不存在,判断也是成立的//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;public class HttpEncodingAutoConfiguration { //他已经和SpringBoot的配置文件映射了 private final HttpEncodingProperties properties; //只有一个有参构造器的情况下,参数的值就会从容器中拿 public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) { this.properties = properties; } @Bean //给容器中添加一个组件,这个组件的某些值需要从properties中获取 @ConditionalOnMissingBean(CharacterEncodingFilter.class) //判断容器没有这个组件? public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE)); return filter; } 根据当前不同的条件判断,决定这个配置类是否生效? 一但这个配置类生效,这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的。 5) 所有在配置文件中能配置的属性都是在xxxxProperties类中封装者‘,配置文件能配置什么就可以参照某个功能对应的这个属性类。 1234@ConfigurationProperties(prefix = "spring.http.encoding") //从配置文件中获取指定的值和bean的属性进行绑定public class HttpEncodingProperties { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); 精髓: 12345671) SpringBoot启动会加载大量的自动配置类2) 我们看我们需要的功能有没有SpringBoot默认写好的自动配置类3) 我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)4) 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值 xxxxAutoConfigurartion:自动配置类 给容器中添加组件 xxxxProperties:封装配置文件中相关属性 细节Conditional派生注解(Spring注解版原生的@Conditional作用)作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效 @Conditional扩展注解 作用(判断是否满足当前指定条件) @ConditionalOnJava 系统的java版本是否符合要求 @ConditionalOnBean 容器中存在指定Bean; @ConditionalOnMissingBean 容器中不存在指定Bean; @ConditionalOnExpression 满足SpEL表达式指定 @ConditionalOnClass 系统中有指定的类 @ConditionalOnMissingClass 系统中没有指定的类 @ConditionalOnSingleCandidate 容器中只有一个指定的Bean,或者这个Bean是首选Bean @ConditionalOnProperty 系统中指定的属性是否有指定的值 @ConditionalOnResource 类路径下是否存在指定资源文件 @ConditionalOnWebApplication 当前是web环境 @ConditionalOnNotWebApplication 当前不是web环境 @ConditionalOnJndi JNDI存在指定项 自动配置类必须在一定的条件下才能生效 我们怎么知道哪些自动配置类生效 我们可以通过启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效 1234567891011121314151617181920212223=========================AUTO-CONFIGURATION REPORT=========================Positive matches:(自动配置类启用的)----------------- DispatcherServletAutoConfiguration matched: - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition) - @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition) Negative matches:(没有启动,没有匹配成功的自动配置类)----------------- ActiveMQAutoConfiguration: Did not match: - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition) AopAutoConfiguration: Did not match: - @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice' (OnClassCondition)]]></content>
<tags>
<tag>SpringBoot</tag>
</tags>
</entry>
<entry>
<title><![CDATA[SpringBoot-入门篇]]></title>
<url>%2F2018%2F08%2F26%2FSpringBoot-%E5%85%A5%E9%97%A8%E7%AF%87%2F</url>
<content type="text"><![CDATA[SpringBoot就是简化Spring应用开发的一个框架,整个Spring技术栈的一个大整合,J2EE开发的一站式解决方案。 Spring Boot HelloWorld1. 创建一个maven工程2. 导入Spring Boot相关的依赖1234567891011<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version></parent><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency></dependencies> 3. 编写一个主程序,启动Spring Boot应用123456789101112/** * @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用 */@SpringBootApplicationpublic class HelloWorldMainApplication { public static void main(String[] args) { // Spring应用启动起来 SpringApplication.run(HelloWorldMainApplication.class,args); }} 4. 编写相关的Controller Service123456789@Controllerpublic class HelloController { @ResponseBody @RequestMapping("/hello") public String hello(){ return "Hello World!"; }} 5. 运行主程序测试6. 简化部署123456789 <!-- 这个插件,可以将应用打包成一个可执行的jar包;--><build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins></build> 将这个应用打成jar包,直接使用java -jar的命令进行执行 Hello World探究POM文件1. 父项目12345678910111213<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version></parent>他的父项目是<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>1.5.9.RELEASE</version> <relativePath>../../spring-boot-dependencies</relativePath></parent>他来真正管理Spring Boot应用里面的所有依赖版本 Spring Boot的版本仲裁中心以后我们导入依赖默认是不需要写版本(没有在dependencies里面管理的依赖自然需要声明版本号) 2. 启动器1234<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency> spring-boot-starter-web: spring-boot-starter:spring-boot场景启动器,帮我们导入了web模块正常运行所依赖的组件。Spring Boot将所有的功能场景都抽取出来,做成一个个的starters(启动器),只需要在项目里面引入这些starter相关场景的所有依赖都会导入进来,要用什么功能就导入什么场景的启动器。 主程序类,主入口类12345678//@SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用@SpringBootApplicationpublic class HelloWorldMainApplication { public static void main(String[] args) { // Spring应用启动起来 SpringApplication.run(HelloWorldMainApplication.class,args); }} @SpringBootApplication:SpringBoot应用标注在某个类上说明这个类是SpringBoot的主配置,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用。 12345678910@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })public @interface SpringBootApplication {} @SpringBootConfiguration: Spring Boot的配置类,标注在某个类上,表示这是一个Spring Boot的配置类。 @Configuration(Spring中已经定义的注解): 配置类上来标注这个注解,配置类也就是我们之前写的配置文件,配置类也是容器中的一个组件@Component。 @EnableAutoConfiguration: 开启自动配置功能以前我们需要配置的东西,Spring Boot帮我们自动配置,@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效。 123@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {} @AutoConfigurationPackage:自动配置。 @Import(AutoConfigurationPackages.Registrar.class): Spring的底层注解@Import,给容器中导入一个组件,导入的组件由AutoConfigurationPackages.Registrar.class将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器。 @Import(EnableAutoConfigurationImportSelector.class): 给容器中导入什么组件?EnableAutoConfigurationImportSelector:主要作用是导入哪些组件的选择器,将所有需要导入的组件以全类名的方式返回,这些组件就会被添加到容,器中会给容器中导入非常多的自动配置类(xxxAutoConfiguration),自动配置类的作用就是给容器中导入这个场景需要的所有组件,并配置好这些组件。有了自动配置类,免去了我们手动编写配置注入功能组件等的工作。 自动配置类是如何加载到的? SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader): Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取,EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作,以前我们需要自己配置的东西,自动配置类都帮我们。 J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar 使用Spring Initializer快速创建Spring Boot项目IDEA:使用 Spring Initializer快速创建项目 IDE都支持使用Spring的项目创建向导快速创建一个Spring Boot项目 选择我们需要的模块,向导会联网创建Spring Boot项目 默认生成的Spring Boot项目 主程序已经生成好了,我们只需要我们自己的逻辑。 resources文件夹中目录结构 static:保存所有的静态资源; js css images templates:保存所有的模板页面;(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面),可以使用模板引擎(freemarker thymeleaf) application.properties:Spring Boot应用的配置文件,可以修改一些默认设置 STS使用 Spring Starter Project快速创建项目]]></content>
<tags>
<tag>SpringBoot</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Oracle]]></title>
<url>%2F2018%2F04%2F12%2FOracle%2F</url>
<content type="text"><![CDATA[之前整理的Oracle笔记,作为一个后端开发,不懂Oracle是不能忍的(虽然我还只是只ROOKIE,2333333333333333)。 常见关键字create 创建 alter 修改 drop 扔掉 truncate 截断 insert 新建 delete删除 update 修改 query 查询 grant 授权 revoke 撤销授权 commit 提交 rollback 回滚 savepoint 保存还原点 基本语句解锁/加锁账户:alter user username account unlock; alter user username account lock; 修改密码:alter user username identified by password; 创建账户:create user username identified by password; 给用户授权/撤销授权:grant dba to username; revoke dba from username; 删除用户:drop user username; 切换用户:conn username/password; 查看当前用户:show user; 查看表结构desc 表名; 修改创建的表名alter table 原表名 rename to 想更改表名; 建表之后增加字段alter table 表名 add 字段名 字段类型; 建表之后修改字段名alter table 表名 rename column 字段名 to 想要更改表名; 建表之后修改字段数据类型alter table 表名 modify 字段名 想要的数据类型; 建表之后删除字段alter table 表名 drop column 想删除字段; 删除表drop table 表名 purge; 插入数据insert into 表名() values(); 修改数据update student set name = ‘xiaogang’; 删除数据delete from student where name = ‘xiaoxin’; 查询数据select * from student; 基本符号like:%:代表任意位的任意字符 _:代表一位上任意字符 escape逃离符:指定一个字符逃离,保证like之后的字符串中出现的字符看作是普通字符。 Ex:select * from student where name like ‘xiao,_%’ escape ‘,’; 运算符:多行函数:聚组函数:组函数count()记数sum()求和avg()平均 max()最大min()最小 单行函数:ceil():返回大于等于x的最小整数 floor():返回小于等于x的最大整数 round():四舍五入round(a1,a2):保留指定位小数位的四舍五入 Ex:select round(3.1415926,3) from dual; //返回3.142 trunc():直接截断trunc(a1,a2):保留制定位数的小数 sign():求符号位 正数1 负数-1 零返回0abs():且绝对值power(a,b):求a的b次方sqrt():求正平方根转换函数to_number(c):将一个字符类型的数字变成数值类型to_char():将数值类型转换为字符串 将数字转换为字符串 select * from student where ‘456.12’ = to_char(salary); 常用于在货币单位,格式化字符串 select to_char(123123123123.00,’999,999,999,999,999.00’) from dual; 日期转换 to_char(日期,‘yyyy-MM-dd hh24:mi:ss’) JAVA: yyyy-MM-dd HH:mi:ss Oracle:yyyy-mm-dd hh24:mi:ss:xff ff3 毫秒数保留三位 to_date(c1,c2)c1:字符类型的日期 c2:格式 取出年 select to_char(to_date(‘2018-04-04’,‘yyyy-mm-dd’),’yyyy’) from dual; 取出月 ‘yyyy’换成‘month’ 取出日 ‘yyyy’ 换成‘dd’ 日期函数: 日期可以加减(整数)运算 单位是:天 相差结果是多少天 两个日子没法相加 yyyy 年 year 年 mm 月 month 带”月”的月份 ddd 年中的天 dd 月中的天 d 周中的天 hh 12小时制 hh24 24小时制 mi 分钟 ss 秒 xff 毫秒 add_months(c1,c2) 在某个日子上增加多少个月c1:日期 c2:整数值 select add_months(sysdate,-1) from dual; months_between(c1,c2) 计算两个日期之间的月份计算方式:c1- c2 last_day():计算给定日期的所在月份的最后一天next_day(c1,c2)c1:日期 c2:周中的某天 字符函数lower():转换成小写upper():转换成大写initcap():首字母大写length():求长度substr(c1,c2,c3) 截取字符串c1:被截取的字符串 c2:从哪个位置开始截取 c3:截取长度 默认截取到最后 instr(c1,c2,c3,c4) 索引字符串c1:被查询的字符串 c2:希望找到的字符 c3:从哪个位置开始找 默认为1 c4:第几次出现 select instr(‘woshizhizhuxia’,’z’,1,2) from dual; concat(c1,c2) 拼接字符串 也可以用 || 拼接字符串Ipad(c1,c2,c3) 左侧补全rpad(c1,c2,c3)右侧补全c1:希望补全的字符串 c2:补全到多少位 c3:以哪个字符来补全 trim(c1) 默认c1两侧去除空格trim(c1 from c2) 把c2的两侧溢出指定的c1ltrim(c1,c2) 左侧去除rtrim(c1,c2)右侧去除c1:被去除的字符串 c2:去除的字符串 默认是空格 replace(c1,c2,c3) 完全替换c1:原字符串 c2:被替换的字符串 c3:替换的字符串 通用函数nvl():空值处理nvl(字段,替换显示的内容)nvl2():空值处理二代nvl2(字段,不是空显示什么,是空显示什么)decode(c1,c2,c3,c4,c5,….Cx,Cx+1)c1:原来拿来判断的值 从第二个参数开始,每两个参数看作是一组,拿每一组的第一个参数和c1进行比较 如果相同则返回该组的第二个参数 第一次判断:c2==c1?c3: 第二次判断:c4==c1?c5: 如果参数个数是奇数个,并且最终判断没有相同的数据,则返回空 如果参数个数是偶数个,并且最终判断没有相同的数据,则返回最后一个参数的值 条件取值语句:,(case email –开始条件取值 when ‘3’ –当条件成立 then salary+200 –则 when ‘7’ then salary-200 else salary+500 –默认值 end) –结束 排序 order by排序字段:desc 代表降序 asc 代表升序 order by 后面可以加多个字段 order by 字段1 desc,字段2 asc 分组 group by(前面不能用where 可以在后面用having)根据某一个或多个列上的值,将该列上相同的值所在的记录划分为一个组,这样一张表就可以被划分为多个组,如 果以字段A分组,那么只能直接查询A。 或者用组函数统计其他字段,不能直接查询其他字段。 约束主键约束:primary key 可在表中唯一确定数据的列,主键列应为非空且唯一。 一张表只能有一个主键 外键约束:foreign key 也可以写references在子表中,若一个列上的值引用了母表中主键上的值,这个列便是外键。 非空:not null唯一:unique检查:check 如何添加约束 在创建表时直接添加约束 12345678alter table 表名 add constraint 约束名 约束;Ex:alter table test add constraint a primary key(id);除not null(有些特殊)alter table test modify 列名 constraint 约束名 not null;Ex:alter table test modify salary constraint a not null; 如何删除约束 1alter table 表名 drop constraint 约束名; 多表查询内连接:inner join on 可简写为 join on展示出两张表中有对应关系的数据,可以理解为取交集; 外连接*左外连接:left join on * 展示左表中的全部数据和右表中与左表有对应关系的数据; Ex:select * from student s left join class c on s.sid = c.id; 右外连接;right join on 展示右表中的全部数据与左表中与右表有对应关系的数据; Ex:select * from student s right join class c on s.sid = c.id; 全连接:full join on显示两张表中有对应关系的数据,无对应关系的也展示。 交叉连接(笛卡尔积):cross join显示两张表中的数据一一交叉对应。 什么时候用多表查询?什么时候用子表查询?如果查询数据在多个表内,要使用多表连接。 如果不使用子表的数据,只需要使用子表来当条件,需使用子表查询。 子查询中使用了In some any all 这几个关键字,效率低,可以使用多表关联的方式。 rownumrownum是一个伪列,也就是说不是真是存在的,它是随着结果集生成的。 rownum都是从1开始的。 当我们输入:select * from 表 where rownum >5;不会匹配出任何数据,因为oracle只能确定第一个是哪个, 其他的它并不知道从那开始,认定为false; *想要实现 rownum > n * rownum 本身是不行的,但是可以先查出一个记过集合,既子查询。 * 实现rownum > n 时注意问题 rownum 不能与order by 同一查询语句中出现。(但在子查询中可使用order by) 不能使用 表名.rownum 若rownum在where之后,只能写rownum > 0 || rownum < 任意数 || rownum >= 1 Ex: 12345678910select * from ( select rownum rn,e.* from ( select * from student order by salary )e where rownum < 9 //这里已经将取出的结果集再次排序 )where rn > 5; 分页时确定当页从哪开始 开始数:int startcount = (curpage -1 ) * pagesize + 1; 结束数:int endcount = curpage * pagesize; rowid是映射每一行物理地址的唯一标识,通常用于删除完全重复的数据。 12//删除重复的数据delete from table_name where rowid not in (select min(rowid) from table_name); 联合关键字: unionunion: select * from school where name like ‘%大’ union select * from school where name like ‘北%’; 若第一条语句中包含第二句中查询的内容,则只展示第一条语句查询的内容。 union all 若第一条语句中包含第二句中查询的内容,都展示出来。 intersect 求交集只展示两条语句查询的内容重复部分。 minus 从第一个查询结果中减去第二个结果中重复出现的in(效率低,用exists代替) not in表示条件符合查询结果中某一个值就成立。 Ex:select * from school where id in (select sid from stduent); select * from school where id not in (select sid from stduent); some/any用法与In相同,In用于无符号,some/any 用与有符号。 all 表示所有的值都大或都小(min,max代表第二条语句中的最大值最小值)>any == >min <any == <max >all == >max <all == <min 序列 sequence一个单独的数据对象,是一个能够生成有序的整数列值的对象。 一般oracle调用序列来实现主键自增。 在一个新的会话中,必须要调用下一个值才能获得当前的值。 如何创建序列create sequence 序列名; create sequence seq_student increment by 1/-1 –增长,一次增1 正数+1 负数-1 start with 1 –从1开始 升序默认就是+1 降序-1 minvalue 1 –最小值 -10的26次幂 maxvalue 100 –最大值 10的27次幂 序列超过最大值后会从minvalue 的数字重新开始 cycle –循环 默认nocycle nocache; –不缓存 cache 4 默认生成20个序列号 查询当前用户有多少序列select * from user_sequences; 获取下一个序列的值序列名.nextval 如何获取当前序列的值select 序列名.currval from dual; 如何删除序列drop sequence 序列名; 如何修改序列alter sequence 序列名 想要修改的序列条件; 消除延迟段创建特性alter session set deferred_segment_creation=false; View视图定义视图 由SELECT查询语句定义的逻辑表,只有定义并无数据,在创建视图时,只是将视图的定义信息保存在数据字典中,并不将任何实际数据复制即不在表空间中分配存储空间。可以像使用表一样使用视图(使用视图的时候只是重新执行了SQL)。 通过视图看到的数据并不存储在视图中,数据存储在定义视图时查询的表(基表)。若基表中的数据发生改变视图也会自动更新。(若基表结构发生改变 ,则需要 ALTER VIEW 视图名 COMPILE) 一个视图可以从另一个视图中产生。 Oracle 的数据库对象分为五种:表,视图,序列,索引,同义词。 为什么要使用视图 使用视图,可以定制用户数据,焦距特定的数据(即用户只能看到特定的行或列)。 Ex:不同职位需求的数据不同,可以通过视图将特定的数据展示给特定的需求。 简单 Ex:在查询表中特定的某些数据时,需要调用一些函数,或者关联其他的表,最后写出的SQL语句长,复杂。若查询经常执行可以创建一个视图,再次查询时只SELECT * FROM 视图名 就OK了。 视图基本语法 创建视图 1234CREATE [OR REPLACE][FORCE][NOFORCE] VIEW view_name AS SELECT_STATEMENT[WITH CHECK OPTION[CONSTRAINT constraint_name]][WITH READ ONLY] REPLACE: 如果创建视图时,已经存在此视图,则重新创建此视图,相当于覆盖。 FORCE:强制创建视图,不论视图依赖的基表是否存在或者是否有权限创建。 NOFORCE:只有在基表存在且拥有创建权限才创建视图。 WITH CHECK OPTION :指出在视图上进行修改要符合SELECT_STATEMENT锁指定的限定条件。 WITH READ ONLY:默认可以通过对基表进行增删改查操作,WITH READ ONLY只允许查看视图,现实开发中并不会通过视图对基表进行增删改操作。 视图的定义原则 视图的查询可以使用复杂的 SELECT 语法,包括 连接/分组 和 子查询。 没有 WITH CHECK OPTION 和 READ ONLY,查询中不能使用 ORDER BY 子句。 OR REPLACE:不删除原视图便可更改其定义并重建,并重新赋予对象权限。 删除视图 删除视图的定义并不会影响基表的数据。 只有视图所有者或者拥有DROP VIEW权限的用户可以删除视图。 视图删除后,基于视图创建的其他视图将无效。 1DROP VIEW view_name; 视图分类 简单视图 只从单表获取数据。 不包含函数和数据组。 可以进行DML操作(不建议)。 复杂视图 从多个表里获取数据。 包含函数和数据组。 小结视图适用于查询数据。 不要通过视图更改基表数据! 不要通过视图更改基表数据! 不要通过视图更改基表数据! 重要事情说三遍。 Tablespace概念表空间:是一个或多个数据文件的逻辑集合。 表空间逻辑存储对象: 永久段: 如表,索引,存储过程,视图。 临时段:如临时表或排序段 回滚段(UNDO):主要用于事物回滚,恢复,撤销数据 逻辑结构: block –>extent –>segment–>tablespace–>database 创建表空间: 12345CREATE TABLESPACE tablespace_name nologging DATAFILE '' --文件存在位置SIZE 100M --表空间初始大小AUTOEXTEND ON TEXT --下一次扩展大小MAXSIZE --最大值 在创建时给用户指定表空间 1CREATE USER user_name IDENTIFY BY password DEFAULT TABLESPACE tablespace_name; 更改用户表空间 1ALTER USER user_name DEFAULT TABLESPACE tablespace_name; 删除表空间(删除表空间后,需要为原指向此表空间的用户重新指定表空间) 1DROP TABLESPACE tablespace_name [INCLUDING ONTENTS AND DATAFILES]; Index索引类型: 普通索引 1CREATE INDEX index_name on table_name(字段) 唯一索引 unique 1CREATE UNIQUE INDEX index_name on table_name(字段) 位图索引 bitmap //这种索引适合用在数据量比较大,基数比较小的列 Ex:男/女 1CREATE BITMAP INDEX index_name on table_name(字段) 函数索引 1CREATE INDEX index_name on table_name(函数(列名)) 操作索引 重命名索引 1ALTER INDEX index_name rename to new_name; 查看索引 1SELECT index_name,index_type,tablespace_name,uniqueness from all_indexes where table_name = 'tablename'; 删除索引 1DROP INDEX index_name; 合理使用索引创建唯一性索引,保证数据库表中每一行数据的唯一性。 大大加快数据的检索速度。 加速表与表之间的连接,特别是在实现数据的参考完整性方面特别有意义。 与此同时 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加 索引需要占用物理空间,除了数据表占据空间之外,每一个索引都要占据一定的物理空间。 当对表中的数据进行增加,删除和修改的时候,索引也要动态的维护,降低了数据的维护速度。 存储过程 procedure所谓存储过程就是在服务器端,能够被一个或多个应用程序调用的一段sql语句集。 创建存储过程:123456789101112131415161718192021CREATE OR REPLACE PROCEDURE过程名(参数名 in 参数类型,参数名 in 参数类型,参数名 out 参数类型,参数名 out 参数类型)AS 变量名 变量类型:=值;beginsql语句集end;Ex:create or replace procedurepro_hi(key in number,value out varchar)asbeginif key=1then value = '你好'if key=2then value = '再见'end if;end if;end;/ 存储过程可以没有参数,如果没有参数则过程名之后不能出现括号。 存储过程可以有参数,可有多个参数传入或传出,也可只有传入或传出。 传入参数用in标明,传出参数用out表明。 存储过程并没有返回值,而是通过返回参数来返回数据的。 调用存储过程:123456789101112131415declare变量 类型:=初始值;begin过程名(参数,变量);end;Ex:declare val varchar2(20):='';beginpro_hi(1,val);dbms_output.put_line(val);pro_hi(2,val);dbms_output.put_line(val);end; 触发器 trigger触发器,当某个事件发生时自动的隐式运行。 for each row 行级触发器 创建触发器123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657create or replace trigger trigger_namebefore/after insert/update/delete on table_namefor each rowbeginsql语句集;end;Ex:--创建表create table good(id int primary key,good_name varchar2(20));--创建序列create sequence seq_ids;--创建触发器create or replace trigger tri_insert_goodbefore insert on goodfor each rowbeginselect seq_ids.nextvalinto:new.idfrom dual; --从序列中生成一个新的数值,赋值给当前插入行的ID列end;--增加数据,触发器insert into good(good_name)values('苹果');--创建日志表create table test_log(name varchar2(20),time date);--创建触发器create or replace trigger test_deptbefore delete or insert or update on deptdeclare var_tag varchar2(20);--声明一个变量,存储对dept表执行的操作类型beginif inserting thenvar_tag :='insert';elsif updating thenvar_tag :='update';elsif deleting thenvar_tag :='delete';end if;insert into test_log values(var_tag,sysdate);--向日志表中插入对dept表的操作信息end;--分别执行语句对dept表进行操作insert into dept values(66,'教育部','济南');update dept set loc='易途' where deptno = 66;delete from dept where deptno=66;select * from dept;select * from test_log; SQL优化 建议不要用*代替所有列名,需要什么查什么。 建议使用truncate代替delete(truncate在删除数据上比delete效率高)。 在确保语句的完整性的前提下尽量使用commit。 用exists代替in。 SQL语句写的时候尽量用大写,节省编译时间。 SQL语句中给表使用别名,减少解析时间。 合理使用索引。 表连接在where条件之前,数据多的纪录在where字句的末尾,表连接之前过滤掉的数据越多越好。 优化group by,将不需要的纪录在group by之前过滤掉。 尽量减少表的查询次数。 查询低效率执行的SQL123456789 SELECT EXECUTIONS,DISK_READS,BUFFER_GETS, ROUND((BUFFER_GETSDISK_READS)/BUFFER_GETS,2)HIT_RADIO,ROUND(DISK_READS/EXECUTIONS,2) Reads_per_run,SQL_TEXTFROM V$SQLAREA WHERE EXECUTIONS > 0 AND BUFFER_GETS > 0 AND (BUFFER_GETS-DISK_READS)/BUFFER_GETS < 0.8 ORDER BY 4 DESC; 常见语句关键字优先级from –优先级最高 where –优先级比from低 group by –优先级比where低 having – 优先级在group by之后 select –优先级高于order by order by –优先级最低]]></content>
<categories>
<category>Oracle</category>
</categories>
<tags>
<tag>Oracle</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Java类型转换]]></title>
<url>%2F2018%2F03%2F07%2FJava%E7%B1%BB%E5%9E%8B%E8%BD%AC%E6%8D%A2%2F</url>
<content type="text"><![CDATA[今天对Java基本类型的转换有了一些新的认知,记录下来。 Java 基本类型转换Java中数据类型主要分为两大类:基本数据类型和引用数据类型。基本数据类型共8种,分别为:布尔型 boolean 未知 字 符型 char 2字节 数值型 byte 1字节 short 2字节 int 4字节 float 4字节 long 8字节 double 8字节。 引用数据类型可分为:类,接口,数组。 在Java中,整数类型(byte/short/int/long)中,对于未声明数据类型的整形,其默认类型为int型。在浮点类型 (float/double)中,对于未声明数据类型的浮点型,默认为double型。 布尔类型boolean占有一个字节,由于其本身所代码的特殊含义,boolean类型与其他基本类型不能进行类型的转换(既不 能进行自动类型的提升,也不能强制类型转换), 否则,将编译出错。 基本数据类型之间的转换图: 在定义基本类型变量时,每种基本类型的取值范围是有限的,若定义值超出取值范围,则编译错误。Java整数类型取值范 围计算公式(-2^(n-1) 到 2^(n-1)-1),浮点类型取值范围为float:符号位1 + 幂值位8 + 数值位23,double:符号位1 +幂值 位11 + 数值位52。 超出取值范围错误原因:jvm在编译过程中,对于默认为int类型的数值时,当赋给一个比int型数值范围小的数值类型变量(在此统一称为数值类型k,k可以是byte/char/short类型),会进行判断,如果此int型数值超过数值类型k,那么会直接编译出错。因为你将一个超过了范围的数值赋给类型为k的变量,k装不下嘛,你又没有进行强制类型转换,当然报错了。但是如果此int型数值尚在数值类型k范围内,jvm会自定进行一次隐式类型转换,将此int型数值转换成类型k。这一点有点特别,需要稍微注意下。例如: 123byte a = 1000;float b = (float)3.12;byte c = 3; char类型转换特别之处:char型其本身是unsigned型,同时具有两个字节,其数值范围是0 ~ 2^16-1,因为,这直接导致byte型不能自动类型提升到char,char和short直接也不会发生自动类型提升(因为负数的问题),同时,byte当然可以直接提升到short型。 强制类型转换中,可能会出现负数的输出,如例: 123int a = 233;byte b = (byte)a;System.out.println(b); 上面的例子中输出值是 -23. 为什么结果是-23?需要从二进制存储考虑。 233的二进制表示为:24位0 + 11101001,byte型只有8位,于是从高位开始舍弃,剩下:11101001,由于二进制最高位1表示负数,0表示正数,符号位不变取反,其相应的负数为-23。 若想求负数的二进制,有两种方法:方法①:则他的计算公式为 -N = ~N + 1, ~ 为取反的意思。方法②:用反码补码来计算。(先确定原码,再确定反码(原码符号位不变,其余位取反。),再确定补码(反码 + 1)。注:二进制在计算机中以补码的方式存放的。)例如: 1234-23 的二进制表达首先确定-23的原码位 10111 加上符号位为 110111再确定反码为 101000再确定补码为 101001 再将位数补全(int类型) 加上26位1 当进行数学运算时,数据类型会自动发生提升到运算符左右之较大者,以此类推.当最会的运算结果赋值给指定数值类型时,可能会需要强制类型转换。例如: 123int a = 9;byte b = 1;byte c = (byte)(a + b); Java 按位取反运算符”~” 如何运算正数的原码,反码,补码是一样的!既: 正数9(二进制为:1001)在内存中存储为01001,必须补上符号位(开头的0为符号位)。补码为01001,反码为01001,其中前面加的0是符号位,负数的符号位用1表示 负数-1(二进制为:0001)在内存中存储为10001,开头的1为符号位,在内存中存放为,11111(负数的补码是:符号位不变,其余各位求反,末位加1)既得到11111。 补码为11111 反码为11110 也就是说在求负数的反码.补码时,负数的补码是:符号位不变,其余各位求反,末位加1,既-1的补码为11111,反码是:符号位为1,其余各位求反,但末位不加1,既-1的反码为11110。反码 + 1既是补码。 1234实例: 求~8,计算步骤如下。8的二进制 1000 则补码为:加上符号位 01000取反为 10111 这是~8的补码 求反码既 -1 为 10110符号位不变再次取反为原码 11001 既-9 参考https://www.cnblogs.com/liujinhong/p/6005714.html http://blog.csdn.net/smilecall/article/details/42454471]]></content>
<categories>
<category>Java</category>
</categories>
<tags>
<tag>Java 基本类型</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Mysql5.6部署]]></title>
<url>%2F2018%2F01%2F19%2FMysql5-6%E9%83%A8%E7%BD%B2%2F</url>
<content type="text"><![CDATA[Centos安装Mysql,方便以后安装。 数据库 安装必要的组件 12# yum install –y autoconf automake imake libxml2-devel\ expat-devel cmake gcc gcc-c++ libaio libaio-devel bzr bison libtool ncurses5-devel 下载解压mysql软件 12345# cd /usr/local/src# wget -c http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.14-linux-glibc2.5-x86_64.tar.gz -O mysql-5.6.14-linux-glibc2.5-x86_64.tar.gz# tar zxvf mysql-5.6.14-linux-glibc2.5-x86_64.tar.gz –C ../# cd /usr/local/# ln -s mysql-5.6.14-linux-glibc2.5-x86_64 mysql 创建Mysql用户组和用户,及数据库存放目录: 1234567# mkdir -p /data/mysql_data_3306# mkdir -p /data/mysql_log# mkdir -p /data/log-bin# groupadd mysql# useradd mysql -g mysql -M -s /sbin/nologin# chown -R mysql.mysql /data/mysql_data_3306 /data/mysql_log /data/log-bin# chown -R mysql.mysql /usr/local/mysql-5.6.14-linux-glibc2.5-x86_64 配置文件(依具体环境) 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566# vi /etc/my.cnf [mysqld]# GENERAL #user = mysqldefault-storage-engine = InnoDBsocket = /data/mysql_data_3306/mysql.sockpid-file = /data/mysql_data_3306/mysql.pidport = 3306# MyISAM #key_buffer_size = 1344Mmyisam_recover = FORCE,BACKUP# SAFETY #max_allowed_packet = 16Mmax_connect_errors = 1000000skip_name_resolve# DATA STORAGE #datadir = /data/mysql_data_3306/long_query_time = 1# BINARY LOGGING #log-bin = /data/log-bin/mysql-bin-3306expire-logs-days = 14sync-binlog = 1server-id = 1max_binlog_size = 500M# REPLICATION #relay-log = /data/log-bin/relay-bin-3306slave-net-timeout = 60# CACHES AND LIMITS #tmp_table_size = 32Mmax_heap_table_size = 32Mmax_connections = 500thread_cache_size = 50open_files_limit = 65535table_definition_cache = 4096table_open_cache = 4096# INNODB #innodb_data_file_path = ibdata1:128M;ibdata2:10M:autoextendinnodb_flush_method = O_DIRECTinnodb_log_files_in_group = 2innodb_lock_wait_timeout = 50innodb_log_file_size = 256Minnodb_flush_log_at_trx_commit = 1innodb_file_per_table = 1innodb_thread_concurrency = 8innodb_buffer_pool_size = 8G# LOGGING #log-error = /data/mysql_log/mysql-error-3306.loglog-queries-not-using-indexes = 1slow-query-log = 1long_query_time = 1slow-query-log-file = /data/mysql_log/mysql-slow-3306.log# FOR SLAVE ##binlog-format = ROW#log-slave-updates = true#gtid-mode = on#enforce-gtid-consistency = true#master-info-repository = TABLE#relay-log-info-repository = TABLE#sync-master-info = 1#slave-parallel-workers = 2#binlog-checksum = CRC32#master-verify-checksum = 1#slave-sql-verify-checksum = 1#binlog-rows-query-log_events = 1#report-port = 3306#report-host = 10.1.1.10 系统服务 12345# cp -af /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld_3306# vi /etc/init.d/mysqld_3306修改两处位置:basedir=/usr/local/mysqldatadir=/data/mysql_data_3306 执行如下命令 123# chmod 755 /etc/init.d/mysqld_3306# chkconfig --add mysqld_3306# chkconfig --level 345 mysqld_3306 on 初始化数据库 12# cd /usr/local/mysql# ./scripts/mysql_install_db --user=mysql --defaults-file=/etc/my.cnf 启动数据库进程 1# service mysqld_3306 start 修改root密码 1234# /usr/local/mysql/bin/mysql -p -uroot -S /tmp/mysql.sock #这里直接回车就能进入数据库系统Mysql> delete from mysql.user where user='';Mysql> update mysql.user set password=PASSWORD(“1qaz2wsx”) where user='root';Mysql>flush privileges; 配置环境变量export mysql所在路径]]></content>
<categories>
<category>数据库</category>
</categories>
<tags>
<tag>Mysql</tag>
</tags>
</entry>
<entry>
<title><![CDATA[Shell]]></title>
<url>%2F2017%2F11%2F07%2FShell%2F</url>
<content type="text"><![CDATA[Shell是命令语言也是程序设计语言,最近在学习Linux,感觉会写点Shell脚本是一个程序员的标配,下面要系统学习一下Shell。 Shell变量 调用变量:${变量名} (字符串与数组类似) 获取变量长度:${#变量名} (字符串与数组类似) 字符串的截取与拼接还是非常有用的[#,##,%,%%等8种字符串截取],个人是参考菜鸟教程 基本运算符 expr表达式计算工具,格式: `expr $a 运算符 $b` (或者可以使用”$[]”可以进行基本运算,不同之处在于不能有空格。) 格式:if 逻辑运算 then ... else ... fi Shell获取参数 方法内 $1 2 3 4 5…[若参数个数大于10,则需${10}] $* 与 $@ 是有区别的。 $*:若参数为 1 2 3 ,以一个单字符串显示所有向脚本传递的参数。 $@:与$*相同,但是使用时加引号,并在引号中返回每个参数。 感觉shell语法跟其他编程语言还是差不多的,但书写上还是有些差别。]]></content>
<categories>
<category>Linux</category>
</categories>
<tags>
<tag>shell</tag>
</tags>
</entry>
</search>