文章列表

开发人员不得不知的MySQL索引和查询优化

作者:微信小助手

<section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="padding-top: 10px;padding-right: 10px;padding-left: 10px;box-sizing: border-box;background-color: rgb(239, 239, 239);"> <span style="display: inline-block;width: 5%;line-height: 0.8;font-weight: bolder;font-size: 48px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> “ </section></span> <section style="display: inline-block;vertical-align: top;float: right;width: 90%;line-height: 1.5;font-size: 15px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><span style="letter-spacing: 1px;">本文主要总结了工作中一些常用的操作及不合理的操作,在对慢查询进行优化时收集的一些有用的资料和信息,本文适合有 MySQL 基础的开发人员。</span></p> </section> <section style="clear: both;box-sizing: border-box;"></section> </section> </section> </section> </section> <p style="line-height: 1.75em;"><br></p> <section label="Powered by 135editor.com" data-role="outer"> <section label="Powered by 135editor.com" data-role="outer"> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="" data-copyright="0" data-ratio="0.5635792778649922" data-s="300,640" src="/upload/963fc715904246caec61fe1ee22780ec.png" data-type="png" data-w="637" style=""></p> <section data-tools="135编辑器" data-color="#138bde" data-id="86122"> <section> <section> <section> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">索引相关</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> </section> <section data-tools="135编辑器" data-color="#138bde" data-id="39"> <section data-tools="135编辑器" data-color="#138bde" data-id="39" data-custom="#1e9be8"> <section> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span><span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span></strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>索引基数</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">基数是数据列所包含的不同值的数量,例如,某个数据列包含值 1、3、7、4、7、3,那么它的基数就是 4。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">索引的基数相对于数据表行数较高(也就是说,列中包含很多不同的值,重复的值很少)的时候,它的工作效果最好。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">如果某数据列含有很多不同的年龄,索引会很快地分辨数据行;如果某个数据列用于记录性别(只有“M”和“F”两种值),那么索引的用处就不大;如果值出现的几率几乎相等,那么无论搜索哪个值都可能得到一半的数据行。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">在这些情况下,最好根本不要使用索引,因为查询优化器发现某个值出现在表的数据行中的百分比很高的时候,它一般会忽略索引,进行全表扫描。惯用的百分比界线是“30%”。</span></p> <p style="line-height: normal;"><br></p> <section data-tools="135编辑器" data-color="#138bde" data-id="39"> <section data-tools="135编辑器" data-color="#138bde" data-id="39" data-custom="#1e9be8"> <section> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span><span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span></strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>索引失效原因</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">索引失效的原因有如下几点:</span></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">对索引列运算,运算包括(+、-、*、/、!、&lt;&gt;、%、like'%_'(% 放在前面)。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">类型错误,如字段类型为 varchar,where 条件用 number。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">对索引应用内部函数,这种情况下应该要建立基于函数的索引。例如 select * from template t where ROUND (t.logicdb_id) = 1,此时应该建 ROUND (t.logicdb_id) 为索引。</span></p><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">MySQL 8.0 开始支持函数索引,5.7 可以通过虚拟列的方式来支持,之前只能新建一个 ROUND (t.logicdb_id) 列然后去维护。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">如果条件有 or,即使其中有条件带索引也不会使用(这也是为什么建议少使用 or 的原因),如果想使用 or,又想索引有效,只能将 or 条件中的每个列加上索引。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">如果列类型是字符串,那一定要在条件中数据使用引号,否则不使用索引。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">B-tree 索引 is null 不会走,is not null 会走,位图索引 is null,is not null 都会走。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">组合索引遵循最左原则。</span></p></li> </ul> <section data-tools="135编辑器" data-color="#138bde" data-id="39"> <section data-tools="135编辑器" data-color="#138bde" data-id="39" data-custom="#1e9be8"> <section> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span></strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>索引的建立</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(71, 193, 168);letter-spacing: 1px;">索引的建立需要注意以下几点:</span></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">最重要的肯定是根据业务经常查询的语句。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">尽量选择区分度高的列作为索引,区分度的公式是 COUNT(DISTINCT col) / COUNT(*),表示字段不重复的比率,比率越大我们扫描的记录数就越少。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">如果业务中唯一特性最好建立唯一键,一方面可以保证数据的正确性,另一方面索引的效率能大大提高。</span></p></li> </ul> <section data-tools="135编辑器" data-color="#138bde" data-id="86122"> <section> <section> <section> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">EXPLIAN 中有用的信息</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> </section> <section data-tools="135编辑器" data-color="#138bde" data-id="39"> <section data-tools="135编辑器" data-color="#138bde" data-id="39" data-custom="#1e9be8"> <section> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span><span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span></strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>基本用法</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> </section> </section> <p><span style="color: rgb(71, 193, 168);font-size: 15px;letter-spacing: 1px;line-height: 28px;text-align: justify;">EXPLIAN&nbsp;基本用法如下:</span></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">desc 或者 explain 加上你的 SQL。</span></p></li> <li><p style="text-align: justify;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">extended explain 加上你的 SQL,然后通过 show warnings 可以查看实际执行的语句,这一点也是非常有用的,很多时候不同的写法经 SQL 分析后,实际执行的代码是一样的。</span></p></li> </ul> <section data-tools="135编辑器" data-color="#138bde" data-id="39"> <section data-tools="135编辑器" data-color="#138bde" data-id="39" data-custom="#1e9be8"> <section> <p style="line-height: normal;"><br></p> <section style="box-sizing: border-box;"> <section class="V5" style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="width: 0.6em;display: inline-block;vertical-align: middle;box-sizing: border-box;"> <span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.2;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span> <strong><span style="width: 0.6em;height: 0.6em;display: block;opacity: 0.6;margin-top: 2px;margin-bottom: 2px;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span><span style="width: 0.6em;height: 0.6em;display: block;opacity: 1;box-sizing: border-box;background-color: rgb(89, 89, 89);"></span></strong> </section> <section style="display: inline-block;vertical-align: middle;font-size: 18px;padding-left: 5px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><strong>提高性能的特性</strong></p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">EXPLIAN&nbsp;提高性能的特性如下:</span></p> </section> </section> </section> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p style="text-align: justify;line-height: 1.75em;"><strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">索引覆盖(covering index):</span></strong><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">需要查询的数据在索引上都可以查到不需要回表 EXTRA 列显示 using index。</span></p></li>

Java优秀的第三方库

作者:じ☆ve宝贝

几乎每个程序员都知道要“避免重复发明轮子”的道理——尽可能使用那些优秀的第三方框架或库,但当真正进入开发时,我却经常发现他们有时并不知道那些轮子在哪里。最近,我在业余时间带几个年轻的程序员一起做了一个很小的商业项目,而在一起开发的过程中,我几乎在所有需要判断字符串是否为空的地方,看到了下面的代码: ` if(inputString == null || inputString.length == 0){......} ` 除了字符串判断是否为空之外,还有很多字符串处理或其他数据类型判断的方法,缺少经验的程序员们往往都会想办法自己来写。这些代码当然都没有错,但我们应该尽可能去利用那些已经非常成熟的第三方库,以更标准的方式去解决这些通用的问题,并且提高开发效率。 下面便是我整理的,在大部分项目中使用到的优秀JAVA第三方库 ,供大家参考: ------------ ###JAVA核心扩展 正如前面说到的字符串判断的例子,JAVA的标准库虽然提供了那些最基本的数据类型操作方法,但仍然对一些常见的需求场景,缺少实用的工具类。而另一些则是JAVA标准库本身不够完善,需要第三方库去加以补充的。 ####Apache Commons Lang Apache Commons Lang是Apache最著名的JAVA库 (GitHub上的代码库),它是对java.lang的很好扩展,包含了大量非常实用的工具类,其中用的最多的有StringUtils,DateUtils,NumberUtils等。之前提到的代码利用StringUtils可以改写为: ` if(StringUtils.isBlank(inputString)){...} ` 除了Apache Commons Lang,还有一些其他的Apache库也是对JAVA本身的很好补充,如Apache Commons Collection,Apache Commons IO,Apache Commons Math 在Maven项目中加入Apache Commons Lang这个库: ``` <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.4</version> </dependency> ``` ####Google Cuava Google Cuava在国内项目中很少使用,但我合作过的一些国外JAVA工程师几乎都会推荐这个JAVA库。它包含了Google在自己的JAVA项目中所使用的一些核心JAVA库。包含了对:**集合,缓存,并发库,字符串处理, I/O等各个方面的支持**。另外Google开发的库总是以性能著称。 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>19.0</version> </dependency> ``` ####Joda-Time Java SE 8之前的JAVA版本中对日期的支持是比较差的,Joda-Time被经常被使用来替换原有的日期系统,它能够支持更多的日历体系,并提供了很多非常方便的日期处理方法,而且它的性能也是非常出色的。(GitHub上的代码库) 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.9.3</version> </dependency> ``` ------------ ###Web框架 Web框架是一个应用最核心的部分,因此我总是推荐使用那些最标准的,并且有良好社区支持的框架,比如Spring和Struts。 ####Spring Spring是一个开源的应用框架,它包含很多子项目比如Spring MVC, Spring Security, Spring Data,Sping Boot等等,几乎可以满足你项目上的所有需要。它也是我开发Web项目的首选后端框架。 添加下面的引用,在Spring MVC项目中加入这个库(以下仅引入Spring Core的支持) ``` <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.5.RELEASE</version> </dependency> ``` ####Struts 2 Struts 2 是Apache最有名的Web框架,它也是一个免费开源的MVC框架。Struts也能很好地支持REST,SOAP,AJAX等最新技术。 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>org.apache.struts</groupId> <artifactId>struts2-core</artifactId> <version>2.3.28</version> </dependency> ``` 除了上面提到的两个最长哟你的Web框架之外,还有如Google Web Toolkit, Tapestry, Strips等一些优秀的框架可供选择 。 ------------ ###数据库(持久层) 持久层框架的选择对一个项目的成败同样非常关键,它会直接影响到系统的性能、质量、安全以及稳定性。 ####MyBatis MyBatis是我最喜欢的数据库(持久层)框架,因为它完全是基于SQL语句的(通过SQL来提取数据并自动映射为所需的数据对象),能够为我带来足够的灵活性。 添加下面的引用,在Maven项目中加入这个库(如需配合Spring使用,可选择对应的Maven库) ``` <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.0</version> </dependency> ``` ####Spring JDBC / Spring Data Spring JDBC并不是独立的Spring子项目,而是一个整合在Spring核心库内,为JDBC操作提供基本封装处理的模块。通过简单的配置后,可以通过对Context中的jdbcTemplate进行调用来获得结果。 ``` String SQL = "select name from Student where id = ?"; String name = jdbcTemplateObject.queryForObject(SQL, new Object[]{10}, String.class); ``` Spring Data是Spring的一个子项目,提供了更加强大的持久层功能封装,和对象映射功能。它能与Spring MVC很好地整合。你可以利用JPA和CrudRepository来极大简化持久层的开发。 ``` public interface EmployeeRepository extends CrudRepository<Employee, Long> { Employee findByFirstName(String firstName); List<Employee> findByLastName(String lastName); } ``` ####Hibernate 可能是国内用得最广泛的持久层框架了,它非常强大,但用好它并不容易,你需要了解它的内部机制,否则可能会出现一些无法预见的性能问题,特别是在数据量特别大的时候。(GitHub上的代码库) 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>5.1.0.Final</version> </dependency> ``` 除了上面一些最常用的持久层库,还有几个优秀的库,比如 JDO,JOOQ,Apache DbUtils等 ------------ ###日志 JAVA中也包含了日志记录功能,但它在处理日志分级,日志的存储,以及日志的备份、归档方面都不够出色,因此在项目中我们一般都会使用第三方日志库来处理日志。 ####SLF4J- Simple Logging Facade for Java (SLF4J) SLF4J为我们提供了一个日志服务的抽象层,基于它你可以选择不同的日志实现,比如:java.util.logging,logback,log4j,当你需要改变日志实现组件时,不需要修改任何代码,只需要更改一些相应的配置就可以了。 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.21</version> </dependency> ``` ####Apache Log4j Log4j是最有名的日志组件,通过简单的配置后就能在程序中方便地记录各个级别的日志,它的日志文件能够根据不同的规则进行命名以及归档。 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.5</version> </dependency> Logback ``` Logback比Log4j更新,它被视为是log4j的一个替代者。它比log4j的性能更好,而且更完整地实现了SLF4J的接口,并且自带了更多的功能,比如自动压缩日志,更多的filter等。 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.5</version> </dependency> ``` ####JSON JSON已经成为最广泛使用的一种数据传输格式,因此程序中对JSON的处理也正变得越来越多。下面是我推荐的一些JSON处理库: ####Jackson Jackson是一个多用途的Java库,用于处理JSON数据。使用它可以很方便地在JSON数据和Java对象之间进行转换。 ``` ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally User user = mapper.readValue(new File("user.json"), User.class); ``` ####Google Gson Google开发的JSON库,可以实现JSON字符串与JAVA对象之间的转换,使用起来也非常方便。 ``` Gson gson = new Gson(); String[] strings = {"abc", "def", "ghi"}; gson.toJson(strings); // ==> ["abc", "def", "ghi"] ``` ###图表 ####JFreeChart 能够为你生成各种类型的图表,并且支持多种输出格式,包括PNG和JPEG图片格式,以及向PDF,EPS,SVG等矢量图。 ####JasperReports JasperReports提供了一套完整的报表解决方案,帮助用户使用用Java语言来开发具有报告功能的程序。JasperReports的模版采用XML格式,从数据库中抽取数据,并以PDF、HTML、XLS、CSV及XML等各种格式生成报表。它的一大优势是能够处理大数据量的报表。 ###测试 ####JUnit JUnit是目前使用最广泛的JAVA单元测试库通过它,你可以i非常方便地编写自己的单元测试代码,并进行自动化测试。 ``` @Test public void lookupEmailAddresses() { assertThat(new CartoonCharacterEmailLookupService().getResults("looney"), allOf( not(empty()), containsInAnyOrder( allOf(instanceOf(Map.class), hasEntry("id", "56"), hasEntry("email", "roadrunner@fast.org")), allOf(instanceOf(Map.class), hasEntry("id", "76"), hasEntry("email", "wiley@acme.com")) ) )); } ``` 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> ``` ###Office文档处理 ####Apache POI Apache POI是一个免费的开源库用于处理Microsoft Office文档。用它可以使用Java读取和创建,修改MS Excel文件,MS Word和MSPowerPoint文件。(GitHub上的代码库) 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.14</version> </dependency> ``` #####docx4j docx4j是另一套基于JAXB的Office文档(docx,pptx,xlsx)处理库。(GitHub上的代码库) 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>org.docx4j</groupId> <artifactId>docx4j</artifactId> <version>3.3.0</version> </dependency> ``` ###XML解析 ####JDOM JDOM是一个开源项目,它基于树型结构,利用纯JAVA的技术对XML文档实现解析、生成、序列化以及多种操作。在 JDOM 中,XML 元素用 Element 表示,XML 属性用 Attribute 表示,XML 文档本身用 Document 表示。因此这些API都非常直观易用。(GitHub上的代码库) 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>org.jdom</groupId> <artifactId>jdom</artifactId> <version>2.0.2</version> </dependency> ``` ####DOM4J DOM4J是一个处理XML的开源框架,它整合了对于XPath,并且完全支持DOM,SAX,JAXP等技术。 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> ``` ####xerces Xerces是一个开放源代码的XML语法分析器。从JDK1.5以后,Xerces就成了JDK的XML默认实现 添加下面的引用,在Maven项目中加入这个库 ``` <dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId> <version>2.11.0</version> </dependency> ``` 其他值得关注的代码库 ------------ ####jSOUP jSOUP提供了一套与外部互联网的网页(HTML)进行交互的API,能够让使用者非常方便地 利用CSS选择器来解析HTML页面,从而获取需要的内容。 ``` Document doc = Jsoup.connect("http://en.wikipedia.org/").get(); Elements newsHeadlines = doc.select("#mp-itn b a"); ``` ####Lomobok Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO)。它通过注释实现这一目的。通过在IDE中加入Lombok,开发人员可以节省构建诸如 hashCode()和equals()这样的方法以及以往用来分类各种 accessor 和 mutator 的大量时间。 ####Netty Netty是由JBOSS提供的一个java开源框架。Netty提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。也就是说,Netty 是一个基于NIO的客户,服务器端编程框架,使用Netty 可以确保你快速和简单的开发出一个网络应用,例如实现了某种协议的客户,服务端应用。 如果你发现有其他优秀的第三方库,也请在下面的评论中分享,我会继续完善这份清单,使它更具参考价值^_^

MySQL 查询1000万以上数据的解决方案

作者:じ☆ve宝贝

MySQL 导出大量数据时,如果不做分页限制会直接提示java.lang.OutOfMemoryError: Java heap space,如果使用limit加载全部数据的话,limit在超过一定数据量后性能大幅度下降,不能满足我们的需求。查找文档后找到MySQL的JDBC中fetchSize参数可以解决该问题。 ** setFetchSize (int rows) ** :为 JDBC 驱动程序提供一个提示,它提示此 Statement 生成的 ResultSet 对象需要更多行时应该从数据库获取的行数。 ** MysqlExportData.java ** ``` package cn.studyjava; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import cn.studyjava.common.Const; /** * MySQL 导出大批量数据(取回数据量为 6504622 行!总计用时:1270/s, 平均每6万用时12/s) * @author zsljava 2018年1月8日 下午3:44:18 * @since 1.0.0 */ public class MysqlExportData { public static long exportData(String sql) { String url = "jdbc:mysql://localhost:3306/data?user=root&password=XXXX"; try { Class.forName("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e1) { e1.printStackTrace(); } long allStart = System.currentTimeMillis(); long count = 0; Connection con = null; PreparedStatement ps = null; // Statement st = null; ResultSet rs = null; try { con = DriverManager.getConnection(url); ps = (PreparedStatement) con.prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY); ps.setFetchSize(Integer.MIN_VALUE); ps.setFetchDirection(ResultSet.FETCH_REVERSE); // 默认3600 s 的query Timeout(查询超时后自动关闭,因为我们需要流链接,因此不能短时间关闭) ps.setQueryTimeout(Const.SOCKET_TIMEOUT_INSECOND); rs = ps.executeQuery(); System.out.println("开始执行"); long oneStart = System.currentTimeMillis(); while (rs.next()) { // 此处处理业务逻辑 count++; if (count % 60000 == 0) { long end = System.currentTimeMillis(); System.out.println(" 写入到第 " + (count / 60000) + " 个文件中, 用时:" + ((end - oneStart) / 1000) + "/s"); oneStart = end; } } long end = System.currentTimeMillis(); System.out.println("取回数据量为 " + count + " 行!总计用时:"+((end - allStart)/1000)+"/s"); } catch (SQLException e) { e.printStackTrace(); } finally { try { if (rs != null) { rs.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (ps != null) { ps.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (con != null) { con.close(); } } catch (SQLException e) { e.printStackTrace(); } } return count; } public static void main(String[] args) throws InterruptedException { String sql = "select * from company "; exportData(sql); } } ``` ** Const.java ** ``` package cn.studyjava.common; /** * * @author zsljava 2017年12月12日 下午2:22:18 * @since 1.0.0 */ public class Const { public static final int SOCKET_TIMEOUT_INSECOND = 172800; } ``` ** maven pom.xml ** ``` <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.43</version> </dependency> ``` 可以通过MySQL jdbc的fetchSize参数,解决MySQL一次性查询数据量过大时导致内存溢出的问题。 欢迎大家讨论交流

解决线上数据库死锁,就是这么简单!

作者:微信小助手

<section style="box-sizing: border-box;font-size: 16px;"> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="margin-top: 10px;margin-bottom: 10px;box-sizing: border-box;"> <section style="padding-top: 10px;padding-right: 10px;padding-left: 10px;box-sizing: border-box;background-color: rgb(239, 239, 239);"> <span style="display: inline-block;width: 5%;line-height: 0.8;font-weight: bolder;font-size: 48px;box-sizing: border-box;"> <section style="box-sizing: border-box;"> “ </section></span> <section style="display: inline-block;vertical-align: top;float: right;width: 90%;line-height: 1.5;font-size: 15px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;"><span style="letter-spacing: 1px;">前几天,线上发生了一次数据库死锁问题,这一问题前前后后排查了比较久的时间,这个过程中自己也对数据库的锁机制有了更深的理解。</span></p> </section> <section style="clear: both;box-sizing: border-box;"></section> </section> </section> </section> </section> <p style="line-height: 1.75em;"><br></p> <p style="text-align: center;margin-left: 8px;margin-right: 8px;margin-bottom: 5px;"><img class="rich_pages" data-copyright="0" data-ratio="0.5744089012517385" data-s="300,640" src="/upload/4b5e26bc5edba45e168c7cfcc27f5699.png" data-type="png" data-w="719" style=""></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">本文总结了这次死锁排查的全过程,并分析了导致死锁的原因及解决方案。希望给大家提供一个死锁的排查及解决思路。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">本文涉及到 MySQL 执行引擎、数据库隔离级别、InnoDB 锁机制、索引、数据库事务等多领域知识。前车之鉴,后事之师,希望读者们都可以有所收获。</span></p> <p style="line-height: normal;"><br></p> <section class=""> <section style="box-sizing: border-box;font-size: 16px;"> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">现象</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">某天晚上,同事正在发布,突然线上大量报警,很多是关于数据库死锁的,</span><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">报警提示信息如下:</span><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section class="output_wrapper" style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="hljs markdown" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);padding: 0.5em;display: block !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;background: rgb(40, 43, 46);">{"errorCode":"SYSTEM_ERROR","errorMsg":"nested&nbsp;exception&nbsp;is&nbsp;org.apache.ibatis.exceptions.PersistenceException:&nbsp;<br>Error&nbsp;updating&nbsp;database.&nbsp;Cause:&nbsp;ERR-CODE:&nbsp;[<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">TDDL-4614</span>][<span class="hljs-symbol" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">ERR_EXECUTE_ON_MYSQL</span>]&nbsp;<br>Deadlock&nbsp;found&nbsp;when&nbsp;trying&nbsp;to&nbsp;get&nbsp;lock;&nbsp;<br>The&nbsp;error&nbsp;occurred&nbsp;while&nbsp;setting&nbsp;parameters\n###&nbsp;SQL:&nbsp;<br>update&nbsp;fund<span class="hljs-emphasis" style="font-size: inherit;color: inherit;line-height: inherit;font-style: italic;word-wrap: inherit !important;word-break: inherit !important;">_transfer_</span>stream&nbsp;set&nbsp;gmt<span class="hljs-emphasis" style="font-size: inherit;color: inherit;line-height: inherit;font-style: italic;word-wrap: inherit !important;word-break: inherit !important;">_modified=now(),state&nbsp;=&nbsp;?&nbsp;where&nbsp;fund_</span>transfer<span class="hljs-emphasis" style="font-size: inherit;color: inherit;line-height: inherit;font-style: italic;word-wrap: inherit !important;word-break: inherit !important;">_order_</span>no&nbsp;=&nbsp;?&nbsp;and&nbsp;seller_id&nbsp;=&nbsp;?&nbsp;and&nbsp;state&nbsp;=&nbsp;'NEW'<br></code></pre> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">通过报警,我们基本可以定位到发生死锁的数据库以及数据库表。先来介绍下本文案例中涉及到的数据库相关信息。</span></p> <p style="line-height: normal;"><br></p> <section class=""> <section style="box-sizing: border-box;font-size: 16px;"> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">背景情况</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">我们使用的数据库是&nbsp;</span><span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;line-height: 1.75em;">MySQL 5.7,引擎是 InnoDB,事务隔离级别是 READ-COMMITED。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">数据库版本查询方法:</span><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section class="output_wrapper" style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="hljs sql" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);padding: 0.5em;display: block !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;background: rgb(40, 43, 46);"><span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">select</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">version</span>();<br></code></pre> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">引擎查询方法:</span></p> <section class="output_wrapper" style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="hljs sql" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);padding: 0.5em;display: block !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;background: rgb(40, 43, 46);"><span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">show</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">create</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">table</span>&nbsp;fund_transfer_stream;<br></code></pre> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">建表语句中会显示存储引擎信息,形如:ENGINE=InnoDB。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">事务隔离级别查询方法:</span></p> <section class="output_wrapper" style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="hljs css" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);padding: 0.5em;display: block !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;background: rgb(40, 43, 46);"><span class="hljs-selector-tag" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">select</span>&nbsp;@@<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">tx_isolation</span>;<br></code></pre> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">事务隔离级别设置方法(只对当前 Session 生效):</span></p> <section class="output_wrapper" style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="hljs sql" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);padding: 0.5em;display: block !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;background: rgb(40, 43, 46);"><span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">set</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">session</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">transaction</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">isolation</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">level</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">read</span>&nbsp;committed;<br></code></pre> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">PS:注意,如果数据库是分库的,以上几条 SQL 语句需要在单库上执行,不要在逻辑库执行。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">发生死锁的表结构及索引情况(隐去了部分无关字段和索引):</span></p> <section class="output_wrapper" style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="hljs sql" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);padding: 0.5em;display: block !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;background: rgb(40, 43, 46);"><span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">CREATE</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">TABLE</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`fund_transfer_stream`</span>&nbsp;(&nbsp;<br>&nbsp;&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`id`</span>&nbsp;<span class="hljs-built_in" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">bigint</span>(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">20</span>)&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">unsigned</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">NOT</span>&nbsp;<span class="hljs-literal" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">NULL</span>&nbsp;AUTO_INCREMENT&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">COMMENT</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'主键'</span>,<br>&nbsp;&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`gmt_create`</span>&nbsp;datetime&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">NOT</span>&nbsp;<span class="hljs-literal" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">NULL</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">COMMENT</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'创建时间'</span>,<br>&nbsp;&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`gmt_modified`</span>&nbsp;datetime&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">NOT</span>&nbsp;<span class="hljs-literal" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">NULL</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">COMMENT</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'修改时间'</span>,&nbsp;<br>&nbsp;&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`pay_scene_name`</span>&nbsp;<span class="hljs-built_in" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">varchar</span>(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">256</span>)&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">NOT</span>&nbsp;<span class="hljs-literal" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">NULL</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">COMMENT</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'支付场景名称'</span>,&nbsp;<br>&nbsp;&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`pay_scene_version`</span>&nbsp;<span class="hljs-built_in" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">varchar</span>(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">256</span>)&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">DEFAULT</span>&nbsp;<span class="hljs-literal" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">NULL</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">COMMENT</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'支付场景版本'</span>,<br>&nbsp;&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`identifier`</span>&nbsp;<span class="hljs-built_in" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">varchar</span>(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">256</span>)&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">NOT</span>&nbsp;<span class="hljs-literal" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">NULL</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">COMMENT</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'唯一性标识'</span>,<br>&nbsp;&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`seller_id`</span>&nbsp;<span class="hljs-built_in" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">varchar</span>(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">64</span>)&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">NOT</span>&nbsp;<span class="hljs-literal" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">NULL</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">COMMENT</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'卖家Id'</span>,<br>&nbsp;&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`state`</span>&nbsp;<span class="hljs-built_in" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">varchar</span>(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">64</span>)&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">DEFAULT</span>&nbsp;<span class="hljs-literal" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">NULL</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">COMMENT</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'状态'</span>,&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`fund_transfer_order_no`</span>&nbsp;<span class="hljs-built_in" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">varchar</span>(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">256</span>)&nbsp;<br>&nbsp;&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">DEFAULT</span>&nbsp;<span class="hljs-literal" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">NULL</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">COMMENT</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'资金平台返回的状态'</span>,&nbsp;<br>&nbsp;&nbsp;PRIMARY&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">KEY</span>&nbsp;(<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`id`</span>),<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">UNIQUE</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">KEY</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`uk_scene_identifier`</span>&nbsp;<br>&nbsp;&nbsp;(<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">KEY</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`idx_seller`</span>&nbsp;(<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`seller_id`</span>),<br>&nbsp;&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">KEY</span>&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`idx_seller_transNo`</span>&nbsp;(<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`seller_id`</span>,<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`fund_transfer_order_no`</span>(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">20</span>))<br>&nbsp;&nbsp;)&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">ENGINE</span>=<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">InnoDB</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">DEFAULT</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">CHARSET</span>=utf8mb4&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">COMMENT</span>=<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'资金流水'</span>;<br></code></pre> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">该数据库共有三个索引,1 个聚簇索引(主键索引),2 个非聚簇索<span style="color: rgb(89, 89, 89);font-size: 15px;letter-spacing: 1px;line-height: 29.75px;">引</span>(非主键索引)。</span></p> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">聚簇索引:</span></p> <section class="output_wrapper" style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="hljs javascript" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);padding: 0.5em;display: block !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;background: rgb(40, 43, 46);">PRIMARY&nbsp;KEY&nbsp;(<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`id`</span>)<br></code></pre> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">非聚簇索引:</span></p> <section class="output_wrapper" style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="hljs javascript" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);padding: 0.5em;display: block !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;background: rgb(40, 43, 46);">KEY&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`idx_seller`</span>&nbsp;(<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`seller_id`</span>),<br><br>KEY&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`idx_seller_transNo`</span>&nbsp;(<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`seller_id`</span>,<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`fund_transfer_order_no`</span>(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">20</span>))<br></code></pre> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">以上两个索引,其实 idx_seller_transNo 已经覆盖到了 idx_seller,由于历史原因,该表以 seller_id 分表,所以是先有的 idx_seller,后有的 idx_seller_transNo。</span></p> <p style="line-height: normal;"><br></p> <section class=""> <section style="box-sizing: border-box;font-size: 16px;"> <section style="box-sizing: border-box;" powered-by="xiumi.us"> <section style="border-bottom-width: 1px;border-bottom-style: solid;border-bottom-color: black;margin-top: 0.5em;margin-bottom: 0.5em;line-height: 1.2;box-sizing: border-box;"> <section style="display: inline-block;border-bottom-width: 6px;border-bottom-style: solid;border-color: rgb(89, 89, 89);margin-bottom: -1px;font-size: 20px;color: rgb(89, 89, 89);box-sizing: border-box;"> <p style="box-sizing: border-box;">死锁日志</p> </section> </section> </section> </section> <p style="line-height: normal;"><br></p> </section> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;letter-spacing: 1px;color: rgb(71, 193, 168);">当数据库发生死锁时,可以通过以下命令获取死锁日志:</span><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;"></span></p> <section class="output_wrapper" style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="hljs sql" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);padding: 0.5em;display: block !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;background: rgb(40, 43, 46);"><span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">show</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">engine</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">innodb</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">status</span><br></code></pre> </section> <p style="line-height: normal;"><br></p> <p style="text-align: justify;margin-left: 8px;margin-right: 8px;line-height: 1.75em;margin-bottom: 5px;"><span style="font-size: 15px;color: rgb(89, 89, 89);letter-spacing: 1px;">发生死锁,第一时间查看死锁日志,得到死锁日志内容如下:</span></p> <section class="output_wrapper" style="font-size: 16px;color: rgb(62, 62, 62);line-height: 1.6;letter-spacing: 0px;font-family: 'Helvetica Neue', Helvetica, 'Hiragino Sans GB', 'Microsoft YaHei', Arial, sans-serif;"> <pre style="font-size: inherit;color: inherit;line-height: inherit;"><code class="hljs perl" style="margin-right: 2px;margin-left: 2px;line-height: 18px;font-size: 14px;letter-spacing: 0px;font-family: Consolas, Inconsolata, Courier, monospace;border-radius: 0px;color: rgb(169, 183, 198);padding: 0.5em;display: block !important;word-wrap: normal !important;word-break: normal !important;overflow: auto !important;background: rgb(40, 43, 46);">Transactions&nbsp;deadlock&nbsp;detected,&nbsp;dumping&nbsp;detailed&nbsp;information.<br><span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">2019</span>-<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">03</span>-<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">19</span>T21:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">44</span>:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">23.516263</span>+08:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">00</span>&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">5877341</span>&nbsp;[Note]&nbsp;InnoDB:&nbsp;<br><br>***&nbsp;(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">1</span>)&nbsp;TRANSACTION:<br>TRANSACTION&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">173268495</span>,&nbsp;ACTIVE&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">0</span>&nbsp;sec&nbsp;fetching&nbsp;rows<br>mysql&nbsp;tables&nbsp;in&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">use</span>&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">1</span>,&nbsp;locked&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">1</span><br>LOCK&nbsp;WAIT&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">304</span>&nbsp;lock&nbsp;struct(<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">s</span>),&nbsp;heap&nbsp;size&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">41168</span>,&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">6</span>&nbsp;row&nbsp;lock(<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">s</span>),&nbsp;undo&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">log</span>&nbsp;entries&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">1</span><br>MySQL&nbsp;thread&nbsp;id&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">5877358</span>,&nbsp;OS&nbsp;thread&nbsp;handle&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">47356539049728</span>,&nbsp;query&nbsp;id&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">557970181</span>&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">11.183</span>.<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">244.150</span>&nbsp;fin_instant_app&nbsp;updating<br><br>update&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`fund_transfer_stream`</span>&nbsp;set&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`gmt_modified`</span>&nbsp;=&nbsp;NOW(),&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`state`</span>&nbsp;=&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'PROCESSING'</span>&nbsp;where&nbsp;((<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`state`</span>&nbsp;=&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'NEW'</span>)&nbsp;AND&nbsp;(<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`seller_id`</span>&nbsp;=&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'38921111'</span>)&nbsp;AND&nbsp;(<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`fund_transfer_order_no`</span>&nbsp;=&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">'99010015000805619031958363857'</span>))<br><span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">2019</span>-<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">03</span>-<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">19</span>T21:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">44</span>:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">23.516321</span>+08:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">00</span>&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">5877341</span>&nbsp;[Note]&nbsp;InnoDB:&nbsp;<br><br>***&nbsp;(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">1</span>)&nbsp;HOLDS&nbsp;THE&nbsp;LOCK(S):<br>RECORD&nbsp;LOCKS&nbsp;space&nbsp;id&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">173</span>&nbsp;page&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">no</span>&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">13726</span>&nbsp;n&nbsp;bits&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">248</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">index</span>&nbsp;idx_seller_transNo&nbsp;of&nbsp;table&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`xxx`</span>.<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`fund_transfer_stream`</span>&nbsp;trx&nbsp;id&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">173268495</span>&nbsp;lock_mode&nbsp;X&nbsp;locks&nbsp;rec&nbsp;but&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">not</span>&nbsp;gap<br>Record&nbsp;lock,&nbsp;heap&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">no</span>&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">168</span>&nbsp;PHYSICAL&nbsp;RECORD:&nbsp;n_fields&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">3</span>;&nbsp;compact&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">format</span>;&nbsp;info&nbsp;bits&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">0</span><br><br><span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">2019</span>-<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">03</span>-<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">19</span>T21:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">44</span>:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">23.516565</span>+08:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">00</span>&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">5877341</span>&nbsp;[Note]&nbsp;InnoDB:&nbsp;<br><br>***&nbsp;(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">1</span>)&nbsp;WAITING&nbsp;FOR&nbsp;THIS&nbsp;LOCK&nbsp;TO&nbsp;BE&nbsp;GRANTED:<br>RECORD&nbsp;LOCKS&nbsp;space&nbsp;id&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">173</span>&nbsp;page&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">no</span>&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">12416</span>&nbsp;n&nbsp;bits&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">128</span>&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">index</span>&nbsp;PRIMARY&nbsp;of&nbsp;table&nbsp;<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`xxx`</span>.<span class="hljs-string" style="font-size: inherit;line-height: inherit;color: rgb(238, 220, 112);word-wrap: inherit !important;word-break: inherit !important;">`fund_transfer_stream`</span>&nbsp;trx&nbsp;id&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">173268495</span>&nbsp;lock_mode&nbsp;X&nbsp;locks&nbsp;rec&nbsp;but&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">not</span>&nbsp;gap&nbsp;waiting<br>Record&nbsp;lock,&nbsp;heap&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">no</span>&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">56</span>&nbsp;PHYSICAL&nbsp;RECORD:&nbsp;n_fields&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">17</span>;&nbsp;compact&nbsp;<span class="hljs-keyword" style="font-size: inherit;line-height: inherit;color: rgb(248, 35, 117);word-wrap: inherit !important;word-break: inherit !important;">format</span>;&nbsp;info&nbsp;bits&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">0</span><br><span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">2019</span>-<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">03</span>-<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">19</span>T21:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">44</span>:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">23.517793</span>+08:<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">00</span>&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">5877341</span>&nbsp;[Note]&nbsp;InnoDB:&nbsp;<br><br>***&nbsp;(<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">2</span>)&nbsp;TRANSACTION:<br>TRANSACTION&nbsp;<span class="hljs-number" style="font-size: inherit;line-height: inherit;color: rgb(174, 135, 250);word-wrap: inherit !important;word-break: inherit !important;">173268500</span>,&n

Java设计模式(转)——20.状态模式

作者:じ☆ve宝贝

## 20.状态模式(State) 核心思想就是:当对象的状态改变时,同时改变其行为,很好理解!就拿QQ来说,有几种状态,在线、隐身、忙碌等,每个状态对应不同的操作,而且你的好友也能看到你的状态,所以,状态模式就两点:1、可以通过改变状态来获得不同的行为。2、你的好友能同时看到你的变化。看图: ![状态设计模式](/upload/content31.png "状态设计模式") State类是个状态类,Context类可以实现切换,我们来看看代码: ``` package cn.studyjava.dp.state; /** * 状态类的核心类 */ public class State { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } public void method1(){ System.out.println("execute the first opt!"); } public void method2(){ System.out.println("execute the second opt!"); } } ``` ``` package cn.studyjava.dp.state; /** * 状态模式的切换类 */ public class Context { private State state; public Context(State state) { this.state = state; } public State getState() { return state; } public void setState(State state) { this.state = state; } public void method() { if (state.getValue().equals("state1")) { state.method1(); } else if (state.getValue().equals("state2")) { state.method2(); } } } ``` 测试类: ``` public class Test { public static void main(String[] args) { State state = new State(); Context context = new Context(state); //设置第一种状态 state.setValue("state1"); context.method(); //设置第二种状态 state.setValue("state2"); context.method(); } } ``` 输出: execute the first opt! execute the second opt! 根据这个特性,状态模式在日常开发中用的挺多的,尤其是做网站的时候,我们有时希望根据对象的某一属性,区别开他们的一些功能,比如说简单的权限控制等。

迅雷批量下载文件、Java批量下载文件

作者:Happy生龙

> 近期实现了抖音个人主页解析,可能解析出四五十个视频,用户一个一个点击下载太麻烦了,服务器端批量下载后压缩打包又占用服务器资源,个人服务器,没有那么大的资源。因此调用迅雷的api去实现批量下载。 >网上找了很多内容,奈何版本太久,已经失效了,经过不懈努力终于找到迅雷最新的JS-SDK,实现迅雷批量下载功能。 [实现效果](https://www.studyjava.cn/douyin) 找一个抖音上的个人主页,粘贴在地址栏,可以尝试最终的效果。 最终实现Java批量下载文件,迅雷最新Js API。迅雷批量现在 ## 官网地址: ``` http://open.thunderurl.com/ ``` ## 示例代码: ``` //引入 JS 文件 //在您的网页中加入如下代码: <script src="//open.thunderurl.com/thunder-link.js"></script> //在需要使用迅雷下载的 a 标签上添加 thunder-link 类。 <a class="thunder-link" href="填写下载链接">迅雷下载</a> //调用 thunderLink 方法,生成迅雷下载链接。 thunderLink(); //原理:thunderLink 方法会遍历网页中所有的 a 标签,将带有 thunder-link 类的 a 标签转换为迅雷下载链接。 //基础用法仅适用于简单场景,若您需要更多的配置及使用批量下载,请查看高级用法。 ``` ## 高级用法: ``` //开始批量添加 function download(){ var urls = []; urls.push({ name:"视频名称1" , url: "视频下载地址1" }); urls.push({ name:"视频名称2" , url: "视频下载地址2" }); console.log(urls); // 创建批量任务 thunderLink.newTask({ downloadDir: downloadDir, // 指定当前任务的下载目录,迅雷会在用户剩余空间最大的磁盘根目录中创建这个目录。若不填此项,会下载到用户默认下载目录 installFile: '''', // 指定下载文件中的安装文件,下载完成后若用户选择立即安装,则运行此文件。若不填此项,下载完成后,用户可打开下载文件所在的文件夹 runParams: '''', // 指定打开安装文件时的启动参数 taskGroupName: ''抖音短视频下载'', // 指定任务组名称,将在下载目录中创建同名子文件夹保存所有下载文件。若不填此项,将不会创建同名子文件夹保存下载文件 excludePath: '''', // 如果您希望批量下载的文件保持服务器上的文件目录结构,可以指定排除URL的前缀,迅雷会根据被排除前缀后的URL路径,创建文件夹保存对应的文件。若不填此项,将把所有文件都放置于同一层下载目录中 tasks: urls }); } ```

反射 — Java 高级开发必须懂的

作者:微信小助手

<p style="text-align: center;"><span style="font-size: 14px;letter-spacing: 0.5440000295639038px;text-align: center;max-width: 100%;color: rgb(255, 41, 65);line-height: 22.4px;">(给</span><span style="font-size: 14px;letter-spacing: 0.5440000295639038px;text-align: center;max-width: 100%;line-height: 22.4px;color: rgb(0, 128, 255);">ImportNew</span><span style="font-size: 14px;letter-spacing: 0.5440000295639038px;text-align: center;max-width: 100%;color: rgb(255, 41, 65);line-height: 22.4px;">加星标,提高Java技能)</span></p> <p><br></p> <blockquote> <p style="letter-spacing: 0.5440000295639038px;white-space: normal;background-color: rgb(255, 255, 255);max-width: 100%;min-height: 1em;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;overflow-wrap: break-word !important;">转自:博客园,作者:rocomp</span></p> <p style="letter-spacing: 0.5440000295639038px;white-space: normal;background-color: rgb(255, 255, 255);max-width: 100%;min-height: 1em;text-align: left;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="font-size: 14px;">链接:www.cnblogs.com/rocomp/p/4781987.html</span></p> </blockquote> <p><br></p> <p><span style="font-size: 15px;">理解反射对学习Java框架有很大的帮助,如Spring框架的核心就是使用Java反射实现的,而且对做一些Java底层的操作会很有帮助。&nbsp;</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;">一、Class类的使用</span></strong></span><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">1、万事万物皆对象,(当然,基本数据类型,静态成员不是面向对象(属于类的)),所以我们创建的每一个类也都是对象,即类本身是java.lang.Class类的实例对象,但是</span><span style="font-size: 15px;color: rgb(0, 0, 0);">这些对象都不需要new出来</span><span style="font-size: 15px;">,因为java.lang.Class类的构造方法是私有的</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">2、任何一个类都是Class类的实例对象,这个实例对象有</span><span style="font-size: 15px;color: rgb(171, 25, 66);">三种表示方式</span><span style="font-size: 15px;">:(我们新建一个Student类)</span></p> <p><span style="font-size: 15px;"><br></span></p> <ol class=" list-paddingleft-2" style="list-style-type: decimal;"> <li><p><span style="font-size: 15px;">Class c1 = Student.class;//实际告诉我们任何一个类都有一个隐含的静态成员变量class(知道类名时用)</span><br></p><p><br></p></li> <li><p><span style="font-size: 15px;">Class c2 = stu.getClass();//已知该类的对象通过getClass方法(知道对象时用)&nbsp;&nbsp;</span></p><p><br></p></li> <li><p><span style="font-size: 15px;">Class c3 = Class.forName("类的全名");//会有一个ClassNotFoundException异常</span></p></li> </ol> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">官网解释说:c1,c2表示了Student类的类类型()class&nbsp;type),万事万物皆对象,类也是对象,是Class类的实例对象,这个对象我们成为该类的类类型(有点乱,但是慢慢捋一下还是能理解的)</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;color: rgb(171, 25, 66);">这里有一点值得注意</span><span style="font-size: 15px;">,当我们执行System.out.println(c1==c2);语句,结果返回的是</span><span style="font-size: 15px;color: rgb(171, 25, 66);">true</span><span style="font-size: 15px;">,这是为什么呢?原因是不管c1还是c2都代表了Student类的类类型,一个类可能是Class类的一个实例对象。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">我们完全可以通过类的类类型创建该类的对象实例,即通过c1或c2创建Student的实例。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">Student&nbsp;stu&nbsp;=&nbsp;(Student)c1.newInstance();//前提是必须要有无参的构造方法,因为该语句会去调用其无参构造方法。该语句会抛出异常。</span></p> <p><span style="font-size: 15px;">&nbsp;</span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;">二、动态加载类</span></strong></span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;"><br></span></strong></span></p> <ol class=" list-paddingleft-2" style="list-style-type: decimal;"> <li><p><span style="font-size: 15px;">编译时加载类是静态加载类,</span></p><p><span style="font-size: 15px;">new 创建对象是静态加载类,在编译时刻就需要加载所有可用使用到的类,如果有一个用不了,那么整个文件都无法通过编译</span></p><p><br></p></li> <li><p><span style="font-size: 15px;">运行时加载类是动态加载类</span><span style="font-size: 15px;">&nbsp; &nbsp; &nbsp;&nbsp;</span></p><p><span style="font-size: 15px;">Class&nbsp;c&nbsp;=&nbsp;&nbsp;Class.forName("类的全名"),不仅表示了类的类型,还表示了动态加载类,编译不会报错,在运行时才会加载,使用接口标准能更方便动态加载类的实现。</span><span style="font-size: 15px;">功能性的类尽量使用动态加载,而不用静态加载。</span></p></li> </ol> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">很多软件比如QQ,360的在线升级,并不需要重新编译文件,只是动态的加载新的东西</span></p> <p><span style="font-size: 15px;">&nbsp; &nbsp; &nbsp;&nbsp;</span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;">三、获取方法信息</span></strong></span><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">1、基本的数据类型,void关键字都存在类类型</span></p> <p><span style="font-size: 15px;"><br></span></p> <pre style="overflow-x:auto;"><code style="font-size: 0.85em;font-family: Consolas, Menlo, Courier, monospace;margin: 0px 0.15em;white-space: pre;overflow: auto;padding: 0.5em;color: rgb(171, 178, 191);text-size-adjust: none;display: block !important;min-width: 400px;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(40, 44, 52);font-weight: 400;" class="c hljs cpp">Class c1 =<span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">int</span>.<span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">class</span>;<span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//int的类类型</span><br>Class c2 =String.<span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">class</span>;<span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//String类的类类型,可以理解为编译生成的那个String.class字节码文件,</span><br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//当然,这并不是官方的说法</span><br>Class c3 =<span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">double</span>.<span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">class</span>;<br>Class c4 =Double.<span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">class</span>;<br>Class c5 =<span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">void</span>.<span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">class</span>;</code></pre> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">2、Class类的基本API操作&nbsp;</span></p> <p><span style="font-size: 15px;"><br></span></p> <pre style="overflow-x:auto;"><code style="font-size: 0.85em;font-family: Consolas, Menlo, Courier, monospace;margin: 0px 0.15em;white-space: pre;overflow: auto;padding: 0.5em;color: rgb(171, 178, 191);text-size-adjust: none;display: block !important;min-width: 400px;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(40, 44, 52);font-weight: 400;" class="c hljs cpp"><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">/**<br>* 打印类的信息,包括类的成员函数,成员变量<br>* @param obj 该对象所属类的信息<br>*/</span><br><span class="hljs-function" style="color: rgb(171, 178, 191);font-weight: 400;font-style: normal;">publicstaticvoid <span class="hljs-title" style="color: rgb(97, 174, 238);font-weight: 400;font-style: normal;">printClassMessage</span><span class="hljs-params" style="color: rgb(171, 178, 191);font-weight: 400;font-style: normal;">(Object obj)</span></span>{<br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//要获取类的信息,首先要获取类的类类型</span><br>Class c = obj.getClass();<span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//传递的是哪个子类的对象,c就是该子类的类类型</span><br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//获取类的名称</span><br>System.out.println(<span class="hljs-string" style="color: rgb(152, 195, 121);font-weight: 400;font-style: normal;">"累的名称是:"</span>+c.getName());<br><br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">/*<br> * Method类,方法的对象<br>* 一个成员方法就是一个Method对象<br>* getMethods()方法获取的是所有的public的函数,包括父类继承而来的<br>* getDeclaredMethods()获取的是多有该类自己声明的方法,不问访问权限<br>*/</span><br>Method[] ms = c.getMethods();<span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//c.getDeclaredMethods();</span><br><span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">for</span>(<span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">int</span> i =<span class="hljs-number" style="color: rgb(209, 154, 102);font-weight: 400;font-style: normal;">0</span>; i &lt; ms.length; i++){<br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//得到方法的返回值类型的类类型</span><br>Class retrunType = ms[i].getReturnType();<br>System.out.print(retrunType.getName()+<span class="hljs-string" style="color: rgb(152, 195, 121);font-weight: 400;font-style: normal;">" "</span>);<br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//得到方法的名称</span><br>System.out.print(ms[i].getName()+<span class="hljs-string" style="color: rgb(152, 195, 121);font-weight: 400;font-style: normal;">"("</span>);<br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//获取的参数类型---&gt;得到的是参数列表的类型的类类型</span><br>Class[] paraTypes = ms[i].getParameterTypes();<br><span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">for</span>(Class&nbsp;class1&nbsp;:&nbsp;paraTypes){<br>System.out.print(class1.getName()+<span class="hljs-string" style="color: rgb(152, 195, 121);font-weight: 400;font-style: normal;">","</span>);<br>}<br>System.out.println(<span class="hljs-string" style="color: rgb(152, 195, 121);font-weight: 400;font-style: normal;">")"</span>);<br>}<br>}</code></pre> <p><br></p> <p><span style="font-size: 15px;">Class的API中还有很多其他的方法,可以得到interface、Package、Annotation等很多信息,具体使用请参考帮助手册,本文就不在详细讲解。</span><span style="font-size: 15px;color: rgb(171, 25, 66);">特别注意的一点是</span><span style="font-size: 15px;">,</span><span style="font-size: 15px;color: rgb(0, 0, 0);">如果你想得到一个类的信息,首先就要获取该类的类类型。</span><span style="font-size: 15px;"></span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;"><br></span></strong></span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="color: rgb(171, 25, 66);font-size: 15px;">四、获取成员变量构造函数信息&nbsp;&nbsp;</span></strong></span><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <pre style="overflow-x:auto;"><code style="font-size: 0.85em;font-family: Consolas, Menlo, Courier, monospace;margin: 0px 0.15em;white-space: pre;overflow: auto;padding: 0.5em;color: rgb(171, 178, 191);text-size-adjust: none;display: block !important;min-width: 400px;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(40, 44, 52);font-weight: 400;" class="c hljs cpp"><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">/**<br> * 成员变量也是对象,是java.lang.reflect.Field这个类的的对象<br>* Field类封装了关于成员变量的操作<br>* getFields()方法获取的是所有public的成员变量的信息<br>* getDeclareFields()方法获取的是该类自己声明的成员变量的信息<br>*/</span><br>Field[] fs = c.getDeclaredFields();<br><span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">for</span>(Field&nbsp;field&nbsp;:&nbsp;fs){<br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//得到成员变量的类型的类类型</span><br>Class fieldType = field.getType();<br>String typeName = fieldType.getName();<br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//得到成员变量的名称</span><br>String fieldName = field.getName();<br>System.out.print(typeName+<span class="hljs-string" style="color: rgb(152, 195, 121);font-weight: 400;font-style: normal;">" "</span>+fieldName);<br>}<br><br><br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">/**<br> * 构造函数也是对象<br>* java.lang.Constructor中封装了构造函数的信息<br>* getConstructor()方法获取所有的public的构造函数<br>* getDeclaredConstructors得到所有的构造函数<br>*/</span><br>Constructor[] cs = c.getDeclaredConstructors();<br><span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">for</span>(Constructor&nbsp;constructor&nbsp;:&nbsp;cs){<br>System.out.print(constructor.getName()+<span class="hljs-string" style="color: rgb(152, 195, 121);font-weight: 400;font-style: normal;">"("</span>);<br><span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//获取构造函数的参数列表---》得到的是参数雷彪的类类型</span><br>Class[] paramTypes = constructor.getParameterTypes();<br><span class="hljs-keyword" style="color: rgb(198, 120, 221);font-weight: 400;font-style: normal;">for</span>(Class&nbsp;class1&nbsp;:&nbsp;paramTypes){<br>System.out.print(class1.getName()+<span class="hljs-string" style="color: rgb(152, 195, 121);font-weight: 400;font-style: normal;">","</span>);<br>}<br>System.out.println(<span class="hljs-string" style="color: rgb(152, 195, 121);font-weight: 400;font-style: normal;">")"</span>);<br>}</code></pre> <p><span style="font-size: 15px;"><br></span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;">五、方法反射的基本操作</span></strong></span></p> <p><span style="font-size: 15px;"><br></span></p> <ol class=" list-paddingleft-2" style="list-style-type: decimal;"> <li><p><span style="font-size: 15px;">如何获取某个方法</span></p><p><span style="font-size: 15px;">&nbsp; &nbsp; &nbsp; &nbsp;方法的名称和方法的参数列表才能唯一决定某个方法</span></p><p><span style="font-size: 15px;">&nbsp;</span><span style="font-size: 15px;">&nbsp; &nbsp; &nbsp; Method m = c.getDeclaredMethod("方法名",可变参数列表(参数类型.class))</span></p><p><br></p></li> <li><p><span style="font-size: 15px;">方法的反射操作</span></p><p><span style="font-size: 15px;">&nbsp; &nbsp; &nbsp; &nbsp;m.invoke(对象,参数列表)</span></p><p><span style="font-size: 15px;">&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;方法如果没有返回值,返回null,如果有返回值返回Object类型,然后再强制类型转换为原函数的返回值类型</span></p></li> </ol> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;"><br></span></strong></span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="color: rgb(171, 25, 66);font-size: 15px;">六、通过反射了解集合泛型的本质</span></strong></span><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <pre style="overflow-x:auto;"><code style="font-size: 0.85em;font-family: Consolas, Menlo, Courier, monospace;margin: 0px 0.15em;white-space: pre;overflow: auto;padding: 0.5em;color: rgb(171, 178, 191);text-size-adjust: none;display: block !important;min-width: 400px;background: none 0% 0% / auto repeat scroll padding-box border-box rgb(40, 44, 52);font-weight: 400;" class="c hljs cpp">ArrayList list1 =newArrayList();<br>ArrayList&lt;String&gt; list2 =newArrayList&lt;String&gt;();<br><br>Class c1 = list1.getClass();<br>Class c2 = list2.getClass();<br><br>System.out.println(c1==c2);<span class="hljs-comment" style="color: rgb(92, 99, 112);font-weight: 400;font-style: italic;">//结果为true,为什么??</span></code></pre> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;color: rgb(171, 25, 66);">结果分析</span><span style="font-size: 15px;">:因为反射的操作都是编译之后的操作,也就是运行时的操作,c1==c2返回true,说明编译之后集合的泛型是去泛型化的。</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">那么我们就可以理解为,Java集合中的泛型,是用于防止错误类型元素输入的,比如在list2中我们add一个int,add(10)就会编译报错,那么这个泛型就可以只在编译阶段有效,通过了编译阶段,泛型就不存在了。</span><span style="font-size: 15px;">可以验证,我们绕过编译,用反射动态的在list2中add一个int是可以成功的,只是这时因为list2中存储了多个不同类型的数据(String型,和int型),就不能用for-each来遍历了,会抛出类型转换错误异常ClassCastException</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;"></span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;">补充资料:</span></strong></span><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;">七、关于Java类加载器内容的详解</span></strong></span><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;">&nbsp;</span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;">1、类的加载</span></strong></span><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化</span></p> <p><span style="font-size: 15px;"><br></span></p> <ul class=" list-paddingleft-2" style="list-style-type: disc;"> <li><p><span style="font-size: 15px;">加载:</span></p><p><span style="font-size: 15px;">&nbsp; &nbsp; &nbsp; &nbsp;就是指将class文件读入内存,并为之创建一个Class对象,任何类被使用时系统都会建立一个Class对象</span></p><p><br></p></li> <li><p><span style="font-size: 15px;">连接:</span></p><p><span style="font-size: 15px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;验证:</span><span style="font-size: 15px;">确保被加载类的正确性</span></p><p><span style="font-size: 15px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;准备:</span><span style="font-size: 15px;">负责为类的静态成员分配内存,并设置默认初始化值</span></p><p><span style="font-size: 15px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;解析:</span><span style="font-size: 15px;">将类中的符号引用替换为直接引用</span></p><p><br></p></li> <li><p><span style="font-size: 15px;">初始化:</span></p><p><span style="font-size: 15px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;局部变量保存在栈区:</span><span style="font-size: 15px;">必须手动初始化</span></p><p><span style="font-size: 15px;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;的对象保存在堆区:</span><span style="font-size: 15px;">虚拟机会进行默认初始化,基本数据类型初始化值为0,引用类型初始化值为null</span></p></li> </ul> <p><span style="font-size: 15px;"><br></span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;">2、类加载的时机(只加载一次)</span></strong></span><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">以下时机仅表示第一次的时候</span></p> <p><span style="font-size: 15px;"><br></span></p> <ol class=" list-paddingleft-2" style="list-style-type: decimal;"> <li><p><span style="font-size: 15px;">创建类的实例的时候</span></p></li> <li><p><span style="font-size: 15px;">访问类的静态变量的时候</span></p></li> <li><p><span style="font-size: 15px;">调用类的静态方法的时候</span></p></li> <li><p><span style="font-size: 15px;">使用反射方式来强制创建某个类或接口对应的java.lang.Class对象</span></p></li> <li><p><span style="font-size: 15px;">初始化某个类的子类的时候</span></p></li> <li><p><span style="font-size: 15px;">直接使用java.exe命令来运行某个主类</span></p></li> </ol> <p><span style="font-size: 15px;">&nbsp;</span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;">3、类加载器</span></strong></span><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">负责将.class文件加载到内存中,并为之生成对应的Class对象</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="font-size: 15px;">虽然我们在开发过程中不需要关心类加载机制,但是了解这个机制我们就能更好的理解程序的运行</span></p> <p><span style="font-size: 15px;"><br></span></p> <p><span style="color: rgb(171, 25, 66);"><strong><span style="font-size: 15px;">4、类加载器的组成</span></strong></span><span style="font-size: 15px;"></span></p> <p><span style="font-size: 15px;"><br></span></p> <ol class=" list-paddingleft-2" style="list-style-type: decimal;"> <li><p><span style="font-size: 15px;">Bootstrap ClassLoader 根类加载器</span></p><p><span style="font-size: 15px;">&nbsp; &nbsp; &nbsp; 也被称为引导类加载器,负责Java核心类的加载,比如System类,在JDK中JRE的lib目录下rt.jar文件中的类</span></p><p><br></p></li> <li><p><span style="font-size: 15px;">Extension ClassLoader 扩展类加载器</span></p><p><span style="font-size: 15px;">&nbsp; &nbsp; &nbsp; &nbsp;负责JRE的扩展目录中jar包的加载,在JDK中JRE的lib目录下ext目录</span></p><p><br></p></li> <li><p><span style="font-size: 15px;">System ClassLoader 系统类加载器</span></p><p><span style="font-size: 15px;">&nbsp; &nbsp; &nbsp; 负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径,主要是我们开发者自己写的类</span></p></li> </ol> <p><br></p> <section style="white-space: normal;font-variant-ligatures: normal;orphans: 2;widows: 2;max-width: 100%;box-sizing: border-box;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="padding-top: 1.1em;max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;display: inline-block;vertical-align: top;overflow-wrap: break-word !important;"> <section style="padding: 0.2em 0.4em;max-width: 100%;box-sizing: border-box;border-top-left-radius: 0px;border-top-right-radius: 0.5em;border-bottom-right-radius: 0.5em;border-bottom-left-radius: 0px;background-color: rgb(249, 110, 87);color: rgb(255, 255, 255);overflow-wrap: break-word !important;"> <p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;"><strong style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;">推荐阅读</strong></p> </section> <section style="max-width: 100%;box-sizing: border-box;width: 0px;border-right-width: 4px;border-right-style: solid;border-right-color: rgb(249, 110, 87);border-top-width: 4px;border-top-style: solid;border-top-color: rgb(249, 110, 87);overflow-wrap: break-word !important;border-left-width: 4px !important;border-left-style: solid !important;border-left-color: transparent !important;border-bottom-width: 4px !important;border-bottom-style: solid !important;border-bottom-color: transparent !important;"></section> </section> <section style="padding-left: 10px;max-width: 100%;box-sizing: border-box;display: inline-block;vertical-align: top;color: rgb(160, 160, 160);font-size: 14px;overflow-wrap: break-word !important;"> <p style="max-width: 100%;box-sizing: border-box;min-height: 1em;overflow-wrap: break-word !important;">(点击标题可跳转阅读)</p> </section> <section style="margin-top: -3.5em;margin-left: 8px;padding: 3.5em 10px 10px;max-width: 100%;box-sizing: border-box;border-width: 1px;border-style: solid;border-color: rgb(204, 204, 204);overflow-wrap: break-word !important;"> <section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;overflow-wrap: break-word !important;"> <section style="max-width: 100%;box-sizing: border-box;font-size: 14px;line-height: 2.6;overflow-wrap: break-word !important;"> <p><a href="http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&amp;mid=2651483325&amp;idx=1&amp;sn=1a230d4f9d9b9922fb4dbb2d16f2129d&amp;chksm=bd2500c28a5289d4c9d9ebd9a3ac7640b1e10a1c3c042c928201252b63fddd157dadcffb39ca&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2"><span style="font-size: 12px;">一篇文章了解 Java 反射和应用</span></a><br></p> <p><a href="http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&amp;mid=2651479956&amp;idx=1&amp;sn=1064427684542ba3d3c748e7df22dfa8&amp;chksm=bd2533eb8a52bafd98eb121243955b250700609cf68f0d8706090a6d2dba24ac429679a677da&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" data-linktype="2"><span style="font-size: 12px;">粗浅看 Java 反射机制</span></a><br></p> <p><a href="http://mp.weixin.qq.com/s?__biz=MjM5NzMyMjAwMA==&amp;mid=2651478952&amp;idx=2&amp;sn=bc7ef9c2a8be792ca1aa56be62cbd5b5&amp;chksm=bd2537d78a52bec1e8148df65e39bb12a4d44e14d51912964102fd6cc8a6bc915eedd42e63dd&amp;scene=21#wechat_redirect" target="_blank" data-itemshowtype="0" style="font-size: 12px;text-decoration: underline;" data-linktype="2"><span style="font-size: 12px;">Java 反射机制应用实践</span></a><br></p> <p><span style="font-size: 12px;"></span></p> </section> </section> </section> </section> </section> </section> </section> </section> <p style="white-space: normal;"><br></p> <p style="white-space: normal;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;color: rgb(255, 169, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">看完本文有收获?请转发分享给更多人</span></p> <p style="white-space: normal;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(255, 169, 0);box-sizing: border-box !important;overflow-wrap: break-word !important;">关注「ImportNew」,提升Java技能</strong></p> <p style="white-space: normal;max-width: 100%;min-height: 1em;letter-spacing: 0.544px;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><img class="" data-ratio="0.9166666666666666" data-s="300,640" data-type="png" data-w="600" width="auto" src="/upload/899866149276fa5fddb73c61ae04be64.png" style="box-sizing: border-box !important;overflow-wrap: break-word !important;visibility: visible !important;width: 600px !important;"></p> <p style="text-align: right;"><span style="font-size: 14px;background-color: rgb(255, 254, 213);color: rgb(255, 41, 65);">喜欢就点一下「好看」呗~</span></p>

spring boot注入jar包中的接口总是提示that could not be found

作者:じ☆ve宝贝

``` @ComponentScan(basePackages = {"cn.studyjava"}) ``` SpringBoot在写启动类的时候如果不使用@ComponentScan指明对象扫描范围,默认指扫描当前启动类所在的包里的对象,如果当前启动类没有包,则在启动时会报错:Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package错误。 因为启动类不能直接放在main/java文件夹下,必须要建一个包把它放进去或者使用@ComponentScan指明要扫描的包。

Jetty、Solr、SolrCloud 出现414 URI Too Long 问题解决方案

作者:じ☆ve宝贝

** 找到solr中的jetty.xml ** ![](/upload/e40f191fbcf94c1aae97f9cc208d6a37.png) ** 修改requestHeaderSize的值即可 ** ![](/upload/70383620e61d4fb599bd0d8e70de7228.png)

SpringBoot | 番外:使用小技巧合集

作者:微信小助手

<p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(255, 0, 0);font-size: 14px;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(255, 41, 65);line-height: 22.4px;box-sizing: border-box !important;word-wrap: break-word !important;">(点击</span><span style="max-width: 100%;line-height: 22.4px;color: rgb(0, 128, 255);box-sizing: border-box !important;word-wrap: break-word !important;">上方公众号</span><span style="max-width: 100%;color: rgb(255, 41, 65);line-height: 22.4px;box-sizing: border-box !important;word-wrap: break-word !important;">,可快速关注)</span></span></p> <p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <blockquote style="max-width: 100%;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"> <p style="max-width: 100%;min-height: 1em;text-align: left;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;word-wrap: break-word !important;">来源:oKong ,</span></p> <p style="max-width: 100%;min-height: 1em;text-align: left;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;box-sizing: border-box !important;word-wrap: break-word !important;">blog.lqdev.cn/2018/08/11/springboot/springboot-tips/</span></p> </blockquote> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">前言</span></strong></p> <p><br></p> <p>最近工作比较忙,事情也比较多。加班回到家都十点多了,洗个澡就想睡觉了。所以为了不断更太多天,偷懒写个小技巧合集吧。之后有时间都会进行文章更新的。原创不易,码字不易,还希望大家多多支持!话不多说,开始今天的技巧合集吧~</p> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">设置网站图标</span></strong></p> <p><br></p> <p>原来我们在使用tomcat开发时,设置网站图片时,即icon图标时,一般都是直接替换root包下的favicon.ico替换成自己的,或者在网页的头部设置link的ref为icon然后设置其href值。而在SpringBoot中,替换图片也是很简单的,只需要将自定义图片放置在静态资源目录下即可,即默认有static、public、resources、/META-INF/resources或者自定义的静态目录下即可。</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.6805194805194805" src="/upload/a94be0f7fa71d584f8ccf2de2ab0a43e.png" data-type="png" data-w="385" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.392991239048811" src="/upload/d116372157d1a89f197ad9fdd13c0490.png" data-type="png" data-w="799" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><span style="color: rgb(255, 76, 65);"><strong>允许跨域访问</strong></span></p> <p><br></p> <p>CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。</p> <p><br></p> <p>简单来说,跨域问题是可以通过nginx来解决的,或者通过jsonp(只支持get请求)来解决。而SpringBoot中也提供了配置方法。</p> <p><br></p> <p>0.利用@CrossOrigin注解,可放至在类上或者方法上。类上代表整个控制层所有的映射方法都支持跨域请求。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">@CrossOrigin(origins = "http://blog.lqdev.cn", maxAge = 3600)</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">@RestController</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class demoController{</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp;@GetMapper("/")</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp;public String index(){</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; return "hello,CORS";</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp;}</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>1.配置全局CORS配置。官网也有给出实例,具体如下:</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">@Configuration<br></span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class MyConfiguration {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; @Bean</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; public WebMvcConfigurer corsConfigurer() {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; return new WebMvcConfigurerAdapter() {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void addCorsMappings(CorsRegistry registry) {&nbsp; &nbsp; &nbsp; registry.addMapping("/api/**").allowedOrigins("https://blog.lqdev.cn");</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; };</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">独立Tomcat运行</span></strong></p> <p><br></p> <p>讲解了这么久,一般上我们都是通过jar包的方式进行启动的应用的。所以部署在独立的tomcat时,需要如何解决呢?其实也简单,只需要将项目打包方式修改为war包,然后修改下启动类配置即可。</p> <p><br></p> <p>0.修改pom打包方式为war,同时排除了内置的tomcat。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&lt;packaging&gt;war&lt;/packaging&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&lt;!-- 排除内置的tomcat --&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &lt;dependency&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;artifactId&gt;spring-boot-starter-tomcat&lt;/artifactId&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;scope&gt;compile&lt;/scope&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &lt;/dependency&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&lt;!-- 若直接有使用servlet对象时(这是废话,⊙﹏⊙‖∣),需要将servlet引入,本例是没有的~ --&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp;&lt;dependency&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;groupId&gt;javax.servlet&lt;/groupId&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;artifactId&gt;javax.servlet-api&lt;/artifactId&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;scope&gt;provided&lt;/scope&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp;&lt;/dependency&gt;</span></p> </blockquote> <p><br></p> <p>1.改造下启动类,使其继承SpringBootServletInitializer,同时覆盖configure方法。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">@SpringBootApplication</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">@Slf4j</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class ChapterApplication extends SpringBootServletInitializer{</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; public static void main(String[] args) {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; SpringApplication.run(ChapterApplication.class, args);</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; //&nbsp; &nbsp; new SpringApplicationBuilder().sources(ChapterApplication.class).web(false).run(args);</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; //之后这里设置业务逻辑 比如挂起一个线程 或者设置一个定时任务。保证不退出</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; //不然它就是一个启动类,启动后就停止了。</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; log.info("jar,chapter启动!");</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; }&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; @Override</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; log.info("外部tomcat,chapter启动!");</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; return application.sources(ChapterApplication.class);</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; }</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>2.maven打包成war(mvn clean install),然后放入tomcat中,启动运行即可。</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.6122961104140527" src="/upload/15deed9594f91649fda14aeb703ef766.png" data-type="png" data-w="797" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p>其实这样设置的话,在开发时直接运行启动类也还是可以直接运行的,方便.</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.251959686450168" src="/upload/ebfdb0718d40d142306c57305564c017.png" data-type="png" data-w="893" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">启动不设置端口</span></strong></p> <p><br></p> <p>对一些定时任务服务项目,其本身只是提供一个定时调度功能,不需要其他服务调用,只是去调度其他服务。像这样的服务,正常也就不需要设置端口了。这时候SpringBoot也是支持的。只需要改下启动方式:</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">new SpringApplicationBuilder().sources(ChapterApplication.class).web(false).run(args);</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">//之后这里设置业务逻辑 比如挂起一个线程 或者设置一个定时任务。保证不退出</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">//不然它就是一个启动类,启动后就停止了。</span></p> </blockquote> <p><br></p> <p>或者修改配置文件的属性:</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">spring.main.web-environment=false</span></p> </blockquote> <p><br></p> <p>最后效果,是不是没有看见端口了:</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.17720090293453725" src="/upload/1f7e23b05f14ee626b0e34b4dddef6a0.png" data-type="png" data-w="886" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">启动完成前进行业务逻辑</span></strong></p> <p><br></p> <p>利用CommandLineRunner或者ApplicationRunner可实现在SpringApplication的run()完成前执行一些业务逻辑</p> <p><br></p> <p>0.修改启动类,实现CommandLineRunner接口,ApplicationRunner类似,只是run的入参不同而已。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">@Override</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; public void run(String... args) throws Exception {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; log.info("CommandLineRunner运行");</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; }</span></p> </blockquote> <p><br></p> <p>1.运行应用,注意查看控制台输出:</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.0913884007029877" src="/upload/660085d60b73a1a908de4096a735a938.png" data-type="png" data-w="1138" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p>当然,直接申明一个bean也是可以的。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">@Configuration</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">@Slf4j</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">public class CommandLineRunnerConfig {</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; @Bean&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; public CommandLineRunner runner(){&nbsp;&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; return new CommandLineRunner() {&nbsp;&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; public void run(String... args){&nbsp;&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log.info("CommandLineRunner运行2");</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; };&nbsp;&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; }&nbsp;&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">}</span></p> </blockquote> <p><br></p> <p>若多个时,可设置@Order来确定执行的顺序。</p> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">动态修改日志级别</span></strong></p> <p><br></p> <p>通过org.springframework.boot.logging.LoggingSystem提供的api即可。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">loggingSystem.setLogLevel(null, LogLevel.DEBUG);</span></p> </blockquote> <p><br></p> <p>如,默认时是info模式,未修改时,debug模式是不会输出的。</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.6627737226277373" src="/upload/4827461108507d549435d33a40579a10.png" data-type="png" data-w="685" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p>动态设置后</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.649331352154532" src="/upload/c47a24bba3abf380286d5afb130cfb57.png" data-type="png" data-w="673" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">热部署</span></strong></p> <p><br></p> <p>前面讲了这么多章节,因为功能都很单一,所以一般上都是直接重启服务来进行更新操作。但当服务功能一多,启动速度缓慢时,还是配置个热部署比较方便。在SpringBoot中,只需要加入一个spring-boot-devtools即可</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&lt;dependencies&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &lt;dependency&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &lt;artifactId&gt;spring-boot-devtools&lt;/artifactId&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &lt;optional&gt;true&lt;/optional&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &lt;/dependency&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&lt;/dependencies&gt;</span></p> </blockquote> <p><br></p> <p>题外话:这里的&lt;optional&gt;true&lt;/optional&gt;是表示依赖不会传递,依赖了此项目的需要额外引入此包,若需要使用的话。</p> <p><br></p> <p>若不生效,可试着在打包工具spring-boot-maven-plugin下的configuration加入&lt;fork&gt;true&lt;/fork&gt;看看,具体配置项如下:</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&lt;plugin&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &lt;groupId&gt;org.springframework.boot&lt;/groupId&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &lt;artifactId&gt;spring-boot-maven-plugin&lt;/artifactId&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &lt;configuration&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &lt;fork&gt;true&lt;/fork&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &lt;/configuration&gt;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&lt;/plugin&gt;</span></p> </blockquote> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">自定义启动Banner</span></strong></p> <p><br></p> <p>看烦了自带的Banner,动手修改一个属于自己的Banner,提现逼格的时候到了~哈哈,以下是官网给的配置指南:</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.11290322580645161" src="/upload/99530e69a3e75077221836b89f81add0.png" data-type="png" data-w="1302" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p><strong><span style="color: rgb(123, 12, 0);">文字形式</span></strong></p> <p><br></p> <p>其实,替换很简单,只需要在classpath路径下创建一个banner.txt即可。具体的一些变量官网也有给出,具体如下:</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.4007936507936508" src="/upload/b702c42006306a723ac38829a9de5c8a.png" data-type="png" data-w="1260" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p>现在我们就定制一个自己的Banner。</p> <p><br></p> <blockquote> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">_&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _&nbsp; &nbsp;_&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_&nbsp; __&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; _&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;| |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; | | | |&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| |/ /&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;| |</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;| |__&nbsp; &nbsp; &nbsp;___&nbsp; | | | |&nbsp; &nbsp;___&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;___&nbsp; &nbsp;| ' /&nbsp; &nbsp; ___&nbsp; &nbsp; _ __&nbsp; &nbsp; &nbsp;__ _&nbsp; | |</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;| '_ \&nbsp; &nbsp;/ _ \ | | | |&nbsp; / _ \&nbsp; &nbsp; &nbsp; &nbsp;/ _ \&nbsp; |&nbsp; &lt;&nbsp; &nbsp; / _ \&nbsp; | '_ \&nbsp; &nbsp;/ _` | | |</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;| | | | |&nbsp; __/ | | | | | (_) |&nbsp; _&nbsp; | (_) | | . \&nbsp; | (_) | | | | | | (_| | |_|</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;|_| |_|&nbsp; \___| |_| |_|&nbsp; \___/&nbsp; ( )&nbsp; \___/&nbsp; |_|\_\&nbsp; \___/&nbsp; |_| |_|&nbsp; \__, | (_)</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |/&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;__/ |&nbsp; &nbsp;&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |___/&nbsp; &nbsp; &nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">&nbsp;</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">${AnsiColor.BRIGHT_RED}</span></p> <p><span style="font-size: 12px;color: rgb(136, 136, 136);">Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version}</span></p> </blockquote> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.2747747747747748" src="/upload/9bf58e179b6c8a3262f12718c2d7276d.png" data-type="png" data-w="888" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p>题外话:手输字符画是不太现实的,大家可通过一些网站进行快速生成。可自行搜索下,网上一搜一大把。</p> <p><br></p> <p><strong><span style="color: rgb(123, 12, 0);">图片形式</span></strong></p> <p><br></p> <p>若觉得使用文字不够酷炫,当然也可以将图片设置为启动的banner。目前支持的图片格式有gif、png、jpg。使用也很简单,只需要命名为banner即可。</p> <p><br></p> <p>如将头像放入目录中,最后的效果如下:</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.5387994143484627" src="/upload/b16f4b257506d7290ee20ad4fa98afb3.png" data-type="png" data-w="1366" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p>当然,若图片是有色彩的,也是可以的,对于太复杂的图片显示效果就不佳了,如下。</p> <p><br></p> <p>原图:</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.7235576923076923" src="/upload/ebe995f6f6d53f52a5175c6949e21052.png" data-type="png" data-w="416" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p>banner效果图:</p> <p><br></p> <p style="text-align: center;"><img class="" data-ratio="0.6532951289398281" src="/upload/e32b599323e1c8cce1be3cf2a032c2af.png" data-type="png" data-w="698" style="border-width: 0px;border-style: initial;border-color: initial;font-size: 0px;color: transparent;vertical-align: middle;margin: 0px;top: 0px;left: 0px;right: 0px;bottom: 0px;"></p> <p><br></p> <p>是不是很酷炫~</p> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">相关资料</span></strong></p> <p><br></p> <p>1、https://docs.spring.io/spring-boot/docs/1.5.15.RELEASE/reference/htmlsingle</p> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">总结</span></strong></p> <p><br></p> <p>本章节主要是简单的介绍了一些SpringBoot的一些小技巧,一般上也就一句话或者一个注释、一句配置就解决问题的。写这篇文章时,又去翻了翻官网的指南,很不错,每次都去看都有新发现。以上有部分就是看了写下的。确实,在看官网时,一般上是需要了解哪些知识点,就搜索直奔主题了,还没有哪次是从头看的。有时间还是耐心的看一看,就是全是英文看的有点头疼,好在代码是看的懂的,⊙﹏⊙‖∣</p> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">一点吐槽</span></strong></p> <p><br></p> <p>原本是想偷懒,发一点时间完成的。最后本着有图有真相且负责的原则,为了截图展现效果,实际操作了一遍,发现时间没有和写一篇正文来的少,好尴尬。。既然说了,就简单说下,接下来的章节会涉及的知识点吧。接下来还是web开发相关,会介绍下websocket相关知识点,这部分本人也不是很熟悉,估计写的也是简单入门的,也希望会来个聊天室的实践,加深下影响。说了webSocket,那就不能把Servlet3.0提供的异步请求机制遗漏了,会介绍下原生的方式及Spring提供的方式实现,对一些异常处理,比如超时等设置也会进行说明下,既然都说的异步请求了,顺道也就讲下异步调用的相关知识点吧。至于Docker系列,鉴于本人也是初学者,写起来还是比较慢的,有时间就更吧~</p> <p><br></p> <p><strong><span style="color: rgb(255, 76, 65);">最后</span></strong></p> <p><br></p> <p>目前互联网上很多大佬都有SpringBoot系列教程,如有雷同,请多多包涵了。本文是作者在电脑前一字一句敲的,每一步都是实践的。若文中有所错误之处,还望提出,谢谢。</p> <p><br></p> <section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);word-wrap: break-word !important;"> <section class="" style="margin-top: 10px;margin-bottom: 10px;max-width: 100%;box-sizing: border-box;text-align: left;word-wrap: break-word !important;"> <section class="" style="padding: 10px;max-width: 100%;box-sizing: border-box;display: inline-block;width: 668px;border-width: 1px;border-style: solid;border-color: rgb(226, 226, 226);box-shadow: rgb(226, 226, 226) 0px 16px 1px -13px;word-wrap: break-word !important;"> <section class="" powered-by="xiumi.us" style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"> <section class="" style="max-width: 100%;box-sizing: border-box;word-wrap: break-word !important;"> <section class="" style="max-width: 100%;box-sizing: border-box;color: rgb(93, 93, 93);word-wrap: break-word !important;"> <p class="" style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-size: 13px;word-wrap: break-word !important;">【关于投稿】</p> <p class="" style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-size: 13px;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <p class="" style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-size: 13px;word-wrap: break-word !important;">如果大家有原创好文投稿,请直接给公号发送留言。</p> <p class="" style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-size: 13px;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <p class="" style="max-width: 100%;box-sizing: border-box;min-height: 1em;font-size: 13px;word-wrap: break-word !important;"><span style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;">①&nbsp;留言格式:</span><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;">【投稿】+《&nbsp;文章标题》+&nbsp;文章链接</span><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;">②&nbsp;示例:</span><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;">【投稿】《不要自称是程序员,我十多年的&nbsp;IT&nbsp;职场总结》:http://blog.jobbole.com/94148/</span><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><br style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(53, 53, 53);box-sizing: border-box !important;word-wrap: break-word !important;">③&nbsp;最后请附上您的个人简介哈~</span></span></p> <p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> </section> </section> </section> </section> </section> </section> <p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;text-align: justify;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;word-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;word-wrap: break-word !important;"></p> <p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;word-wrap: break-word !important;"><span style="max-width: 100%;font-size: 14px;color: rgb(255, 169, 0);box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: break-word !important;">看完本文有收获?请转发分享给更多人</span></p> <p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;word-wrap: break-word !important;"><strong style="max-width: 100%;color: rgb(255, 169, 0);box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: break-word !important;">关注「ImportNew」,提升Java技能</strong></p> <p style="max-width: 100%;min-height: 1em;color: rgb(51, 51, 51);font-family: -apple-system-font, system-ui, &quot;Helvetica Neue&quot;, &quot;PingFang SC&quot;, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei UI&quot;, &quot;Microsoft YaHei&quot;, Arial, sans-serif;font-size: 17px;letter-spacing: 0.544px;white-space: normal;background-color: rgb(255, 255, 255);text-align: center;box-sizing: border-box !important;word-wrap: break-word !important;"><img class="" data-ratio="0.9166666666666666" data-s="300,640" data-type="png" data-w="600" width="auto" src="/upload/899866149276fa5fddb73c61ae04be64.png" style="box-sizing: border-box !important;word-wrap: break-word !important;overflow-wrap: break-word !important;visibility: visible !important;width: 600px !important;"></p>