├── .gitignore ├── LICENSE ├── README.md ├── SpringBoot-Druid ├── README.md ├── pom.xml ├── springbootcluster.sql ├── springbootcluster1.sql ├── springbootmaster.sql └── src │ ├── main │ ├── java │ │ └── com │ │ │ ├── App.java │ │ │ └── lengchuan │ │ │ └── springBoot │ │ │ └── druid │ │ │ ├── ReadAndWrite │ │ │ ├── annotation │ │ │ │ └── TargetDataSource.java │ │ │ ├── aspect │ │ │ │ └── DynamicDataSourceAspect.java │ │ │ └── config │ │ │ │ ├── DataSourceConfig.java │ │ │ │ ├── DynamicDataSource.java │ │ │ │ ├── DynamicDataSourceHolder.java │ │ │ │ ├── Read1DruidDataSourceConfig.java │ │ │ │ ├── Read2DruidDataSourceConfig.java │ │ │ │ └── WriteDruidDataSourceConfig.java │ │ │ ├── config │ │ │ ├── Cluster1DruidDataSourceConfig.java │ │ │ ├── ClusterDruidDataSourceConfig.java │ │ │ └── MasterDruidDataSourceConfig.java │ │ │ ├── controller │ │ │ └── StudentController.java │ │ │ ├── mapper │ │ │ ├── cluster │ │ │ │ └── ClassMapper.java │ │ │ ├── cluster1 │ │ │ │ └── TeacherMapper.java │ │ │ └── master │ │ │ │ └── StudentMapper.java │ │ │ ├── model │ │ │ ├── Class.java │ │ │ ├── Student.java │ │ │ └── Teacher.java │ │ │ ├── monitor │ │ │ ├── DruidStatFilter.java │ │ │ ├── DruidStatViewServlet.java │ │ │ └── MyDruidStatInterceptor.java │ │ │ └── service │ │ │ ├── ClassService.java │ │ │ ├── StudentService.java │ │ │ └── TeacherService.java │ └── resources │ │ ├── application.properties │ │ └── mapper │ │ ├── cluster │ │ └── ClassMapper.xml │ │ ├── cluster1 │ │ └── TeacherMapper.xml │ │ └── master │ │ └── StudentMapper.xml │ └── test │ └── java │ └── com │ ├── BaseTest.java │ └── lengchuan │ └── springBoot │ └── druid │ └── service │ ├── ClassServiceTest.java │ ├── StudentServiceTest.java │ └── TeacherServiceTest.java ├── SpringBoot-Dubbo ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── lengchuan │ └── App.java ├── SpringBoot-FastJson ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ ├── App.java │ └── lengchuan │ └── springBoot │ ├── controller │ └── UserController.java │ ├── converter │ ├── EncrypConverter.java │ └── FastJsonConverter.java │ ├── druid │ └── model │ │ └── User.java │ └── util │ ├── Base64.java │ └── HttpBody.java ├── SpringBoot-GlobalExceptionHandler ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ ├── App.java │ └── lengchuan │ └── springBoot │ ├── Exception │ ├── MyException1.java │ └── MyException2.java │ ├── controller │ └── DemoController.java │ ├── controller2 │ └── DemoController2.java │ └── exceptionHandler │ ├── ExceptionHandler.java │ ├── ExceptionHandler1.java │ └── ExceptionHandler2.java ├── SpringBoot-HelloWorld-1 ├── pom.xml └── src │ └── main │ └── java │ └── HelloWorldAppTest1.java ├── SpringBoot-HelloWorld-2 ├── README.md ├── pom.xml └── src │ └── main │ └── java │ └── com │ └── lengchuan │ ├── HelloWorldApp2.java │ └── springBoot │ ├── DemoController.java │ └── User.java ├── SpringBoot-JuintTest ├── README.md ├── pom.xml └── src │ ├── main │ └── java │ │ └── com │ │ ├── App.java │ │ └── lengchuan │ │ └── springBoot │ │ └── druid │ │ └── service │ │ └── HelloWorldService.java │ └── test │ └── java │ └── com │ └── lengchuan │ └── springBoot │ └── druid │ └── service │ └── HelloWorldServiceTest.java ├── SpringBoot-Mybatis ├── README.md ├── pom.xml ├── springboottest.sql └── src │ ├── main │ ├── java │ │ └── com │ │ │ ├── App.java │ │ │ └── lengchuan │ │ │ └── springBoot │ │ │ └── druid │ │ │ ├── config │ │ │ ├── MapperScannerConfig.java │ │ │ └── MybatisConfig.java │ │ │ ├── mapper │ │ │ └── UserMapper.java │ │ │ ├── model │ │ │ └── User.java │ │ │ └── service │ │ │ └── UserService.java │ └── resources │ │ ├── application.properties │ │ └── mapper │ │ └── UserMapper.xml │ └── test │ └── java │ └── com │ └── lengchuan │ └── springBoot │ └── druid │ └── service │ └── UserServiceTest.java ├── SpringBoot-Redis ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ ├── App.java │ │ │ └── lengchuan │ │ │ └── springBoot │ │ │ └── redis │ │ │ ├── config │ │ │ ├── FastJsonRedisSerializer.java │ │ │ └── RedisTemplateConfig.java │ │ │ ├── dao │ │ │ └── UserDao.java │ │ │ ├── model │ │ │ ├── Entity.java │ │ │ └── User.java │ │ │ └── service │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ └── UserServiceImpl.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ ├── BaseTest.java │ └── lengchuan │ └── springBoot │ └── redis │ └── service │ └── impl │ └── UserServiceImplTest.java ├── SpringBoot-SpringDataJPA ├── README.md ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ ├── App.java │ │ │ └── lengchuan │ │ │ └── springBoot │ │ │ └── jpa │ │ │ ├── config │ │ │ ├── ReadAndWrite │ │ │ │ ├── annotation │ │ │ │ │ └── TargetDataSource.java │ │ │ │ ├── aspect │ │ │ │ │ └── DynamicDataSourceAspect.java │ │ │ │ └── config │ │ │ │ │ ├── DataSourceConfig.java │ │ │ │ │ ├── DynamicDataSource.java │ │ │ │ │ └── DynamicDataSourceHolder.java │ │ │ └── dataSource │ │ │ │ ├── DruidDataSourceConfig.java │ │ │ │ ├── ReadDataSourceConfig.java │ │ │ │ ├── ReadDataSourceConfig1.java │ │ │ │ ├── WriteDataSourceConfig.java │ │ │ │ └── WriteDataSourceConfig1.java │ │ │ ├── entity │ │ │ └── City.java │ │ │ ├── repository │ │ │ └── CityRepository.java │ │ │ └── service │ │ │ ├── CityService.java │ │ │ └── impl │ │ │ └── CityServiceImpl.java │ └── resources │ │ └── application.properties │ └── test │ └── java │ └── com │ ├── BaseTest.java │ └── lengchuan │ └── springBoot │ └── jpa │ └── service │ └── impl │ └── CityServiceImplTest.java └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | *.class 3 | *.log 4 | *.ctxt 5 | .mtj.tmp/ 6 | *.jar 7 | *.war 8 | *.ear 9 | *.zip 10 | *.tar.gz 11 | *.rar 12 | hs_err_pid* 13 | .metadata 14 | bin/ 15 | tmp/ 16 | *.tmp 17 | *.bak 18 | *.swp 19 | *~.nib 20 | local.properties 21 | .settings/ 22 | .loadpath 23 | .recommenders 24 | .project 25 | .externalToolBuilders/ 26 | *.launch 27 | *.pydevproject 28 | .cproject 29 | .classpath 30 | .factorypath 31 | .buildpath 32 | .target 33 | .tern-project 34 | .texlipse 35 | .springBeans 36 | .recommenders/ 37 | .cache-main 38 | .scala_dependencies 39 | .worksheet 40 | 将删除 .idea/ 41 | 将删除 SpringBoot-HelloWorld/HelloWorld1.iml 42 | 将删除 SpringBoot-HelloWorld/src/main/java/com/ 43 | 将删除 SpringBoot-HelloWorld/src/main/resources/ 44 | 将删除 SpringBoot-HelloWorld/src/test/ 45 | 将删除 SpringBoot-HelloWorld/target/ 46 | 将删除 target/ 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SpringBoot -------------------------------------------------------------------------------- /SpringBoot-Druid/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SpringBoot-Study 7 | com.lengchuan 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | jar 12 | 13 | com.lengchuan 14 | SpringBoot-Druid 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-dependencies 21 | ${springboot.version} 22 | pom 23 | import 24 | 25 | 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-web 32 | 33 | 34 | 35 | org.mybatis.spring.boot 36 | mybatis-spring-boot-starter 37 | 1.2.0 38 | 39 | 40 | 41 | 42 | mysql 43 | mysql-connector-java 44 | 6.0.3 45 | 46 | 47 | 48 | 49 | com.github.pagehelper 50 | pagehelper 51 | 4.2.1 52 | 53 | 54 | 55 | 56 | com.alibaba 57 | druid 58 | 1.0.29 59 | 60 | 61 | 62 | org.springframework.boot 63 | spring-boot-starter-test 64 | test 65 | 66 | 67 | org.aspectj 68 | aspectjrt 69 | 70 | 71 | org.aspectj 72 | aspectjtools 73 | 74 | 75 | org.aspectj 76 | aspectjweaver 77 | 78 | 79 | 80 | 81 | 82 | 83 | org.springframework.boot 84 | spring-boot-maven-plugin 85 | 86 | 87 | 88 | repackage 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /SpringBoot-Druid/springbootcluster.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : 127.0.0.1 5 | Source Server Version : 50717 6 | Source Host : localhost:3306 7 | Source Database : springbootcluster 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50717 11 | File Encoding : 65001 12 | 13 | Date: 2017-04-05 21:35:28 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for class 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `class`; 22 | CREATE TABLE `class` ( 23 | `id` int(11) NOT NULL AUTO_INCREMENT, 24 | `className` varchar(30) NOT NULL, 25 | PRIMARY KEY (`id`) 26 | ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; 27 | 28 | -- ---------------------------- 29 | -- Records of class 30 | -- ---------------------------- 31 | INSERT INTO `class` VALUES ('1', 'test'); 32 | INSERT INTO `class` VALUES ('2', 'test'); 33 | INSERT INTO `class` VALUES ('3', 'test'); 34 | -------------------------------------------------------------------------------- /SpringBoot-Druid/springbootcluster1.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : 127.0.0.1 5 | Source Server Version : 50717 6 | Source Host : localhost:3306 7 | Source Database : springbootcluster1 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50717 11 | File Encoding : 65001 12 | 13 | Date: 2017-04-05 21:35:39 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for teacher 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `teacher`; 22 | CREATE TABLE `teacher` ( 23 | `id` int(11) NOT NULL AUTO_INCREMENT, 24 | `name` varchar(20) NOT NULL DEFAULT '', 25 | PRIMARY KEY (`id`) 26 | ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4; 27 | 28 | -- ---------------------------- 29 | -- Records of teacher 30 | -- ---------------------------- 31 | INSERT INTO `teacher` VALUES ('1', 'test'); 32 | INSERT INTO `teacher` VALUES ('2', 'test'); 33 | -------------------------------------------------------------------------------- /SpringBoot-Druid/springbootmaster.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : 127.0.0.1 5 | Source Server Version : 50717 6 | Source Host : localhost:3306 7 | Source Database : springbootmaster 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50717 11 | File Encoding : 65001 12 | 13 | Date: 2017-04-07 22:10:52 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for student 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `student`; 22 | CREATE TABLE `student` ( 23 | `id` int(11) NOT NULL AUTO_INCREMENT, 24 | `name` varchar(20) NOT NULL, 25 | `email` varchar(64) NOT NULL DEFAULT '', 26 | `age` int(11) NOT NULL, 27 | `birthday` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 28 | PRIMARY KEY (`id`) 29 | ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8; 30 | 31 | -- ---------------------------- 32 | -- Records of student 33 | -- ---------------------------- 34 | INSERT INTO `student` VALUES ('3', 'test1', 'test@test.com', '1', '2017-04-04 02:54:18'); 35 | INSERT INTO `student` VALUES ('4', 'test1', 'test@test.com', '1', '2017-04-04 02:56:19'); 36 | INSERT INTO `student` VALUES ('8', 'test1', 'test@test.com', '1', '2017-04-04 03:59:13'); 37 | INSERT INTO `student` VALUES ('11', 'test1', 'test@test.com', '1', '2017-04-07 08:52:59'); 38 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/App.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import com.lengchuan.springBoot.druid.model.Class; 4 | import com.lengchuan.springBoot.druid.model.Student; 5 | import com.lengchuan.springBoot.druid.service.ClassService; 6 | import com.lengchuan.springBoot.druid.service.StudentService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.CommandLineRunner; 9 | import org.springframework.boot.SpringApplication; 10 | import org.springframework.boot.autoconfigure.SpringBootApplication; 11 | import org.springframework.boot.web.servlet.ServletComponentScan; 12 | 13 | import java.util.Date; 14 | 15 | /** 16 | * @author lengchuan 17 | * @date 17-4-4 18 | */ 19 | @SpringBootApplication 20 | @ServletComponentScan("com.lengchuan.springBoot.dataSource.monitor")//扫描servlet配置 21 | public class App implements CommandLineRunner { 22 | 23 | @Autowired 24 | private StudentService studentService; 25 | 26 | @Autowired 27 | private ClassService classService; 28 | 29 | /** 30 | * Callback used to run the bean. 31 | * 32 | * @param args incoming main method arguments 33 | * @throws Exception on error 34 | */ 35 | public void run(String... args) throws Exception { 36 | Student student = new Student(); 37 | student.setAge(1); 38 | student.setBirthday(new Date()); 39 | student.setEmail("123@123.com"); 40 | student.setName("test"); 41 | //studentService.createUser(student); 42 | //studentService.getByPage(1,2); 43 | 44 | // 45 | Class c = new Class(); 46 | c.setClassName("test"); 47 | //classService.createClass(c); 48 | } 49 | 50 | public static void main(String[] args) { 51 | SpringApplication.run(App.class, args); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/ReadAndWrite/annotation/TargetDataSource.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.ReadAndWrite.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 切换数据源 7 | * 8 | * @author lengchuan 9 | * @date 17-4-5 10 | */ 11 | @Target({ElementType.METHOD, ElementType.TYPE}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | public @interface TargetDataSource { 15 | String dataSource() default "";//数据源 16 | } 17 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/ReadAndWrite/aspect/DynamicDataSourceAspect.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.ReadAndWrite.aspect; 2 | 3 | import com.lengchuan.springBoot.druid.ReadAndWrite.annotation.TargetDataSource; 4 | import com.lengchuan.springBoot.druid.ReadAndWrite.config.DynamicDataSourceHolder; 5 | import org.aspectj.lang.ProceedingJoinPoint; 6 | import org.aspectj.lang.annotation.Around; 7 | import org.aspectj.lang.annotation.Aspect; 8 | import org.aspectj.lang.reflect.MethodSignature; 9 | import org.springframework.stereotype.Component; 10 | 11 | import java.lang.reflect.Method; 12 | 13 | /** 14 | * aop 配置动态切换数据源 15 | * 16 | * @author lengchuan 17 | * @date 17-4-5 18 | */ 19 | @Aspect 20 | @Component 21 | public class DynamicDataSourceAspect { 22 | @Around("execution(public * com.lengchuan.springBoot.druid.service..*.*(..))") 23 | public Object around(ProceedingJoinPoint pjp) throws Throwable { 24 | MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); 25 | Method targetMethod = methodSignature.getMethod(); 26 | if (targetMethod.isAnnotationPresent(TargetDataSource.class)) { 27 | String targetDataSource = targetMethod.getAnnotation(TargetDataSource.class).dataSource(); 28 | System.out.println("----------数据源是:" + targetDataSource + "------"); 29 | DynamicDataSourceHolder.setDataSource(targetDataSource); 30 | } 31 | Object result = pjp.proceed();//执行方法 32 | return result; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/ReadAndWrite/config/DataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.ReadAndWrite.config; 2 | 3 | import org.springframework.beans.factory.annotation.Qualifier; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 7 | 8 | import javax.sql.DataSource; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author lengchuan 14 | * @date 17 -4-5 15 | */ 16 | @Configuration 17 | public class DataSourceConfig { 18 | 19 | private final static String WRITE_DATASOURCE_KEY = "writeDataSource"; 20 | private final static String READ1_DATASOURCE_KEY = "read1DataSource"; 21 | private final static String READ2_DATASOURCE_KEY = "read2DataSource"; 22 | 23 | /** 24 | * 注入AbstractRoutingDataSource 25 | * @param writeDataSource 26 | * @param read1DataSource 27 | * @param read2DataSource 28 | * @return 29 | * @throws Exception 30 | */ 31 | @Bean 32 | public AbstractRoutingDataSource routingDataSource( 33 | @Qualifier("writeDataSource") DataSource writeDataSource, 34 | @Qualifier("read1DataSource") DataSource read1DataSource, 35 | @Qualifier("read2DataSource") DataSource read2DataSource 36 | ) throws Exception { 37 | DynamicDataSource dataSource = new DynamicDataSource(); 38 | Map targetDataSources = new HashMap(); 39 | targetDataSources.put(WRITE_DATASOURCE_KEY, writeDataSource); 40 | targetDataSources.put(READ1_DATASOURCE_KEY, read1DataSource); 41 | targetDataSources.put(READ2_DATASOURCE_KEY, read2DataSource); 42 | dataSource.setTargetDataSources(targetDataSources); 43 | dataSource.setDefaultTargetDataSource(writeDataSource); 44 | return dataSource; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/ReadAndWrite/config/DynamicDataSource.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.ReadAndWrite.config; 2 | 3 | import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-4-5 8 | */ 9 | public class DynamicDataSource extends AbstractRoutingDataSource { 10 | @Override 11 | protected Object determineCurrentLookupKey() { 12 | 13 | //可以做一个简单的负载均衡策略 14 | String lookupKey = DynamicDataSourceHolder.getDataSource(); 15 | System.out.println("------------lookupKey---------"+lookupKey); 16 | 17 | return lookupKey; 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/ReadAndWrite/config/DynamicDataSourceHolder.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.ReadAndWrite.config; 2 | 3 | /** 4 | * @author lengchuan 5 | * @date 17-4-5 6 | */ 7 | public class DynamicDataSourceHolder { 8 | //使用ThreadLocal把数据源与当前线程绑定 9 | private static final ThreadLocal dataSources = new ThreadLocal(); 10 | 11 | public static void setDataSource(String dataSourceName) { 12 | dataSources.set(dataSourceName); 13 | } 14 | 15 | public static String getDataSource() { 16 | return dataSources.get(); 17 | } 18 | 19 | public static void clearDataSource() { 20 | dataSources.remove(); 21 | } 22 | } -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/ReadAndWrite/config/Read1DruidDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.ReadAndWrite.config; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import com.github.pagehelper.PageHelper; 5 | import org.apache.ibatis.plugin.Interceptor; 6 | import org.apache.ibatis.session.SqlSessionFactory; 7 | import org.mybatis.spring.SqlSessionFactoryBean; 8 | import org.mybatis.spring.annotation.MapperScan; 9 | import org.springframework.beans.factory.annotation.Qualifier; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.boot.context.properties.ConfigurationProperties; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 15 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 16 | 17 | import javax.sql.DataSource; 18 | import java.util.Properties; 19 | 20 | /** 21 | * read1节点数据源配置 22 | * 23 | * @author lengchuan 24 | * @date 17-4-4 25 | */ 26 | @Configuration 27 | @MapperScan(basePackages = {"com.lengchuan.springBoot.druid.mapper.read1"}, 28 | sqlSessionFactoryRef = "read1SqlSessionFactory") 29 | public class Read1DruidDataSourceConfig { 30 | 31 | @Value("${spring.datasource.read1.read1MapperLocations}") 32 | private String read1MapperLocations; 33 | 34 | @ConfigurationProperties(prefix = "spring.datasource.read1") 35 | @Bean(name = "read1DataSource") 36 | public DataSource read1DataSource() { 37 | return new DruidDataSource(); 38 | } 39 | 40 | /** 41 | * SqlSessionFactory配置 42 | * 43 | * @return 44 | * @throws Exception 45 | */ 46 | @Bean(name = "read1SqlSessionFactory") 47 | public SqlSessionFactory read1SqlSessionFactory( 48 | @Qualifier("read1DataSource") DataSource dataSource 49 | ) throws Exception { 50 | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 51 | sqlSessionFactoryBean.setDataSource(dataSource); 52 | 53 | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 54 | // 配置mapper文件位置 55 | sqlSessionFactoryBean.setMapperLocations(resolver.getResources(read1MapperLocations)); 56 | 57 | //配置分页插件 58 | PageHelper pageHelper = new PageHelper(); 59 | Properties properties = new Properties(); 60 | properties.setProperty("reasonable", "true"); 61 | properties.setProperty("supportMethodsArguments", "true"); 62 | properties.setProperty("returnPageInfo", "check"); 63 | properties.setProperty("params", "count=countSql"); 64 | pageHelper.setProperties(properties); 65 | 66 | //设置插件 67 | sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper}); 68 | return sqlSessionFactoryBean.getObject(); 69 | } 70 | 71 | /** 72 | * 配置事物管理器 73 | * 74 | * @return 75 | */ 76 | @Bean(name = "read1TransactionManager") 77 | public DataSourceTransactionManager read1TransactionManager( 78 | @Qualifier("read1DataSource") DataSource dataSource 79 | ) { 80 | DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); 81 | dataSourceTransactionManager.setDataSource(dataSource); 82 | return dataSourceTransactionManager; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/ReadAndWrite/config/Read2DruidDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.ReadAndWrite.config; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import com.github.pagehelper.PageHelper; 5 | import org.apache.ibatis.plugin.Interceptor; 6 | import org.apache.ibatis.session.SqlSessionFactory; 7 | import org.mybatis.spring.SqlSessionFactoryBean; 8 | import org.mybatis.spring.annotation.MapperScan; 9 | import org.springframework.beans.factory.annotation.Qualifier; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.boot.context.properties.ConfigurationProperties; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 15 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 16 | 17 | import javax.sql.DataSource; 18 | import java.util.Properties; 19 | 20 | /** 21 | * read2节点数据源配置 22 | * 23 | * @author lengchuan 24 | * @date 17-4-4 25 | */ 26 | @Configuration 27 | @MapperScan(basePackages = {"com.lengchuan.springBoot.druid.mapper.read2"}, 28 | sqlSessionFactoryRef = "read2SqlSessionFactory") 29 | public class Read2DruidDataSourceConfig { 30 | 31 | @Value("${spring.datasource.read2.read2MapperLocations}") 32 | private String read2MapperLocations; 33 | 34 | @ConfigurationProperties(prefix = "spring.datasource.read2") 35 | @Bean(name = "read2DataSource") 36 | public DataSource read2DataSource() { 37 | return new DruidDataSource(); 38 | } 39 | 40 | /** 41 | * SqlSessionFactory配置 42 | * 43 | * @return 44 | * @throws Exception 45 | */ 46 | @Bean(name = "read2SqlSessionFactory") 47 | public SqlSessionFactory read2SqlSessionFactory( 48 | @Qualifier("read2DataSource") DataSource dataSource 49 | ) throws Exception { 50 | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 51 | sqlSessionFactoryBean.setDataSource(dataSource); 52 | 53 | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 54 | // 配置mapper文件位置 55 | sqlSessionFactoryBean.setMapperLocations(resolver.getResources(read2MapperLocations)); 56 | 57 | //配置分页插件 58 | PageHelper pageHelper = new PageHelper(); 59 | Properties properties = new Properties(); 60 | properties.setProperty("reasonable", "true"); 61 | properties.setProperty("supportMethodsArguments", "true"); 62 | properties.setProperty("returnPageInfo", "check"); 63 | properties.setProperty("params", "count=countSql"); 64 | pageHelper.setProperties(properties); 65 | 66 | //设置插件 67 | sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper}); 68 | return sqlSessionFactoryBean.getObject(); 69 | } 70 | 71 | /** 72 | * 配置事物管理器 73 | * 74 | * @return 75 | */ 76 | @Bean(name = "read2TransactionManager") 77 | public DataSourceTransactionManager read2TransactionManager( 78 | @Qualifier("read2DataSource") DataSource dataSource 79 | ) { 80 | DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); 81 | dataSourceTransactionManager.setDataSource(dataSource); 82 | return dataSourceTransactionManager; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/ReadAndWrite/config/WriteDruidDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.ReadAndWrite.config; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import org.apache.ibatis.session.SqlSessionFactory; 5 | import org.mybatis.spring.SqlSessionFactoryBean; 6 | import org.mybatis.spring.annotation.MapperScan; 7 | import org.springframework.beans.factory.annotation.Qualifier; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.boot.context.properties.ConfigurationProperties; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 13 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 14 | 15 | import javax.sql.DataSource; 16 | 17 | /** 18 | * write节点数据源配置 19 | * 20 | * @author lengchuan 21 | * @date 17-4-4 22 | */ 23 | @Configuration 24 | @MapperScan(basePackages = {"com.lengchuan.springBoot.druid.mapper.write"}, 25 | sqlSessionFactoryRef = "writeSqlSessionFactory") 26 | public class WriteDruidDataSourceConfig { 27 | 28 | @Value("${spring.datasource.write.writeMapperLocations}") 29 | private String writeMapperLocations; 30 | 31 | @ConfigurationProperties(prefix = "spring.datasource.write") 32 | @Bean(name = "writeDataSource") 33 | public DataSource writeDataSource() { 34 | return new DruidDataSource(); 35 | } 36 | 37 | /** 38 | * SqlSessionFactory配置 39 | * 40 | * @return 41 | * @throws Exception 42 | */ 43 | @Bean(name = "writeSqlSessionFactory") 44 | public SqlSessionFactory writeSqlSessionFactory( 45 | @Qualifier("writeDataSource") DataSource dataSource 46 | ) throws Exception { 47 | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 48 | sqlSessionFactoryBean.setDataSource(dataSource); 49 | 50 | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 51 | // 配置mapper文件位置 52 | sqlSessionFactoryBean.setMapperLocations(resolver.getResources(writeMapperLocations)); 53 | return sqlSessionFactoryBean.getObject(); 54 | } 55 | 56 | /** 57 | * 配置事物管理器 58 | * 59 | * @return 60 | */ 61 | @Bean(name = "writeTransactionManager") 62 | public DataSourceTransactionManager writeTransactionManager( 63 | @Qualifier("writeDataSource") DataSource dataSource 64 | ) { 65 | DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); 66 | dataSourceTransactionManager.setDataSource(dataSource); 67 | return dataSourceTransactionManager; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/config/Cluster1DruidDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.config; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import com.github.pagehelper.PageHelper; 5 | import org.apache.ibatis.plugin.Interceptor; 6 | import org.apache.ibatis.session.SqlSessionFactory; 7 | import org.mybatis.spring.SqlSessionFactoryBean; 8 | import org.mybatis.spring.annotation.MapperScan; 9 | import org.springframework.beans.factory.annotation.Qualifier; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.boot.context.properties.ConfigurationProperties; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 15 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 16 | 17 | import javax.sql.DataSource; 18 | import java.util.Properties; 19 | 20 | /** 21 | * cluster1节点数据源配置 22 | * 23 | * @author lengchuan 24 | * @date 17-4-4 25 | */ 26 | @Configuration 27 | @MapperScan(basePackages = {"com.lengchuan.springBoot.druid.mapper.cluster1"}, 28 | sqlSessionFactoryRef = "cluster1SqlSessionFactory") 29 | public class Cluster1DruidDataSourceConfig { 30 | 31 | @Value("${spring.datasource.cluster1.clusterMapperLocations}") 32 | private String cluster1MapperLocations; 33 | 34 | @ConfigurationProperties(prefix = "spring.datasource.cluster1") 35 | @Bean(name = "cluster1DataSource") 36 | public DataSource cluster1DataSource() { 37 | return new DruidDataSource(); 38 | } 39 | 40 | /** 41 | * SqlSessionFactory配置 42 | * 43 | * @return 44 | * @throws Exception 45 | */ 46 | @Bean(name = "cluster1SqlSessionFactory") 47 | public SqlSessionFactory cluster1SqlSessionFactory( 48 | @Qualifier("cluster1DataSource") DataSource dataSource 49 | ) throws Exception { 50 | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 51 | sqlSessionFactoryBean.setDataSource(dataSource); 52 | 53 | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 54 | //配置mapper文件位置 55 | sqlSessionFactoryBean.setMapperLocations(resolver.getResources(cluster1MapperLocations)); 56 | 57 | //配置分页插件 58 | PageHelper pageHelper = new PageHelper(); 59 | Properties properties = new Properties(); 60 | properties.setProperty("reasonable", "true"); 61 | properties.setProperty("supportMethodsArguments", "true"); 62 | properties.setProperty("returnPageInfo", "check"); 63 | properties.setProperty("params", "count=countSql"); 64 | pageHelper.setProperties(properties); 65 | 66 | //设置插件 67 | sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper}); 68 | return sqlSessionFactoryBean.getObject(); 69 | } 70 | 71 | /** 72 | * 配置事物管理器 73 | * 74 | * @return 75 | */ 76 | @Bean(name = "cluster1TransactionManager") 77 | public DataSourceTransactionManager cluster1TransactionManager( 78 | @Qualifier("cluster1DataSource") DataSource dataSource 79 | ) { 80 | DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); 81 | dataSourceTransactionManager.setDataSource(dataSource); 82 | return dataSourceTransactionManager; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/config/ClusterDruidDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.config; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import com.github.pagehelper.PageHelper; 5 | import org.apache.ibatis.plugin.Interceptor; 6 | import org.apache.ibatis.session.SqlSessionFactory; 7 | import org.mybatis.spring.SqlSessionFactoryBean; 8 | import org.mybatis.spring.annotation.MapperScan; 9 | import org.springframework.beans.factory.annotation.Qualifier; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.boot.context.properties.ConfigurationProperties; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 15 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 16 | 17 | import javax.sql.DataSource; 18 | import java.sql.SQLException; 19 | import java.util.Properties; 20 | 21 | /** 22 | * cluster节点数据源配置 23 | * 24 | * @author lengchuan 25 | * @date 17-4-4 26 | */ 27 | @Configuration 28 | @MapperScan(basePackages = {"com.lengchuan.springBoot.druid.mapper.cluster"}, 29 | sqlSessionFactoryRef = "clusterSqlSessionFactory") 30 | public class ClusterDruidDataSourceConfig { 31 | 32 | @Value("${spring.datasource.cluster.clusterMapperLocations}") 33 | private String clusterMapperLocations; 34 | 35 | @ConfigurationProperties(prefix = "spring.datasource.cluster") 36 | @Bean(name = "clusterDataSource") 37 | public DataSource clusterDataSource() { 38 | DruidDataSource dataSource = new DruidDataSource(); 39 | try { 40 | dataSource.setFilters("stat,wall,log4j"); 41 | dataSource.setUseGlobalDataSourceStat(true); 42 | } catch (SQLException e) { 43 | // 44 | } 45 | return dataSource; 46 | } 47 | 48 | /** 49 | * SqlSessionFactory配置 50 | * 51 | * @return 52 | * @throws Exception 53 | */ 54 | @Bean(name = "clusterSqlSessionFactory") 55 | public SqlSessionFactory clusterSqlSessionFactory( 56 | @Qualifier("clusterDataSource") DataSource dataSource 57 | ) throws Exception { 58 | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 59 | sqlSessionFactoryBean.setDataSource(dataSource); 60 | 61 | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 62 | //配置mapper文件位置 63 | sqlSessionFactoryBean.setMapperLocations(resolver.getResources(clusterMapperLocations)); 64 | 65 | //配置分页插件 66 | PageHelper pageHelper = new PageHelper(); 67 | Properties properties = new Properties(); 68 | properties.setProperty("reasonable", "true"); 69 | properties.setProperty("supportMethodsArguments", "true"); 70 | properties.setProperty("returnPageInfo", "check"); 71 | properties.setProperty("params", "count=countSql"); 72 | pageHelper.setProperties(properties); 73 | 74 | //设置插件 75 | sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper}); 76 | return sqlSessionFactoryBean.getObject(); 77 | } 78 | 79 | /** 80 | * 配置事物管理器 81 | * 82 | * @return 83 | */ 84 | @Bean(name = "clusterTransactionManager") 85 | public DataSourceTransactionManager clusterTransactionManager( 86 | @Qualifier("clusterDataSource") DataSource dataSource 87 | ) { 88 | DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); 89 | dataSourceTransactionManager.setDataSource(dataSource); 90 | return dataSourceTransactionManager; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/config/MasterDruidDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.config; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import com.github.pagehelper.PageHelper; 5 | import org.apache.ibatis.plugin.Interceptor; 6 | import org.apache.ibatis.session.SqlSessionFactory; 7 | import org.mybatis.spring.SqlSessionFactoryBean; 8 | import org.mybatis.spring.annotation.MapperScan; 9 | import org.springframework.beans.factory.annotation.Qualifier; 10 | import org.springframework.beans.factory.annotation.Value; 11 | import org.springframework.boot.context.properties.ConfigurationProperties; 12 | import org.springframework.context.annotation.Bean; 13 | import org.springframework.context.annotation.Configuration; 14 | import org.springframework.context.annotation.Primary; 15 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 16 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 17 | 18 | import javax.sql.DataSource; 19 | import java.sql.SQLException; 20 | import java.util.Properties; 21 | 22 | /** 23 | * master节点数据源配置 24 | * 25 | * @author lengchuan 26 | * @date 17-4-4 27 | */ 28 | @Configuration 29 | @MapperScan(basePackages = {"com.lengchuan.springBoot.druid.mapper.master"}, 30 | sqlSessionFactoryRef = "masterSqlSessionFactory") 31 | public class MasterDruidDataSourceConfig { 32 | 33 | @Value("${spring.datasource.master.masterMapperLocations}") 34 | private String masterMapperLocations; 35 | 36 | @ConfigurationProperties(prefix = "spring.datasource.master") 37 | @Bean(name = "masterDataSource") 38 | @Primary 39 | public DataSource masterDataSource() { 40 | DruidDataSource dataSource = new DruidDataSource(); 41 | try { 42 | dataSource.setFilters("stat,wall,log4j"); 43 | } catch (SQLException e) { 44 | // 45 | } 46 | return dataSource; 47 | } 48 | 49 | /** 50 | * SqlSessionFactory配置 51 | * 52 | * @return 53 | * @throws Exception 54 | */ 55 | @Bean(name = "masterSqlSessionFactory") 56 | @Primary 57 | public SqlSessionFactory masterSqlSessionFactory( 58 | @Qualifier("masterDataSource") DataSource dataSource 59 | ) throws Exception { 60 | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 61 | sqlSessionFactoryBean.setDataSource(dataSource); 62 | 63 | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 64 | // 配置mapper文件位置 65 | sqlSessionFactoryBean.setMapperLocations(resolver.getResources(masterMapperLocations)); 66 | 67 | //配置分页插件 68 | PageHelper pageHelper = new PageHelper(); 69 | Properties properties = new Properties(); 70 | properties.setProperty("reasonable", "true"); 71 | properties.setProperty("supportMethodsArguments", "true"); 72 | properties.setProperty("returnPageInfo", "check"); 73 | properties.setProperty("params", "count=countSql"); 74 | pageHelper.setProperties(properties); 75 | 76 | //设置插件 77 | sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper}); 78 | return sqlSessionFactoryBean.getObject(); 79 | } 80 | 81 | /** 82 | * 配置事物管理器 83 | * 84 | * @return 85 | */ 86 | @Bean(name = "masterTransactionManager") 87 | @Primary 88 | public DataSourceTransactionManager masterTransactionManager( 89 | @Qualifier("masterDataSource") DataSource dataSource 90 | ) { 91 | DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); 92 | dataSourceTransactionManager.setDataSource(dataSource); 93 | return dataSourceTransactionManager; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/controller/StudentController.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.controller; 2 | 3 | import com.lengchuan.springBoot.druid.model.Student; 4 | import com.lengchuan.springBoot.druid.service.StudentService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author lengchuan 13 | * @date 17-4-8 14 | */ 15 | @RestController 16 | public class StudentController { 17 | 18 | @Autowired 19 | private StudentService studentService; 20 | 21 | @RequestMapping("/getStudents") 22 | public List getStudents(Integer page, Integer rows) { 23 | 24 | return studentService.getByPage(page, rows); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/mapper/cluster/ClassMapper.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.mapper.cluster; 2 | 3 | import com.lengchuan.springBoot.druid.model.Class; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-4-4 8 | */ 9 | public interface ClassMapper { 10 | 11 | int insert(Class c); 12 | } 13 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/mapper/cluster1/TeacherMapper.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.mapper.cluster1; 2 | 3 | import com.lengchuan.springBoot.druid.model.Teacher; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-4-4 8 | */ 9 | public interface TeacherMapper { 10 | 11 | int insert(Teacher teacher); 12 | } 13 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/mapper/master/StudentMapper.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.mapper.master; 2 | 3 | import com.lengchuan.springBoot.druid.model.Student; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author lengchuan 9 | * @date 17-4-4 10 | */ 11 | public interface StudentMapper { 12 | 13 | int insert(Student student); 14 | 15 | List getBypage(); 16 | } 17 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/model/Class.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-4-4 8 | */ 9 | public class Class implements Serializable { 10 | 11 | private int id; 12 | 13 | private String className; 14 | 15 | public int getId() { 16 | return id; 17 | } 18 | 19 | public void setId(int id) { 20 | this.id = id; 21 | } 22 | 23 | public String getClassName() { 24 | return className; 25 | } 26 | 27 | public void setClassName(String className) { 28 | this.className = className; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/model/Student.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * @author lengchuan 8 | * @date 17-4-4 9 | */ 10 | public class Student implements Serializable { 11 | private Integer id; 12 | 13 | private String name; 14 | 15 | private String email; 16 | 17 | private Integer age; 18 | 19 | private Date birthday; 20 | 21 | public Integer getId() { 22 | return id; 23 | } 24 | 25 | public void setId(Integer id) { 26 | this.id = id; 27 | } 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | public String getEmail() { 38 | return email; 39 | } 40 | 41 | public void setEmail(String email) { 42 | this.email = email; 43 | } 44 | 45 | public Integer getAge() { 46 | return age; 47 | } 48 | 49 | public void setAge(Integer age) { 50 | this.age = age; 51 | } 52 | 53 | public Date getBirthday() { 54 | return birthday; 55 | } 56 | 57 | public void setBirthday(Date birthday) { 58 | this.birthday = birthday; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/model/Teacher.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-4-5 8 | */ 9 | public class Teacher implements Serializable { 10 | 11 | private Integer id; 12 | 13 | private String name; 14 | 15 | public Integer getId() { 16 | return id; 17 | } 18 | 19 | public void setId(Integer id) { 20 | this.id = id; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(String name) { 28 | this.name = name; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/monitor/DruidStatFilter.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.monitor; 2 | 3 | import com.alibaba.druid.support.http.WebStatFilter; 4 | 5 | import javax.servlet.annotation.WebFilter; 6 | import javax.servlet.annotation.WebInitParam; 7 | 8 | /** 9 | * 配置过滤器,需要拦截哪些url,忽略哪些url,初始化参数等 10 | * 11 | * @author lengchuan 12 | * @date 17-4-7 13 | */ 14 | @WebFilter(filterName = "druidStatFilter",//过滤器名称 15 | urlPatterns = "/",//需要拦截的url 16 | initParams = {//filter初始化信息 17 | //需要忽略的资源 18 | @WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg," + 19 | "*.bmp,*.png,*.css,*.ico,/dataSource/*"), 20 | @WebInitParam(name = "sessionStatEnable", value = "true"), 21 | @WebInitParam(name = "profileEnable", value = "true")}) 22 | public class DruidStatFilter extends WebStatFilter { 23 | } 24 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/monitor/DruidStatViewServlet.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.monitor; 2 | 3 | import com.alibaba.druid.support.http.StatViewServlet; 4 | 5 | import javax.servlet.annotation.WebInitParam; 6 | import javax.servlet.annotation.WebServlet; 7 | 8 | /** 9 | * 配置一个servlet,让我们可以访问监控页面 10 | * 11 | * @author lengchuan 12 | * @date 17-4-7 13 | */ 14 | //表明这是一个servlet 15 | @WebServlet(urlPatterns = "/dataSource/*",//通过哪个url访问 16 | initParams = { 17 | @WebInitParam(name = "loginUsername", value = "lengchuan"),//用户名 18 | @WebInitParam(name = "loginPassword", value = "123456"), //密码 19 | @WebInitParam(name = "resetEnable", value = "true"),//是否可以重置 20 | // @WebInitParam(name = "allow",value = "127.0.0.1"),//白名单 21 | // @WebInitParam(name = "deny",value = "192.168.1.1")//黑名单 22 | }) 23 | public class DruidStatViewServlet extends StatViewServlet { 24 | } 25 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/monitor/MyDruidStatInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.monitor; 2 | 3 | import com.alibaba.druid.support.spring.stat.DruidStatInterceptor; 4 | import org.springframework.aop.Advisor; 5 | import org.springframework.aop.support.DefaultPointcutAdvisor; 6 | import org.springframework.aop.support.JdkRegexpMethodPointcut; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | 10 | /** 11 | * 配置Spring监控 12 | * 13 | * @author lengchuan 14 | * @date 17-4-8 15 | */ 16 | @Configuration 17 | public class MyDruidStatInterceptor { 18 | 19 | private static final String[] patterns = new String[]{"com.lengchuan.springBoot.dataSource.service.*"}; 20 | 21 | @Bean 22 | public DruidStatInterceptor druidStatInterceptor() { 23 | return new DruidStatInterceptor(); 24 | } 25 | 26 | /** 27 | * 切入点 28 | * @return 29 | */ 30 | @Bean 31 | public JdkRegexpMethodPointcut druidStatPointcut() { 32 | JdkRegexpMethodPointcut druidStatPointcut = new JdkRegexpMethodPointcut(); 33 | druidStatPointcut.setPatterns(patterns); 34 | return druidStatPointcut; 35 | } 36 | 37 | /** 38 | * 配置aop 39 | * @return 40 | */ 41 | @Bean 42 | public Advisor druidStatAdvisor() { 43 | return new DefaultPointcutAdvisor(druidStatPointcut(), druidStatInterceptor()); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/service/ClassService.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.service; 2 | 3 | import com.lengchuan.springBoot.druid.mapper.cluster.ClassMapper; 4 | import com.lengchuan.springBoot.druid.model.Class; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | import org.springframework.transaction.annotation.Transactional; 8 | 9 | /** 10 | * @author lengchuan 11 | * @date 17-4-4 12 | */ 13 | @Service 14 | public class ClassService { 15 | 16 | @Autowired 17 | private ClassMapper classMapper; 18 | 19 | @Transactional 20 | public boolean createClass(Class c) { 21 | classMapper.insert(c); 22 | return true; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/service/StudentService.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.service; 2 | 3 | import com.github.pagehelper.Page; 4 | import com.github.pagehelper.PageHelper; 5 | import com.lengchuan.springBoot.druid.ReadAndWrite.annotation.TargetDataSource; 6 | import com.lengchuan.springBoot.druid.mapper.master.StudentMapper; 7 | import com.lengchuan.springBoot.druid.model.Student; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Service; 10 | import org.springframework.transaction.annotation.Transactional; 11 | 12 | import java.util.List; 13 | 14 | /** 15 | * @author lengchuan 16 | * @date 17-4-4 17 | */ 18 | @Service 19 | public class StudentService { 20 | 21 | @Autowired 22 | private StudentMapper studentMapper; 23 | 24 | @Transactional 25 | @TargetDataSource(dataSource = "writeDataSource") 26 | public boolean createUser(Student student) { 27 | studentMapper.insert(student); 28 | 29 | //事务测试 30 | // int i = 1 / 0; 31 | return true; 32 | } 33 | 34 | @TargetDataSource(dataSource = "read1DataSource") 35 | public List getByPage(int page, int rows) { 36 | Page studentPage = PageHelper.startPage(page, rows, true); 37 | List students = studentMapper.getBypage(); 38 | System.out.println("-------------------" + studentPage.toString() + "-----------"); 39 | return students; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/java/com/lengchuan/springBoot/druid/service/TeacherService.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.service; 2 | 3 | import com.lengchuan.springBoot.druid.mapper.cluster1.TeacherMapper; 4 | import com.lengchuan.springBoot.druid.model.Teacher; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | import org.springframework.transaction.annotation.Transactional; 8 | 9 | /** 10 | * @author lengchuan 11 | * @date 17-4-4 12 | */ 13 | @Service 14 | public class TeacherService { 15 | 16 | @Autowired 17 | private TeacherMapper teacherMapper; 18 | 19 | @Transactional 20 | public boolean createTeacher(Teacher teacher) { 21 | teacherMapper.insert(teacher); 22 | return true; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #master数据源 2 | spring.datasource.master.url=jdbc:mysql://localhost:3306/SpringBootMaster 3 | spring.datasource.master.username=root 4 | spring.datasource.master.password=1 5 | spring.datasource.master.driver-class-name=com.mysql.jdbc.Driver 6 | spring.datasource.master.masterMapperLocations=classpath:mapper/master/*.xml 7 | # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 8 | 9 | #cluster数据源 10 | spring.datasource.cluster.url=jdbc:mysql://localhost:3306/SpringBootCluster 11 | spring.datasource.cluster.username=root 12 | spring.datasource.cluster.password=1 13 | spring.datasource.cluster.driver-class-name=com.mysql.jdbc.Driver 14 | spring.datasource.cluster.clusterMapperLocations=classpath:mapper/cluster/*.xml 15 | 16 | 17 | #cluster1数据源 18 | spring.datasource.cluster1.url=jdbc:mysql://localhost:3306/SpringBootCluster1 19 | spring.datasource.cluster1.username=root 20 | spring.datasource.cluster1.password=1 21 | spring.datasource.cluster1.driver-class-name=com.mysql.jdbc.Driver 22 | spring.datasource.cluster1.clusterMapperLocations=classpath:mapper/cluster1/*.xml 23 | 24 | 25 | #write数据源 26 | spring.datasource.write.url=jdbc:mysql://localhost:3306/SpringBootMaster 27 | spring.datasource.write.username=root 28 | spring.datasource.write.password=1 29 | spring.datasource.write.driver-class-name=com.mysql.jdbc.Driver 30 | spring.datasource.write.writeMapperLocations=classpath:mapper/master/*.xml 31 | 32 | #read数据源1 33 | spring.datasource.read1.url=jdbc:mysql://localhost:3306/SpringBootMaster 34 | spring.datasource.read1.username=root 35 | spring.datasource.read1.password=1 36 | spring.datasource.read1.driver-class-name=com.mysql.jdbc.Driver 37 | spring.datasource.read1.read1MapperLocations=classpath:mapper/master/*.xml 38 | 39 | 40 | #read数据源2 41 | spring.datasource.read2.url=jdbc:mysql://localhost:3306/SpringBootMaster 42 | spring.datasource.read2.username=root 43 | spring.datasource.read2.password=1 44 | spring.datasource.read2.driver-class-name=com.mysql.jdbc.Driver 45 | spring.datasource.read2.read2MapperLocations=classpath:mapper/master/*.xml 46 | 47 | 48 | #druid其它配置 49 | #dataSource 50 | # 初始化大小,最小,最大 51 | spring.datasource.druid.initialSize=5 52 | spring.datasource.druid.minIdle=5 53 | spring.datasource.druid.maxActive=20 54 | # 配置获取连接等待超时的时间 55 | spring.datasource.druid.maxWait=60000 56 | # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 57 | spring.datasource.druid.timeBetweenEvictionRunsMillis=60000 58 | # 配置一个连接在池中最小生存的时间,单位是毫秒 59 | spring.datasource.druid.minEvictableIdleTimeMillis=300000 60 | spring.datasource.druid.validationQuery=SELECT 1 FROM DUAL 61 | spring.datasource.druid.testWhileIdle=true 62 | spring.datasource.druid.testOnBorrow=false 63 | spring.datasource.druid.testOnReturn=false 64 | # 打开PSCache,并且指定每个连接上PSCache的大小 65 | spring.datasource.druid.poolPreparedStatements=true 66 | spring.datasource.druid.maxPoolPreparedStatementPerConnectionSize=20 67 | # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 68 | spring.datasource.druid.filters=stat,wall 69 | # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 70 | spring.datasource.druid.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000 71 | # 合并多个DruidDataSource的监控数据 72 | #spring.datasource.useGlobalDataSourceStat=true -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/resources/mapper/cluster/ClassMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | SELECT LAST_INSERT_ID() 8 | 9 | insert into class(className) values(#{className}) 10 | 11 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/resources/mapper/cluster1/TeacherMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | SELECT LAST_INSERT_ID() 8 | 9 | insert into teacher(name) values(#{name}) 10 | 11 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/main/resources/mapper/master/StudentMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | SELECT LAST_INSERT_ID() 8 | 9 | insert into student(name,email,age,birthday) values(#{name},#{email},#{age},#{birthday}) 10 | 11 | 12 | 17 | 21 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/test/java/com/BaseTest.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import org.junit.runner.RunWith; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 6 | 7 | /** 8 | * @author lengchuan 9 | * @date 17-4-5 10 | */ 11 | @RunWith(SpringJUnit4ClassRunner.class) 12 | @SpringBootTest(classes = App.class) 13 | public class BaseTest { 14 | } 15 | -------------------------------------------------------------------------------- /SpringBoot-Druid/src/test/java/com/lengchuan/springBoot/druid/service/ClassServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.service; 2 | 3 | import com.BaseTest; 4 | import com.lengchuan.springBoot.druid.model.Class; 5 | import org.junit.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | 8 | /** 9 | * @author lengchuan 10 | * @date 17-4-4 11 | */ 12 | public class ClassServiceTest extends BaseTest{ 13 | 14 | @Autowired 15 | private ClassService classService; 16 | 17 | @Test 18 | public void createClass() throws Exception { 19 | Class c = new Class(); 20 | c.setClassName("test"); 21 | classService.createClass(c); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /SpringBoot-Druid/src/test/java/com/lengchuan/springBoot/druid/service/StudentServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.service; 2 | 3 | import com.BaseTest; 4 | import com.lengchuan.springBoot.druid.model.Student; 5 | import org.junit.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | 8 | import java.util.Date; 9 | 10 | /** 11 | * @author lengchuan 12 | * @date 17-4-4 13 | */ 14 | public class StudentServiceTest extends BaseTest{ 15 | 16 | 17 | @Autowired 18 | private StudentService studentService; 19 | 20 | @Test 21 | public void createUser() throws Exception { 22 | Student student = new Student(); 23 | student.setName("test1"); 24 | student.setAge(1); 25 | student.setBirthday(new Date()); 26 | student.setEmail("test@test.com"); 27 | studentService.createUser(student); 28 | } 29 | 30 | @Test 31 | public void getByPage() throws Exception { 32 | studentService.getByPage(1, 2); 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /SpringBoot-Druid/src/test/java/com/lengchuan/springBoot/druid/service/TeacherServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.service; 2 | 3 | import com.BaseTest; 4 | import com.lengchuan.springBoot.druid.model.Teacher; 5 | import org.junit.Test; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | 8 | /** 9 | * @author lengchuan 10 | * @date 17-4-5 11 | */ 12 | public class TeacherServiceTest extends BaseTest{ 13 | 14 | @Autowired 15 | private TeacherService teacherService; 16 | 17 | @Test 18 | public void createTeacher() throws Exception { 19 | Teacher teacher = new Teacher(); 20 | teacher.setName("test"); 21 | teacherService.createTeacher(teacher); 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /SpringBoot-Dubbo/README.md: -------------------------------------------------------------------------------- 1 | # SpringBoot学习--集成dubbo 2 | 3 | ## 引入pom依赖 4 | 5 | + 1.spring-boot-starter-parent可以提供依赖管理,引入以后其它的的starter依赖就可以不用配置版本号. 6 | ``` 7 | 8 | com.alibaba.spring.boot 9 | dubbo-spring-boot-starter 10 | 2.0.0 11 | 12 | ``` 13 | 但是这里也有一个问题,如果我们已经有一个自己的parent,那么我们就不能在这么引用了.我们可以使用下面的方式: 14 | ```$xslt 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-dependencies 21 | ${springboot.version} 22 | pom 23 | import 24 | 25 | 26 | 27 | ``` 28 | + 2.spring-boot-starter-web提供了webmvc,tomcat等web开发相关模块 29 | ```$xslt 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | 37 | ``` 38 | 39 | ## 开始HelloWorld 40 | 41 | ### 一个错误的示例 42 | 我们需要一个main作为入口来启动我们的项目,但这里我们需要注意我们启动的主类不能放在default包下, 43 | 不然会遇到很多莫名的问题,比如下面这个: 44 | ```$xslt 45 | 2017-03-26 20:06:27.320 WARN 8832 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [HelloWorldAppTest1]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'errorPageFilter' for bean class [org.springframework.boot.web.support.ErrorPageFilter] conflicts with existing, non-compatible bean definition of same name and class [org.springframework.boot.context.web.ErrorPageFilter] 46 | 2017-03-26 20:06:27.330 ERROR 8832 --- [ main] o.s.boot.SpringApplication : Application startup failed 47 | 48 | org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [HelloWorldAppTest1]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'errorPageFilter' for bean class [org.springframework.boot.web.support.ErrorPageFilter] conflicts with existing, non-compatible bean definition of same name and class [org.springframework.boot.context.web.ErrorPageFilter] 49 | ``` 50 | ### 编写我们的第一个HelloWorld 51 | ```$xslt 52 | @SpringBootApplication 53 | @RestController 54 | public class HelloWorldApp2 { 55 | 56 | @RequestMapping("/hello") 57 | public String hello() { 58 | return "hello world"; 59 | } 60 | 61 | @RequestMapping("/") 62 | public String index() { 63 | return "this is index page"; 64 | } 65 | 66 | /** 67 | * 用于启动项目 68 | * 69 | * @param args 70 | */ 71 | public static void main(String[] args) { 72 | SpringApplication.run(HelloWorldApp2.class, args); 73 | } 74 | 75 | } 76 | ``` 77 | ### 启动项目 78 | 我们只需要启动main方法就可以在浏览器访问localhost:8080/hello,当然我们也可以使用maven命令来启动,我们需要添加下面的插件 79 | ```$xslt 80 | 81 | 82 | 83 | org.springframework.boot 84 | spring-boot-maven-plugin 85 | 86 | 87 | 88 | repackage 89 | 90 | 91 | 92 | 93 | 94 | 95 | ``` 96 | 然后使用mvn spring-boot:run就可以启动项目了,除此之外,我们也可以使用jar包的方式来启动, 97 | ```aidl 98 | java -jar target/SpringBoot-HelloWorld-2-1.0-SNAPSHOT.jar 99 | ``` 100 | 101 | ## 相关注解 102 | + 1.@SpringBootApplication可以自动进行一些必要的默认配置,等价于@Configuration,@EnableAutoConfiguration和@ComponentScan 103 | 这三个注解. 104 | + 2.RestController我们可以直接返回json,当然,从名字我们也知道可以直接用来编写RESTTUL风格的接口,要注意的是这个注解相当于一个@ResponseBody 105 | 注解,我们只能返回json,不能返回View了. 106 | 107 | -------------------------------------------------------------------------------- /SpringBoot-Dubbo/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SpringBoot-Study 7 | com.lengchuan 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | jar 12 | 13 | SpringBoot-Dubbo 14 | 15 | 16 | 17 | 18 | 19 | com.alibaba.boot 20 | dubbo-spring-boot-starter 21 | 0.1.0 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-maven-plugin 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /SpringBoot-Dubbo/src/main/java/com/lengchuan/App.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.web.bind.annotation.GetMapping; 6 | import org.springframework.web.bind.annotation.RestController; 7 | 8 | /** 9 | * @author lengchuan 10 | * @date 2018/7/24 11 | * @desc 启动类 12 | */ 13 | @SpringBootApplication 14 | @RestController 15 | public class App { 16 | 17 | public static void main(String[] args) { 18 | SpringApplication.run(App.class, args); 19 | } 20 | 21 | @GetMapping("/test") 22 | public String test() { 23 | return "hello world"; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SpringBoot-FastJson/README.md: -------------------------------------------------------------------------------- 1 | # SpingBoot使用fastJson 2 | 3 | ## 引入依赖 4 | ```aidl 5 | 6 | 7 | com.alibaba 8 | fastjson 9 | 1.2.29 10 | 11 | 12 | ``` 13 | ## FastJsonHttpMessageConverter 14 | fastJson主要通过FastJsonHttpMessageConverter和FastJsonHttpMessageConverter4来处理我们的HttpMessageconvert, 15 | 这两个类都是对HttpMessageConverter的实现.其中前者支持Spring4.2以前的,后者支持Spring4.2之后的版本. 16 | 17 | ## 使用fastJson 18 | + 1.首先我们继承FastJsonHttpMessageConverter4,进行一些自己需要的设置,可以通过FastJsonConfig这个类来设置相关属性 19 | ```aidl 20 | public class FastJsonConverter extends FastJsonHttpMessageConverter4 { 21 | } 22 | ``` 23 | + 2.我们在我们的启动类里面用@Bean注入HttpMessageConverters,这样我们就可以使用fastJson了 24 | ```aidl 25 | @SpringBootApplication 26 | public class App { 27 | 28 | @Bean 29 | HttpMessageConverters fastJsonHttpMessageConverters() { 30 | return new HttpMessageConverters(new FastJsonConverter()); 31 | } 32 | 33 | public static void main(String[] args) { 34 | SpringApplication.run(App.class, args); 35 | } 36 | } 37 | ``` 38 | 39 | ## HttpMessageConverter 40 | HttpMessageConverter这个类定义了消息转换的几个方法,里面最重要的两个方法就是read()和write()方法.这是我们 41 | 最终需要调用的两个方法,我们再看Spring已经实现的几个类. 42 | + 1.AbstractHttpMessageConverter,这个类虽然实现read()和write方法了,但又使用了两个抽象方法readInternal()和 43 | writeInternal(),这是留给我们去具体的实现细节. 44 | + 2.GenericHttpMessageConverter这也是一个接口. 45 | 46 | + 3.AbstractGenericHttpMessageConverter继承了AbstractHttpMessageConverter并且实现了GenericHttpMessageConverter, 47 | 这个类其实也什么也没干,然后又又一个自己的writeInternal()方法需要我们具体去实现. 48 | + 4.AbstractGenericHttpMessageConverter4,它继承自AbstractGenericHttpMessageConverter,实现writeInternal()方法,这个就是具体对read()的实现了, 49 | 然后实现了readInternal()方法,这个方法来自AbstractHttpMessageConverter. 50 | 51 | ## read()和write()方法 52 | 这是HttpMessageconvert最核心的两个方法 53 | + 1.read()方法用来处理我们接受到的请求信息,比如对参数进行解密,参数验签等,当然这些功能我们也可以用SpringMVC的 54 | 拦截器来实现,在以后会做介绍. 55 | + 2.write()用来处理我们返回的请求信息,比如对参数加密,参数加签名等. 56 | -------------------------------------------------------------------------------- /SpringBoot-FastJson/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SpringBoot-Study 7 | com.lengchuan 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.lengchuan 13 | SpringBoot-FastJson 14 | jar 15 | 16 | 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-dependencies 22 | ${springboot.version} 23 | pom 24 | import 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-web 33 | 34 | 35 | 36 | 37 | com.alibaba 38 | fastjson 39 | 1.2.29 40 | 41 | 42 | 43 | 44 | commons-io 45 | commons-io 46 | 2.5 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | org.springframework.boot 56 | spring-boot-maven-plugin 57 | 58 | 59 | 60 | repackage 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /SpringBoot-FastJson/src/main/java/com/App.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import com.lengchuan.springBoot.converter.EncrypConverter; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.autoconfigure.web.HttpMessageConverters; 7 | import org.springframework.context.annotation.Bean; 8 | 9 | /** 10 | * @author lengchuan 11 | * @date 17-3-28 12 | */ 13 | @SpringBootApplication 14 | public class App { 15 | 16 | // @Bean 17 | // HttpMessageConverters setFastJsonConverter() { 18 | // return new HttpMessageConverters(new FastJsonConverter()); 19 | // } 20 | 21 | @Bean 22 | HttpMessageConverters fastJsonHttpMessageConverters() { 23 | return new HttpMessageConverters(new EncrypConverter()); 24 | } 25 | 26 | public static void main(String[] args) { 27 | SpringApplication.run(App.class, args); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /SpringBoot-FastJson/src/main/java/com/lengchuan/springBoot/controller/UserController.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.controller; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.lengchuan.springBoot.druid.model.User; 5 | import org.springframework.web.bind.annotation.RequestBody; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | /** 10 | * @author lengchuan 11 | * @date 17-3-28 12 | */ 13 | @RestController 14 | @RequestMapping("user") 15 | public class UserController { 16 | 17 | @RequestMapping("/getUser") 18 | public User getUser() { 19 | User user = new User(); 20 | user.setName("test"); 21 | user.setEmail("test@123.com"); 22 | user.setAge(25); 23 | return user; 24 | } 25 | 26 | @RequestMapping("/createUser") 27 | public String getcreateUserUser(@RequestBody User user) { 28 | System.out.println(JSON.toJSON(user)); 29 | return "保存成功"; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /SpringBoot-FastJson/src/main/java/com/lengchuan/springBoot/converter/EncrypConverter.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.converter; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4; 5 | import com.lengchuan.springBoot.util.Base64; 6 | import com.lengchuan.springBoot.util.HttpBody; 7 | import org.apache.commons.io.IOUtils; 8 | import org.springframework.http.HttpInputMessage; 9 | import org.springframework.http.HttpOutputMessage; 10 | import org.springframework.http.converter.HttpMessageNotReadableException; 11 | import org.springframework.http.converter.HttpMessageNotWritableException; 12 | 13 | import java.io.IOException; 14 | import java.io.InputStream; 15 | import java.lang.reflect.Type; 16 | 17 | /** 18 | * 实现参数加密解密 19 | * 我们参照FastJsonHttpMessageConverter4的实现,进行改造 20 | * 21 | * @author lengchuan 22 | * @date 17-3-29 23 | */ 24 | public class EncrypConverter extends FastJsonHttpMessageConverter4 { 25 | 26 | /** 27 | * 重写read()方法 28 | * 29 | * @param type 30 | * @param contextClass 31 | * @param inputMessage 32 | * @return 33 | * @throws IOException 34 | * @throws HttpMessageNotReadableException 35 | */ 36 | @Override 37 | public Object read(Type type, Class contextClass, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { 38 | InputStream in = inputMessage.getBody(); 39 | byte[] data = Base64.decode(IOUtils.toString(in, "UTF-8")); 40 | return JSON.parseObject(data, 0, data.length, getFastJsonConfig().getCharset(), type, getFastJsonConfig().getFeatures()); 41 | } 42 | 43 | /** 44 | * 重写readInternal 45 | * 46 | * @param clazz 47 | * @param inputMessage 48 | * @return 49 | * @throws IOException 50 | * @throws HttpMessageNotReadableException 51 | */ 52 | @Override 53 | protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { 54 | 55 | InputStream in = inputMessage.getBody(); 56 | byte[] data = Base64.decode(IOUtils.toString(in, "UTF-8")); 57 | return JSON.parseObject(data, 0, data.length, getFastJsonConfig().getCharset(), clazz, getFastJsonConfig().getFeatures()); 58 | } 59 | 60 | 61 | /** 62 | * 重写writeInternal()方法 63 | * 64 | * @param obj 65 | * @param type 66 | * @param outputMessage 67 | * @throws IOException 68 | * @throws HttpMessageNotWritableException 69 | */ 70 | @Override 71 | protected void writeInternal(Object obj, Type type, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { 72 | String s = Base64.encode(JSON.toJSONBytes(obj)); 73 | HttpBody httpBody = new HttpBody(); 74 | httpBody.setStatus(1); 75 | httpBody.setBody(s); 76 | super.writeInternal(httpBody, type, outputMessage); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /SpringBoot-FastJson/src/main/java/com/lengchuan/springBoot/converter/FastJsonConverter.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.converter; 2 | 3 | import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter4; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-4-3 8 | */ 9 | public class FastJsonConverter extends FastJsonHttpMessageConverter4 { 10 | } 11 | -------------------------------------------------------------------------------- /SpringBoot-FastJson/src/main/java/com/lengchuan/springBoot/druid/model/User.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | /** 8 | * @author lengchuan 9 | * @date 17-3-28 10 | */ 11 | public class User implements Serializable{ 12 | // @JSONField(serialize = false) 13 | private String name; 14 | private int age; 15 | private String email; 16 | private List friends; 17 | 18 | public User(String name, int age, String email) { 19 | this.name = name; 20 | this.age = age; 21 | this.email = email; 22 | } 23 | 24 | public User() { 25 | friends = new ArrayList(); 26 | friends.add(new User("lengchuan1", 25, "123@123.test")); 27 | friends.add(new User("lengchuan2", 25, "1234@123.test")); 28 | friends.add(new User("lengchuan3", 25, "12345@123.test")); 29 | } 30 | 31 | public String getName() { 32 | return name; 33 | } 34 | 35 | public void setName(String name) { 36 | this.name = name; 37 | } 38 | 39 | public int getAge() { 40 | return age; 41 | } 42 | 43 | public void setAge(int age) { 44 | this.age = age; 45 | } 46 | 47 | public String getEmail() { 48 | return email; 49 | } 50 | 51 | public void setEmail(String email) { 52 | this.email = email; 53 | } 54 | 55 | public List getFriends() { 56 | return friends; 57 | } 58 | 59 | public void setFriends(List friends) { 60 | this.friends = friends; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /SpringBoot-FastJson/src/main/java/com/lengchuan/springBoot/util/Base64.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.util; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.OutputStream; 6 | 7 | public class Base64 { 8 | private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" 9 | .toCharArray(); 10 | 11 | /** 12 | * 加密 13 | * 14 | * @param data 15 | * @return 16 | */ 17 | public static String encode(byte[] data) { 18 | int start = 0; 19 | int len = data.length; 20 | StringBuffer buf = new StringBuffer(data.length * 3 / 2); 21 | 22 | int end = len - 3; 23 | int i = start; 24 | int n = 0; 25 | 26 | while (i <= end) { 27 | int d = ((((int) data[i]) & 0x0ff) << 16) 28 | | ((((int) data[i + 1]) & 0x0ff) << 8) 29 | | (((int) data[i + 2]) & 0x0ff); 30 | 31 | buf.append(legalChars[(d >> 18) & 63]); 32 | buf.append(legalChars[(d >> 12) & 63]); 33 | buf.append(legalChars[(d >> 6) & 63]); 34 | buf.append(legalChars[d & 63]); 35 | 36 | i += 3; 37 | 38 | if (n++ >= 14) { 39 | n = 0; 40 | buf.append(" "); 41 | } 42 | } 43 | 44 | if (i == start + len - 2) { 45 | int d = ((((int) data[i]) & 0x0ff) << 16) 46 | | ((((int) data[i + 1]) & 255) << 8); 47 | 48 | buf.append(legalChars[(d >> 18) & 63]); 49 | buf.append(legalChars[(d >> 12) & 63]); 50 | buf.append(legalChars[(d >> 6) & 63]); 51 | buf.append("="); 52 | } else if (i == start + len - 1) { 53 | int d = (((int) data[i]) & 0x0ff) << 16; 54 | 55 | buf.append(legalChars[(d >> 18) & 63]); 56 | buf.append(legalChars[(d >> 12) & 63]); 57 | buf.append("=="); 58 | } 59 | 60 | return buf.toString(); 61 | } 62 | 63 | /** 64 | * 解密 65 | * 66 | * @param s 67 | * @return 68 | */ 69 | public static byte[] decode(String s) { 70 | 71 | ByteArrayOutputStream bos = new ByteArrayOutputStream(); 72 | try { 73 | decode(s, bos); 74 | } catch (IOException e) { 75 | throw new RuntimeException(); 76 | } 77 | byte[] decodedBytes = bos.toByteArray(); 78 | try { 79 | bos.close(); 80 | bos = null; 81 | } catch (IOException ex) { 82 | System.err.println("Error while decoding BASE64: " + ex.toString()); 83 | } 84 | return decodedBytes; 85 | } 86 | 87 | private static void decode(String s, OutputStream os) throws IOException { 88 | int i = 0; 89 | 90 | int len = s == null ? 0 : s.length(); 91 | 92 | while (true) { 93 | while (i < len && s.charAt(i) <= ' ') 94 | i++; 95 | 96 | if (i == len) 97 | break; 98 | 99 | int tri = (decode(s.charAt(i)) << 18) 100 | + (decode(s.charAt(i + 1)) << 12) 101 | + (decode(s.charAt(i + 2)) << 6) 102 | + (decode(s.charAt(i + 3))); 103 | 104 | os.write((tri >> 16) & 255); 105 | if (s.charAt(i + 2) == '=') 106 | break; 107 | os.write((tri >> 8) & 255); 108 | if (s.charAt(i + 3) == '=') 109 | break; 110 | os.write(tri & 255); 111 | 112 | i += 4; 113 | } 114 | } 115 | 116 | private static int decode(char c) { 117 | if (c >= 'A' && c <= 'Z') 118 | return ((int) c) - 65; 119 | else if (c >= 'a' && c <= 'z') 120 | return ((int) c) - 97 + 26; 121 | else if (c >= '0' && c <= '9') 122 | return ((int) c) - 48 + 26 + 26; 123 | else 124 | switch (c) { 125 | case '+': 126 | return 62; 127 | case '/': 128 | return 63; 129 | case '=': 130 | return 0; 131 | default: 132 | throw new RuntimeException("unexpected code: " + c); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /SpringBoot-FastJson/src/main/java/com/lengchuan/springBoot/util/HttpBody.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.util; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-4-3 8 | */ 9 | public class HttpBody implements Serializable { 10 | private int status; 11 | private String body; 12 | 13 | public int getStatus() { 14 | return status; 15 | } 16 | 17 | public void setStatus(int status) { 18 | this.status = status; 19 | } 20 | 21 | public String getBody() { 22 | return body; 23 | } 24 | 25 | public void setBody(String body) { 26 | this.body = body; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /SpringBoot-GlobalExceptionHandler/README.md: -------------------------------------------------------------------------------- 1 | # SpingBoot全局异常处理 2 | 3 | ## @controllerAdvice()注解 4 | + 1.@ControllerAdvice()注解可以定义一个统一的异常处理类,我们可以定义多个统一异常处理类, 5 | 但这里我们需要注意一点,默认的@ControllerAdvice()会处理所有的controller层抛出的异常, 6 | 如果我们需要对不同的包进行不同的异常处理,比如pc端我们要返回一个jsp页面,app端我们需要返回 7 | 一个json,这时候我们可以通过配置如:@ControllerAdvice("com.lengchuan.xxx")或者 8 | @ControllerAdvice(basePackages="com.lengchuan1.xxx,com.lengchuan2.xxx")来对不同包的异常进行处理. 9 | 10 | ## @ExceptionHandler()注解 11 | + 1.@ExceptionHandler()注解用在方法上,用来处理具体的某一中或某一类异常,比如@ExceptionHandler(Exception.class) 12 | 将会处理所有的异常,如果魔门有一个自定的异常MyException继承自Exception,同时配置了@ExceptionHandler(Exception.class) 13 | 和@ExceptionHandler(MyException.class),则会根据抛出的具体异常来判断选用哪个处理器,比如,我们抛出了MyException,则会优先使用 14 | MyException的异常处理器. 15 | 16 | ## 异常处理器的覆盖 17 | 如果我们配置了多个@controllerAdvice(),如果有一个没有指定具体的包名,那么他会覆盖其它所有指定了包名的异常处理类,导致其它失效. 18 | -------------------------------------------------------------------------------- /SpringBoot-GlobalExceptionHandler/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SpringBoot-Study 7 | com.lengchuan 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.lengchuan 13 | SpringBoot-GlobalExceptionHandler 14 | jar 15 | 16 | 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-dependencies 22 | ${springboot.version} 23 | pom 24 | import 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-web 33 | 34 | 35 | 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-maven-plugin 41 | 42 | 43 | 44 | repackage 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /SpringBoot-GlobalExceptionHandler/src/main/java/com/App.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author lengchuan 8 | * @date 17-3-27 9 | */ 10 | @SpringBootApplication 11 | public class App { 12 | public static void main(String[] args) { 13 | SpringApplication.run(App.class, args); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SpringBoot-GlobalExceptionHandler/src/main/java/com/lengchuan/springBoot/Exception/MyException1.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.Exception; 2 | 3 | /** 4 | * @author lengchuan 5 | * @date 17-3-27 6 | */ 7 | public class MyException1 extends Exception { 8 | public MyException1() { 9 | super(); 10 | } 11 | 12 | public MyException1(String msg) { 13 | super(msg); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SpringBoot-GlobalExceptionHandler/src/main/java/com/lengchuan/springBoot/Exception/MyException2.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.Exception; 2 | 3 | /** 4 | * @author lengchuan 5 | * @date 17-3-27 6 | */ 7 | public class MyException2 extends Exception { 8 | public MyException2() { 9 | super(); 10 | } 11 | 12 | public MyException2(String msg) { 13 | super(msg); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /SpringBoot-GlobalExceptionHandler/src/main/java/com/lengchuan/springBoot/controller/DemoController.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.controller; 2 | 3 | import com.lengchuan.springBoot.Exception.MyException1; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | /** 8 | * @author lengchuan 9 | * @date 17-3-27 10 | */ 11 | @RestController 12 | @RequestMapping("/demo") 13 | public class DemoController { 14 | 15 | @RequestMapping("/default") 16 | public String defaultException() { 17 | throw new NullPointerException(); 18 | } 19 | 20 | @RequestMapping("/my") 21 | public String MyException() throws MyException1 { 22 | throw new MyException1(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SpringBoot-GlobalExceptionHandler/src/main/java/com/lengchuan/springBoot/controller2/DemoController2.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.controller2; 2 | 3 | import com.lengchuan.springBoot.Exception.MyException1; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | /** 8 | * @author lengchuan 9 | * @date 17-3-27 10 | */ 11 | @RestController 12 | @RequestMapping("/demo2") 13 | public class DemoController2 { 14 | 15 | @RequestMapping("/default") 16 | public String defaultException() { 17 | throw new NullPointerException(); 18 | } 19 | 20 | @RequestMapping("/my") 21 | public String MyException() throws MyException1 { 22 | throw new MyException1(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /SpringBoot-GlobalExceptionHandler/src/main/java/com/lengchuan/springBoot/exceptionHandler/ExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.exceptionHandler; 2 | 3 | import org.springframework.web.bind.annotation.ControllerAdvice; 4 | 5 | import javax.servlet.http.HttpServletResponse; 6 | import java.io.IOException; 7 | 8 | /** 9 | * @author lengchuan 10 | * @date 17-3-27 11 | */ 12 | @ControllerAdvice() 13 | public class ExceptionHandler { 14 | 15 | /** 16 | * 全局异常处理 17 | * 18 | * @param response 19 | * @param e 20 | */ 21 | @org.springframework.web.bind.annotation.ExceptionHandler(value = Exception.class) 22 | public void ExceptionHandler(HttpServletResponse response, Exception e) { 23 | System.out.println("-------全局默认异常处理-----"); 24 | try { 25 | response.getOutputStream().write("全局默认异常处理".getBytes()); 26 | } catch (IOException e1) { 27 | e1.printStackTrace(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SpringBoot-GlobalExceptionHandler/src/main/java/com/lengchuan/springBoot/exceptionHandler/ExceptionHandler1.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.exceptionHandler; 2 | 3 | import com.lengchuan.springBoot.Exception.MyException1; 4 | import org.springframework.web.bind.annotation.ControllerAdvice; 5 | 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.io.IOException; 8 | 9 | /** 10 | * @author lengchuan 11 | * @date 17-3-27 12 | */ 13 | @ControllerAdvice("com.lengchuan.springBoot.controller") 14 | public class ExceptionHandler1 { 15 | 16 | /** 17 | * 全局异常处理 18 | * 19 | * @param response 20 | * @param e 21 | */ 22 | @org.springframework.web.bind.annotation.ExceptionHandler(value = Exception.class) 23 | public void ExceptionHandler(HttpServletResponse response, Exception e) { 24 | System.out.println("-------全局默认异常处理1-----"); 25 | try { 26 | response.getOutputStream().write("全局默认异常处理1".getBytes()); 27 | } catch (IOException e1) { 28 | e1.printStackTrace(); 29 | } 30 | } 31 | 32 | /** 33 | * 自定义异常处理 34 | * 35 | * @param response 36 | * @param e 37 | */ 38 | @org.springframework.web.bind.annotation.ExceptionHandler(value = MyException1.class) 39 | public void MyExceptionHandler(HttpServletResponse response, MyException1 e) { 40 | System.out.println("-------自定义异常处理1-----"); 41 | try { 42 | response.getOutputStream().write("自定义异常处理1".getBytes()); 43 | } catch (IOException e1) { 44 | e1.printStackTrace(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /SpringBoot-GlobalExceptionHandler/src/main/java/com/lengchuan/springBoot/exceptionHandler/ExceptionHandler2.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.exceptionHandler; 2 | 3 | import org.springframework.web.bind.annotation.ControllerAdvice; 4 | 5 | import javax.servlet.http.HttpServletResponse; 6 | import java.io.IOException; 7 | 8 | /** 9 | * @author lengchuan 10 | * @date 17-3-27 11 | */ 12 | @ControllerAdvice("com.lengchuan.springBoot.controller2") 13 | public class ExceptionHandler2 { 14 | 15 | /** 16 | * 自定义异常处理 17 | * 18 | * @param response 19 | * @param e 20 | */ 21 | @org.springframework.web.bind.annotation.ExceptionHandler(Exception.class) 22 | public void ExceptionHandler(HttpServletResponse response, Exception e) { 23 | System.out.println("-------全局异常处理2-----"); 24 | try { 25 | response.getOutputStream().write("全局异常处理2".getBytes()); 26 | } catch (IOException e1) { 27 | e1.printStackTrace(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SpringBoot-HelloWorld-1/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SpringBoot-Study 7 | org.lengchuan 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | jar 12 | 13 | SpringBoot-HelloWorld-1 14 | 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-dependencies 20 | ${springboot.version} 21 | pom 22 | import 23 | 24 | 25 | 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-maven-plugin 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /SpringBoot-HelloWorld-1/src/main/java/HelloWorldAppTest1.java: -------------------------------------------------------------------------------- 1 | import org.springframework.boot.SpringApplication; 2 | import org.springframework.boot.autoconfigure.SpringBootApplication; 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | * 这是一个错误的使用方法,项目是无法启动的,启动类不能直接放在默认的包路径下 8 | * 9 | * @author lengchuan 10 | * @date 17-3-26 11 | */ 12 | @SpringBootApplication 13 | @RestController 14 | public class HelloWorldAppTest1 { 15 | 16 | @RequestMapping("/hello") 17 | public String hello() { 18 | return "hello world"; 19 | } 20 | 21 | @RequestMapping("/") 22 | public String index() { 23 | return "this is index page"; 24 | } 25 | 26 | /** 27 | * 用于启动项目 28 | * 29 | * @param args 30 | */ 31 | public static void main(String[] args) { 32 | SpringApplication.run(HelloWorldAppTest1.class, args); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /SpringBoot-HelloWorld-2/README.md: -------------------------------------------------------------------------------- 1 | # SpringBoot学习--HellWorld 2 | 3 | ## 引入pom依赖 4 | 5 | + 1.spring-boot-starter-parent可以提供依赖管理,引入以后其它的的starter依赖就可以不用配置版本号. 6 | ```$xslt 7 | 8 | org.springframework.boot 9 | spring-boot-starter-parent 10 | 2.2.6.RELEASE 11 | 12 | ``` 13 | 但是这里也有一个问题,如果我们已经有一个自己的parent,那么我们就不能在这么引用了.我们可以使用下面的方式: 14 | ```$xslt 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-dependencies 21 | 2.2.6.RELEASE 22 | pom 23 | import 24 | 25 | 26 | 27 | ``` 28 | + 2.spring-boot-starter-web提供了webmvc,tomcat等web开发相关模块 29 | ```$xslt 30 | 31 | 32 | org.springframework.boot 33 | spring-boot-starter-web 34 | 35 | 36 | 37 | ``` 38 | 39 | ## 开始HelloWorld 40 | 41 | ### 一个错误的示例 42 | 我们需要一个main作为入口来启动我们的项目,但这里我们需要注意我们启动的主类不能放在default包下, 43 | 不然会遇到很多莫名的问题,比如下面这个: 44 | ```$xslt 45 | 2017-03-26 20:06:27.320 WARN 8832 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [HelloWorldAppTest1]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'errorPageFilter' for bean class [org.springframework.boot.web.support.ErrorPageFilter] conflicts with existing, non-compatible bean definition of same name and class [org.springframework.boot.context.web.ErrorPageFilter] 46 | 2017-03-26 20:06:27.330 ERROR 8832 --- [ main] o.s.boot.SpringApplication : Application startup failed 47 | 48 | org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [HelloWorldAppTest1]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'errorPageFilter' for bean class [org.springframework.boot.web.support.ErrorPageFilter] conflicts with existing, non-compatible bean definition of same name and class [org.springframework.boot.context.web.ErrorPageFilter] 49 | ``` 50 | ### 编写我们的第一个HelloWorld 51 | ```$xslt 52 | @SpringBootApplication 53 | @RestController 54 | public class HelloWorldApp2 { 55 | 56 | @RequestMapping("/hello") 57 | public String hello() { 58 | return "hello world"; 59 | } 60 | 61 | @RequestMapping("/") 62 | public String index() { 63 | return "this is index page"; 64 | } 65 | 66 | /** 67 | * 用于启动项目 68 | * 69 | * @param args 70 | */ 71 | public static void main(String[] args) { 72 | SpringApplication.run(HelloWorldApp2.class, args); 73 | } 74 | 75 | } 76 | ``` 77 | ### 启动项目 78 | 我们只需要启动main方法就可以在浏览器访问localhost:8080/hello,当然我们也可以使用maven命令来启动,我们需要添加下面的插件 79 | ```$xslt 80 | 81 | 82 | 83 | org.springframework.boot 84 | spring-boot-maven-plugin 85 | 86 | 87 | 88 | repackage 89 | 90 | 91 | 92 | 93 | 94 | 95 | ``` 96 | 然后使用mvn spring-boot:run就可以启动项目了,除此之外,我们也可以使用jar包的方式来启动, 97 | ```aidl 98 | java -jar target/SpringBoot-HelloWorld-2-1.0-SNAPSHOT.jar 99 | ``` 100 | 101 | ## 相关注解 102 | + 1.@SpringBootApplication可以自动进行一些必要的默认配置,等价于@Configuration,@EnableAutoConfiguration和@ComponentScan 103 | 这三个注解. 104 | + 2.RestController我们可以直接返回json,当然,从名字我们也知道可以直接用来编写`restfull`风格的接口,要注意的是这个注解相当于一个@ResponseBody 105 | 注解,我们只能返回json,不能返回View了. 106 | -------------------------------------------------------------------------------- /SpringBoot-HelloWorld-2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SpringBoot-Study 7 | com.lengchuan 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.lengchuan 13 | SpringBoot-HelloWorld-2 14 | jar 15 | 16 | 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-dependencies 22 | ${springboot.version} 23 | pom 24 | import 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-web 33 | 34 | 35 | 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-maven-plugin 41 | 42 | 43 | 44 | repackage 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /SpringBoot-HelloWorld-2/src/main/java/com/lengchuan/HelloWorldApp2.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan; 2 | 3 | 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 6 | import org.springframework.context.annotation.ComponentScan; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | /** 12 | * @author lengchuan 13 | * @date 17-3-26 14 | */ 15 | //@SpringBootApplication 16 | @Configuration 17 | @ComponentScan 18 | @EnableAutoConfiguration 19 | @RestController 20 | public class HelloWorldApp2 { 21 | 22 | @RequestMapping("/hello") 23 | public String hello() { 24 | return "hello world"; 25 | } 26 | 27 | @RequestMapping("/") 28 | public String index() { 29 | return "this is index page"; 30 | } 31 | 32 | /** 33 | * 用于启动项目 34 | * 35 | * @param args 36 | */ 37 | public static void main(String[] args) { 38 | SpringApplication.run(HelloWorldApp2.class, args); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /SpringBoot-HelloWorld-2/src/main/java/com/lengchuan/springBoot/DemoController.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | import org.springframework.web.bind.annotation.RestController; 5 | 6 | /** 7 | * 返回json 8 | * 9 | * @author lengchuan 10 | * @date 17-3-27 11 | */ 12 | @RestController 13 | @RequestMapping("/demo") 14 | public class DemoController { 15 | 16 | @RequestMapping("/getUser") 17 | public User getUser() { 18 | User user = new User(); 19 | user.setName("lengchuan"); 20 | user.setAge(25); 21 | user.setCity("Beijing"); 22 | 23 | return user; 24 | } 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /SpringBoot-HelloWorld-2/src/main/java/com/lengchuan/springBoot/User.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot; 2 | 3 | /** 4 | * @author lengchuan 5 | * @date 2020/4/14 6 | * @desc 7 | */ 8 | class User { 9 | private String name; 10 | private int age; 11 | private String city; 12 | 13 | public String getName() { 14 | return name; 15 | } 16 | 17 | public void setName(String name) { 18 | this.name = name; 19 | } 20 | 21 | public int getAge() { 22 | return age; 23 | } 24 | 25 | public void setAge(int age) { 26 | this.age = age; 27 | } 28 | 29 | public String getCity() { 30 | return city; 31 | } 32 | 33 | public void setCity(String city) { 34 | this.city = city; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /SpringBoot-JuintTest/README.md: -------------------------------------------------------------------------------- 1 | # SpringBoot使用Junit 2 | 3 | ## 引入依赖 4 | ```aidl 5 | 6 | org.springframework.boot 7 | spring-boot-starter-test 8 | test 9 | 10 | ``` 11 | ## 测试 12 | + 1.我们需要测试的类 13 | ```aidl 14 | @Service 15 | public class HelloWorldService { 16 | public void sayHello() { 17 | System.out.println("Hello world"); 18 | } 19 | } 20 | 21 | ``` 22 | + 2.测试 23 | ```aidl 24 | @RunWith(SpringJUnit4ClassRunner.class) 25 | @SpringBootTest(classes = App.class) 26 | public class HelloWorldServiceTest { 27 | 28 | @Autowired 29 | private HelloWorldService helloWorldService; 30 | 31 | @Test 32 | public void sayHello() throws Exception { 33 | helloWorldService.sayHello(); 34 | } 35 | 36 | } 37 | ``` 38 | ## 注解说明 39 | + 1.@RunWith(SpringJUnit4ClassRunner.class)用来引入SpringJunit支持. 40 | + 2.@SpringBootTest(classes = App.class)用来加载我们的启动类,也就是启动Spring容器,这是1.4之后的 41 | 注解,我们也可以用SpringApplicationConfiguration这个注解. 42 | + 3.@WebAppConfiguration,如果是web项目,我们再测试时需要加载ServletContext的话,就需要加上这个注解. -------------------------------------------------------------------------------- /SpringBoot-JuintTest/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SpringBoot-Study 7 | com.lengchuan 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.lengchuan 13 | SpringBoot-JuintTest 14 | jar 15 | 16 | 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-dependencies 22 | ${springboot.version} 23 | pom 24 | import 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-web 33 | 34 | 35 | 36 | org.springframework.boot 37 | spring-boot-starter-test 38 | test 39 | 40 | 41 | 42 | 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-maven-plugin 47 | 48 | 49 | 50 | repackage 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /SpringBoot-JuintTest/src/main/java/com/App.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author lengchuan 8 | * @date 17-4-3 9 | */ 10 | @SpringBootApplication 11 | public class App { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(App.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SpringBoot-JuintTest/src/main/java/com/lengchuan/springBoot/druid/service/HelloWorldService.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.service; 2 | 3 | import org.springframework.stereotype.Service; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-4-3 8 | */ 9 | @Service 10 | public class HelloWorldService { 11 | public void sayHello() { 12 | System.out.println("Hello world"); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /SpringBoot-JuintTest/src/test/java/com/lengchuan/springBoot/druid/service/HelloWorldServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.service; 2 | 3 | import com.App; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 9 | 10 | /** 11 | * @author lengchuan 12 | * @date 17-4-3 13 | */ 14 | @RunWith(SpringJUnit4ClassRunner.class) 15 | @SpringBootTest(classes = App.class) 16 | public class HelloWorldServiceTest { 17 | 18 | @Autowired 19 | private HelloWorldService helloWorldService; 20 | 21 | @Test 22 | public void sayHello() throws Exception { 23 | helloWorldService.sayHello(); 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /SpringBoot-Mybatis/README.md: -------------------------------------------------------------------------------- 1 | # SpringBoot整合Mybatis 2 | 3 | ## 引入依赖 4 | ```aidl 5 | 6 | 7 | org.mybatis.spring.boot 8 | mybatis-spring-boot-starter 9 | 1.2.0 10 | 11 | 12 | 13 | 14 | mysql 15 | mysql-connector-java 16 | 6.0.3 17 | 18 | ``` 19 | ## 配置数据源 20 | 在application.properties里配置mysql数据源 21 | ```aidl 22 | spring.datasource.url=jdbc:mysql://localhost:3306/SpringBootTest 23 | spring.datasource.username=root 24 | spring.datasource.password=1 25 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 26 | 27 | ``` 28 | ## 使用Mybatis 29 | + 1.创建实体对象 30 | ```aidl 31 | public class User implements Serializable { 32 | private Integer userId; 33 | 34 | private String name; 35 | 36 | private String email; 37 | 38 | private Integer age; 39 | 40 | private Date birthday; 41 | //getter/setter 42 | } 43 | ``` 44 | + 2.配置mybatis 45 | ```aidl 46 | @Configuration//声明这是用来配置的类,用来取代xml配置 47 | public class MybatisConfig { 48 | 49 | /** 50 | * 注入一个默认数据源 51 | */ 52 | @Autowired 53 | private DataSource dataSource; 54 | 55 | /** 56 | * SqlSessionFactory配置 57 | * 58 | * @return 59 | * @throws Exception 60 | */ 61 | @Bean 62 | public SqlSessionFactory sqlSessionFactoryBean() throws Exception { 63 | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 64 | sqlSessionFactoryBean.setDataSource(dataSource); 65 | 66 | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 67 | //配置mapper文件位置 68 | sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml")); 69 | return sqlSessionFactoryBean.getObject(); 70 | } 71 | 72 | /** 73 | * 配置事物管理器 74 | * 75 | * @return 76 | */ 77 | @Bean 78 | public DataSourceTransactionManager transactionManager() { 79 | DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); 80 | dataSourceTransactionManager.setDataSource(dataSource); 81 | return dataSourceTransactionManager; 82 | } 83 | } 84 | 85 | ``` 86 | ```aidl 87 | @SpringBootApplication 88 | @MapperScan(value = "com.lengchuan.springBoot.druid.mapper")//需要扫描的mapper接口所在包 89 | public class App { 90 | 91 | public static void main(String[] args) { 92 | SpringApplication.run(App.class, args); 93 | } 94 | } 95 | ``` 96 | 97 | ## 注解说明 98 | + 1.@MapperScan:配置需要扫描的mapper接口位置,除此之外,我们也可以用MapperScannerConfigurer来配置 99 | ```aidl 100 | @Configuration 101 | //MapperScannerConfigurer执行的比较早,所以必须有下面的注解 102 | @AutoConfigureAfter(MybatisConfig.class) 103 | public class MapperScannerConfig { 104 | 105 | @Bean 106 | public MapperScannerConfigurer mapperScannerConfigurer() { 107 | MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); 108 | mapperScannerConfigurer.setBasePackage("com.lengchuan.springBoot.druid.mapper"); 109 | return mapperScannerConfigurer; 110 | } 111 | } 112 | 113 | ``` 114 | 这里需要注意的是,如果我们使用@MapperScan的话,必须把它放在我们的启动类上,就是App这个类. 115 | + 2.@Configuration:表明这是一个配置类,用来代替xml配置 116 | 117 | ## 配置插件 118 | + 1.PageHelper分页插件配置,这里需要注意下Mybatis版本和PageHelper版本的兼容 119 | ```aidl 120 | 121 | 122 | com.github.pagehelper 123 | pagehelper 124 | 4.2.0 125 | 126 | 127 | 128 | ``` 129 | ```aidl 130 | @Bean 131 | public SqlSessionFactory sqlSessionFactoryBean() throws Exception { 132 | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 133 | sqlSessionFactoryBean.setDataSource(dataSource); 134 | 135 | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 136 | //配置mapper文件位置 137 | sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml")); 138 | 139 | //配置分页插件 140 | PageHelper pageHelper = new PageHelper(); 141 | Properties properties = new Properties(); 142 | properties.setProperty("reasonable", "true"); 143 | properties.setProperty("supportMethodsArguments", "true"); 144 | properties.setProperty("returnPageInfo", "check"); 145 | properties.setProperty("params", "count=countSql"); 146 | pageHelper.setProperties(properties); 147 | 148 | //设置插件 149 | sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper}); 150 | return sqlSessionFactoryBean.getObject(); 151 | } 152 | ``` -------------------------------------------------------------------------------- /SpringBoot-Mybatis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SpringBoot-Study 7 | com.lengchuan 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | jar 12 | 13 | com.lengchuan 14 | SpringBoot-Mybatis 15 | 16 | 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-dependencies 21 | ${springboot.version} 22 | pom 23 | import 24 | 25 | 26 | 27 | 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-web 32 | 33 | 34 | 35 | org.mybatis.spring.boot 36 | mybatis-spring-boot-starter 37 | 1.2.0 38 | 39 | 40 | 41 | 42 | mysql 43 | mysql-connector-java 44 | 6.0.3 45 | 46 | 47 | 48 | 49 | 50 | com.github.pagehelper 51 | pagehelper 52 | 4.2.0 53 | 54 | 55 | 56 | org.springframework.boot 57 | spring-boot-starter-test 58 | test 59 | 60 | 61 | 62 | 63 | 64 | 65 | org.springframework.boot 66 | spring-boot-maven-plugin 67 | 68 | 69 | 70 | repackage 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /SpringBoot-Mybatis/springboottest.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : 127.0.0.1 5 | Source Server Version : 50717 6 | Source Host : localhost:3306 7 | Source Database : springboottest 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50717 11 | File Encoding : 65001 12 | 13 | Date: 2017-04-05 21:36:10 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for user 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `user`; 22 | CREATE TABLE `user` ( 23 | `userId` int(11) NOT NULL AUTO_INCREMENT, 24 | `name` varchar(20) NOT NULL, 25 | `email` varchar(64) NOT NULL DEFAULT '', 26 | `age` int(11) NOT NULL, 27 | `birthday` timestamp NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 28 | PRIMARY KEY (`userId`) 29 | ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; 30 | 31 | -- ---------------------------- 32 | -- Records of user 33 | -- ---------------------------- 34 | INSERT INTO `user` VALUES ('3', 'test1', 'test@test.com', '1', '2017-04-04 02:54:18'); 35 | INSERT INTO `user` VALUES ('4', 'test1', 'test@test.com', '1', '2017-04-04 02:56:19'); 36 | INSERT INTO `user` VALUES ('8', 'test1', 'test@test.com', '1', '2017-04-04 03:59:13'); 37 | -------------------------------------------------------------------------------- /SpringBoot-Mybatis/src/main/java/com/App.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author lengchuan 8 | * @date 17-4-4 9 | */ 10 | @SpringBootApplication 11 | //@MapperScan(value = "com.lengchuan.springBoot.dataSource.mapper")//需要扫描的mapper接口所在包 12 | public class App { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(App.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SpringBoot-Mybatis/src/main/java/com/lengchuan/springBoot/druid/config/MapperScannerConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.config; 2 | 3 | import org.mybatis.spring.mapper.MapperScannerConfigurer; 4 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * 配置mybatis需要扫描的mapper接口 10 | * 11 | * @author lengchuan 12 | * @date 17-4-4 13 | */ 14 | @Configuration 15 | //MapperScannerConfigurer执行的比较早,所以必须有下面的注解 16 | @AutoConfigureAfter(MybatisConfig.class) 17 | public class MapperScannerConfig { 18 | 19 | @Bean 20 | public MapperScannerConfigurer mapperScannerConfigurer() { 21 | MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); 22 | mapperScannerConfigurer.setBasePackage("com.lengchuan.springBoot.dataSource.mapper"); 23 | return mapperScannerConfigurer; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /SpringBoot-Mybatis/src/main/java/com/lengchuan/springBoot/druid/config/MybatisConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.config; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import org.apache.ibatis.plugin.Interceptor; 5 | import org.apache.ibatis.session.SqlSessionFactory; 6 | import org.mybatis.spring.SqlSessionFactoryBean; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 11 | import org.springframework.jdbc.datasource.DataSourceTransactionManager; 12 | 13 | import javax.sql.DataSource; 14 | import java.util.Properties; 15 | 16 | /** 17 | * @author lengchuan 18 | * @date 17-4-4 19 | */ 20 | @Configuration//声明这是用来配置的类,用来取代xml配置 21 | public class MybatisConfig { 22 | 23 | /** 24 | * 注入一个默认数据源 25 | */ 26 | @Autowired 27 | private DataSource dataSource; 28 | 29 | /** 30 | * SqlSessionFactory配置 31 | * 32 | * @return 33 | * @throws Exception 34 | */ 35 | @Bean 36 | public SqlSessionFactory sqlSessionFactoryBean() throws Exception { 37 | SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); 38 | sqlSessionFactoryBean.setDataSource(dataSource); 39 | 40 | PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); 41 | //配置mapper文件位置 42 | sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml")); 43 | 44 | //配置分页插件 45 | PageHelper pageHelper = new PageHelper(); 46 | Properties properties = new Properties(); 47 | properties.setProperty("reasonable", "true"); 48 | properties.setProperty("supportMethodsArguments", "true"); 49 | properties.setProperty("returnPageInfo", "check"); 50 | properties.setProperty("params", "count=countSql"); 51 | pageHelper.setProperties(properties); 52 | 53 | //设置插件 54 | sqlSessionFactoryBean.setPlugins(new Interceptor[]{pageHelper}); 55 | return sqlSessionFactoryBean.getObject(); 56 | } 57 | 58 | /** 59 | * 配置事物管理器 60 | * 61 | * @return 62 | */ 63 | @Bean 64 | public DataSourceTransactionManager transactionManager() { 65 | DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(); 66 | dataSourceTransactionManager.setDataSource(dataSource); 67 | return dataSourceTransactionManager; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /SpringBoot-Mybatis/src/main/java/com/lengchuan/springBoot/druid/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.mapper; 2 | 3 | import com.lengchuan.springBoot.druid.model.User; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * @author lengchuan 9 | * @date 17-4-4 10 | */ 11 | public interface UserMapper { 12 | 13 | int insert(User user); 14 | 15 | // int update(User user); 16 | 17 | // int delete(User user); 18 | 19 | // User getById(int userId); 20 | 21 | List getBypage(); 22 | } 23 | -------------------------------------------------------------------------------- /SpringBoot-Mybatis/src/main/java/com/lengchuan/springBoot/druid/model/User.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.model; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * @author lengchuan 8 | * @date 17-4-4 9 | */ 10 | public class User implements Serializable { 11 | private Integer userId; 12 | 13 | private String name; 14 | 15 | private String email; 16 | 17 | private Integer age; 18 | 19 | private Date birthday; 20 | 21 | public Integer getUserId() { 22 | return userId; 23 | } 24 | 25 | public void setUserId(Integer userId) { 26 | this.userId = userId; 27 | } 28 | 29 | public String getName() { 30 | return name; 31 | } 32 | 33 | public void setName(String name) { 34 | this.name = name; 35 | } 36 | 37 | public String getEmail() { 38 | return email; 39 | } 40 | 41 | public void setEmail(String email) { 42 | this.email = email; 43 | } 44 | 45 | public Integer getAge() { 46 | return age; 47 | } 48 | 49 | public void setAge(Integer age) { 50 | this.age = age; 51 | } 52 | 53 | public Date getBirthday() { 54 | return birthday; 55 | } 56 | 57 | public void setBirthday(Date birthday) { 58 | this.birthday = birthday; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /SpringBoot-Mybatis/src/main/java/com/lengchuan/springBoot/druid/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.service; 2 | 3 | import com.github.pagehelper.Page; 4 | import com.github.pagehelper.PageHelper; 5 | import com.lengchuan.springBoot.druid.mapper.UserMapper; 6 | import com.lengchuan.springBoot.druid.model.User; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | import java.util.List; 12 | 13 | /** 14 | * @author lengchuan 15 | * @date 17-4-4 16 | */ 17 | @Service 18 | public class UserService { 19 | 20 | @Autowired 21 | private UserMapper userMapper; 22 | 23 | @Transactional 24 | public boolean createUser(User user) { 25 | userMapper.insert(user); 26 | 27 | //事务测试 28 | // int i = 1 / 0; 29 | return true; 30 | } 31 | 32 | public List getByPage(int page, int rows) { 33 | Page userPage = PageHelper.startPage(page, rows, true); 34 | List users = userMapper.getBypage(); 35 | System.out.println("-------------------" + userPage.toString() + "-----------"); 36 | return users; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SpringBoot-Mybatis/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.url=jdbc:mysql://localhost:3306/SpringBootTest 2 | spring.datasource.username=root 3 | spring.datasource.password=1 4 | spring.datasource.driver-class-name=com.mysql.jdbc.Driver 5 | -------------------------------------------------------------------------------- /SpringBoot-Mybatis/src/main/resources/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | SELECT LAST_INSERT_ID() 8 | 9 | insert into student(name,email,age,birthday) values(#{name},#{email},#{age},#{birthday}) 10 | 11 | 12 | 17 | 21 | -------------------------------------------------------------------------------- /SpringBoot-Mybatis/src/test/java/com/lengchuan/springBoot/druid/service/UserServiceTest.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.druid.service; 2 | 3 | import com.App; 4 | import com.lengchuan.springBoot.druid.model.User; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.boot.test.context.SpringBootTest; 9 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 10 | 11 | import java.util.Date; 12 | 13 | /** 14 | * @author lengchuan 15 | * @date 17-4-4 16 | */ 17 | @RunWith(SpringJUnit4ClassRunner.class) 18 | @SpringBootTest(classes = App.class) 19 | public class UserServiceTest { 20 | 21 | 22 | @Autowired 23 | private UserService userService; 24 | 25 | @Test 26 | public void createUser() throws Exception { 27 | User user = new User(); 28 | user.setName("test1"); 29 | user.setAge(1); 30 | user.setBirthday(new Date()); 31 | user.setEmail("test@test.com"); 32 | userService.createUser(user); 33 | } 34 | 35 | @Test 36 | public void getByPage() throws Exception { 37 | userService.getByPage(1, 2); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /SpringBoot-Redis/README.md: -------------------------------------------------------------------------------- 1 | # 1.SpringBoot 集成Spring Data Redis 2 | 3 | ## 2.Spring Data Redis简介 4 | 5 | Spring Data Redis作为Spring Data的一个模块,在Jedis的基础上对Redis的相关操作进行了更高层次的抽象和封装, 6 | 集成了Jedis的相关方法,使用起来更加方便.Spring Data Redis相对与Jedis最主要的区别在于: 7 | 8 | + 2.1使用RedisTemplate来封装相关操作,是我们不必考虑连接的创建/获取,关闭/回收这些细节,把关注点集中到业务上来. 9 | + 2.2抽象出RedisSerializer,可以自由选择或者自定义序列化方式. 10 | + 2.3对事务操作进行了封装. 11 | + 2.4将发布/订阅的相关方法进行封装,是开发起来更加方便 12 | 13 | 除此之外,Spring Data Redis还有很多优势,加上社区的不断努力,将会更加完善,如果你熟悉Redis或者Jedis,那么 14 | Spring Data Redis对你来说真的很容易掌握. 15 | 16 | ## 3.引入相关依赖 17 | 18 | ```aidl 19 | 20 | org.springframework.boot 21 | spring-boot-starter-redis 22 | 23 | 24 | 25 | redis.clients 26 | jedis 27 | 28 | 29 | 30 | com.alibaba 31 | fastjson 32 | 1.2.29 33 | 34 | ``` 35 | 36 | ## 4.RedisSerializer接口 37 | 38 | ```aidl 39 | public interface RedisSerializer { 40 | 41 | //序列化 42 | byte[] serialize(T t) throws SerializationException; 43 | 44 | //反序列化 45 | T deserialize(byte[] bytes) throws SerializationException; 46 | } 47 | ``` 48 | RedisSerializer只有两个接口需要我们去实现,默认的实现有StringRedisSerializer(默认), 49 | JdkSerializationRedisSerializer,JacksonJsonRedisSerializer,Jackson2JsonRedisSerializer,OxmSerializer. 50 | -------------------------------------------------------------------------------- /SpringBoot-Redis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SpringBoot-Study 7 | com.lengchuan 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.lengchuan 13 | SpringBoot-Redis 14 | jar 15 | 16 | 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-dependencies 22 | ${springboot.version} 23 | pom 24 | import 25 | 26 | 27 | 28 | 29 | 30 | 31 | org.springframework.boot 32 | spring-boot-starter-redis 33 | 34 | 35 | 36 | redis.clients 37 | jedis 38 | 39 | 40 | 41 | com.alibaba 42 | fastjson 43 | 1.2.29 44 | 45 | 46 | 47 | org.springframework.boot 48 | spring-boot-starter-test 49 | test 50 | 51 | 52 | 53 | com.fasterxml.jackson.core 54 | jackson-core 55 | 56 | 57 | 58 | com.fasterxml.jackson.core 59 | jackson-databind 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | org.springframework.boot 68 | spring-boot-maven-plugin 69 | 70 | 71 | 72 | repackage 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/main/java/com/App.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.SpringBootConfiguration; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | /** 8 | * @author lengchuan 9 | * @date 17-5-8 10 | */ 11 | @SpringBootApplication 12 | public class App { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(App.class, args); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/main/java/com/lengchuan/springBoot/redis/config/FastJsonRedisSerializer.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.redis.config; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import org.springframework.data.redis.serializer.RedisSerializer; 5 | import org.springframework.data.redis.serializer.SerializationException; 6 | 7 | import java.nio.charset.Charset; 8 | 9 | /** 10 | * 使用fastjson实现自己的序列化/反序列 11 | * 这里有限制,不能使用 12 | * 13 | * @author lengchuan 14 | * @date 17-4-19 15 | */ 16 | public class FastJsonRedisSerializer implements RedisSerializer { 17 | 18 | private static final Charset charset = Charset.forName("UTF-8"); 19 | 20 | private Class clazz; 21 | 22 | public FastJsonRedisSerializer(Class clazz) { 23 | this.clazz = clazz; 24 | } 25 | 26 | public FastJsonRedisSerializer() { 27 | } 28 | 29 | /** 30 | * 序列化 31 | * 32 | * @param t 33 | * @return 34 | * @throws SerializationException 35 | */ 36 | public byte[] serialize(T t) throws SerializationException { 37 | if (t == null) { 38 | return new byte[0]; 39 | } 40 | return JSON.toJSONString(t).getBytes(charset);//这里可以根据需要选择相应的方法 41 | } 42 | 43 | 44 | /** 45 | * 反序列化 46 | * 47 | * @param bytes 48 | * @return 49 | * @throws SerializationException 50 | */ 51 | public T deserialize(byte[] bytes) throws SerializationException { 52 | if (bytes == null || bytes.length <= 0) { 53 | return null; 54 | } 55 | String str = new String(bytes, charset); 56 | if (clazz == null) { 57 | return (T) JSON.parse(str); 58 | } 59 | return (T) JSON.parseObject(str, clazz); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/main/java/com/lengchuan/springBoot/redis/config/RedisTemplateConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.redis.config; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; 8 | import org.springframework.data.redis.core.RedisTemplate; 9 | import org.springframework.data.redis.core.StringRedisTemplate; 10 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 11 | import org.springframework.data.redis.serializer.RedisSerializer; 12 | 13 | /** 14 | * @author lengchuan 15 | * @date 17-4-19 16 | */ 17 | @Configuration 18 | public class RedisTemplateConfig { 19 | 20 | @Autowired 21 | private JedisConnectionFactory jedisConnectionFactory; 22 | 23 | /** 24 | * 注入Jackson2JsonRedisSerializer作为默认的序列化方式 25 | * 26 | * @param objectMapper 27 | * @return 28 | */ 29 | @Bean 30 | public RedisSerializer jackson2JsonRedisSerializer(ObjectMapper objectMapper) { 31 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 32 | jackson2JsonRedisSerializer.setObjectMapper(objectMapper); 33 | return new Jackson2JsonRedisSerializer(Object.class); 34 | } 35 | 36 | /** 37 | * 可以自己进行注入或者不注入 38 | * 39 | * @return 40 | */ 41 | @Bean 42 | public ObjectMapper objectMapper() { 43 | ObjectMapper objectMapper = new ObjectMapper(); 44 | return objectMapper; 45 | } 46 | 47 | /** 48 | * 自定义注入RedisTemplate 49 | * 50 | * @param redisSerializer 51 | * @return 52 | */ 53 | @Bean 54 | public RedisTemplate redisTemplate(RedisSerializer redisSerializer) { 55 | StringRedisTemplate redisTemplate = new StringRedisTemplate(jedisConnectionFactory); 56 | redisTemplate.setValueSerializer(redisSerializer); 57 | redisTemplate.afterPropertiesSet(); 58 | return redisTemplate; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/main/java/com/lengchuan/springBoot/redis/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.redis.dao; 2 | 3 | import com.lengchuan.springBoot.redis.model.User; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.data.redis.core.RedisTemplate; 6 | import org.springframework.data.redis.core.ValueOperations; 7 | import org.springframework.stereotype.Repository; 8 | 9 | /** 10 | * @author lengchuan 11 | * @date 17-5-8 12 | */ 13 | @Repository 14 | public class UserDao { 15 | 16 | private final static String USER_PREFIX = "User:"; 17 | 18 | @Autowired 19 | private RedisTemplate redisTemplate; 20 | 21 | public void insertUser(User user) { 22 | ValueOperations valueOperations = redisTemplate.opsForValue(); 23 | valueOperations.set(USER_PREFIX + user.getId(), user); 24 | } 25 | 26 | 27 | public User getUser(Integer id) { 28 | ValueOperations valueOperations = redisTemplate.opsForValue(); 29 | 30 | User user = (User) valueOperations.get(USER_PREFIX + id); 31 | return user; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/main/java/com/lengchuan/springBoot/redis/model/Entity.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.redis.model; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-5-8 8 | */ 9 | public class Entity implements Serializable { 10 | } 11 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/main/java/com/lengchuan/springBoot/redis/model/User.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.redis.model; 2 | 3 | /** 4 | * @author lengchuan 5 | * @date 17-5-8 6 | */ 7 | public class User extends Entity { 8 | 9 | private Integer id; 10 | private String name; 11 | private String email; 12 | 13 | public Integer getId() { 14 | return id; 15 | } 16 | 17 | public void setId(Integer id) { 18 | this.id = id; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | 29 | public String getEmail() { 30 | return email; 31 | } 32 | 33 | public void setEmail(String email) { 34 | this.email = email; 35 | } 36 | 37 | @Override 38 | public String toString() { 39 | return "User{" + 40 | "id=" + id + 41 | ", name='" + name + '\'' + 42 | ", email='" + email + '\'' + 43 | '}'; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/main/java/com/lengchuan/springBoot/redis/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.redis.service; 2 | 3 | import com.lengchuan.springBoot.redis.model.User; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-5-8 8 | */ 9 | public interface UserService { 10 | 11 | void createUser(User user); 12 | 13 | User getUser(Integer id); 14 | } 15 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/main/java/com/lengchuan/springBoot/redis/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.redis.service.impl; 2 | 3 | import com.lengchuan.springBoot.redis.dao.UserDao; 4 | import com.lengchuan.springBoot.redis.model.User; 5 | import com.lengchuan.springBoot.redis.service.UserService; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.stereotype.Service; 8 | 9 | /** 10 | * @author lengchuan 11 | * @date 17-5-8 12 | */ 13 | @Service 14 | public class UserServiceImpl implements UserService { 15 | 16 | @Autowired 17 | private UserDao userDao; 18 | 19 | 20 | @Override 21 | public void createUser(User user) { 22 | userDao.insertUser(user); 23 | } 24 | 25 | @Override 26 | public User getUser(Integer id) { 27 | User user = userDao.getUser(id); 28 | return user; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #配置模板 2 | #https://docs.spring.io/spring-boot/docs/${springboot.version}/reference/html/common-application-properties.html 3 | 4 | 5 | # REDIS (RedisProperties) 6 | #spring.redis.cluster.max-redirects= # Maximum number of redirects to follow when executing commands across the cluster. 7 | #spring.redis.cluster.nodes= # Comma-separated list of "host:port" pairs to bootstrap from. 8 | #spring.redis.database=0 # Database index used by the connection factory. 9 | spring.redis.host=127.0.0.1 10 | spring.redis.password= 11 | spring.redis.pool.max-active=8 12 | spring.redis.pool.max-idle=8 13 | spring.redis.pool.max-wait=-1 14 | spring.redis.pool.min-idle=0 15 | spring.redis.port=6379 16 | #spring.redis.sentinel.master= # Name of Redis server. 17 | #spring.redis.sentinel.nodes= # Comma-separated list of host:port pairs. 18 | #spring.redis.timeout=0 # Connection timeout in milliseconds. 19 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/test/java/com/BaseTest.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import com.lengchuan.springBoot.redis.model.User; 4 | import com.lengchuan.springBoot.redis.service.UserService; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 12 | 13 | /** 14 | * @author lengchuan 15 | * @date 17-4-5 16 | */ 17 | @RunWith(SpringJUnit4ClassRunner.class) 18 | @SpringBootTest(classes = App.class) 19 | public class BaseTest { 20 | 21 | private final static Logger logger = LoggerFactory.getLogger(BaseTest.class); 22 | 23 | @Autowired 24 | private UserService userService; 25 | 26 | @Test 27 | public void add() { 28 | 29 | User u = new User(); 30 | u.setId(1); 31 | u.setName("lengchuan"); 32 | u.setEmail("lishuijun1992@gmail.com"); 33 | 34 | userService.createUser(u); 35 | 36 | } 37 | 38 | @Test 39 | public void get() { 40 | 41 | logger.info("获取到用户信息:{}", userService.getUser(1)); 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /SpringBoot-Redis/src/test/java/com/lengchuan/springBoot/redis/service/impl/UserServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.redis.service.impl; 2 | 3 | import com.BaseTest; 4 | import com.lengchuan.springBoot.redis.model.User; 5 | import com.lengchuan.springBoot.redis.service.UserService; 6 | import org.junit.Test; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | 9 | /** 10 | * @author lengchuan 11 | * @date 17-5-8 12 | */ 13 | public class UserServiceImplTest extends BaseTest { 14 | @Test 15 | public void getUser() throws Exception { 16 | System.out.println(userService.getUser(1)); 17 | } 18 | 19 | @Autowired 20 | private UserService userService; 21 | 22 | @Test 23 | public void createUser() throws Exception { 24 | User user = new User(); 25 | user.setId(1); 26 | user.setName("test1"); 27 | user.setEmail("test@test.com"); 28 | userService.createUser(user); 29 | } 30 | 31 | 32 | } -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/README.md: -------------------------------------------------------------------------------- 1 | # SpringBoot集成Spring Data JPA 2 | 3 | ## JPA是什么 4 | 5 | JPA(Java Persistence API)是Sun官方提出的Java持久化规范,它为Java开发人员提供了一种对象/关联映射工具 6 | 来管理Java应用中的关系数据.它包括以下几方面的内容: 7 | + 1.ORM映射 8 | 支持xml和注解方式建立实体与表之间的映射. 9 | + 2.Java持久化API 10 | 定义了一些常用的CRUD接口,我们只需直接调用,而不需要考虑底层JDBC和SQL的细节. 11 | + 3.JPQL查询语言 12 | 这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合. 13 | 14 | 在工作中,我们都会用到ORM技术,比如Hibernate,JOOQ等,根据需求的不同,我们会采用不同的ORM框架,当我们需要 15 | 更换ORM框架来满足我们的需求时,由于不同ORM框架的实现,使用方式的区别以及各自为营,我们往往需要对代码进行重构.JPA的 16 | 出现就是为了解决这个问题,JPA充分吸收了现有一些ORM框架的优点,具有易于使用,伸缩性强等优点,为ORM技术提供了一套标准的 17 | 接口用来整合不同的ORM框架. 18 | 19 | ## Hibernate对JPA的实现 20 | JPA本身并不做具体的实现,而只是定义了一些接口规范,让其它ORM来具体的实现这些接口,就目前来说,对JPA规范实现最好的就是 21 | Hibernate了.这里提一下Mybatis,Mybatis并没有实现JPA规范,它本身也不能算做一个真正的ORM框架. 22 | 23 | ## Spring Data JPA是什么 24 | Spring Data JPA只是Spring Data框架的一个模块,可以极大的简化JPA的使用,Spring Data JPA强大的地方还在于能够简化我们 25 | 对持久层业务逻辑的开发,通过规范持久层方法的名称,通过名称来判断需要实现什么业务逻辑,我们机会可以在不写一句sql,不做任何dao层 26 | 逻辑的情况下完成我们绝大部分的开发,当然,对于一些复杂的,性能要求高的查询,Spring Data JPA一样支持我们使用原生的sql. 27 | 28 | 在这里我们不过多的去介绍JPA以及Spring Data JPA,主要还是与SpringBoot集成的一些细节以及示例. 29 | 30 | ## 引入依赖 31 | 32 | ```aidl 33 | 34 | 35 | org.springframework.boot 36 | spring-boot-starter-data-jpa 37 | 38 | 39 | ``` 40 | 我们引入这个依赖后,发现也引入了Hibernate的包,这是现在一种默认的做法,Hibernate已经被作为JPA规范的最好实现了,这里就不介绍Druid数据源的 41 | 配置了,大家可以看另外一篇XXXX. 42 | 43 | ## 配置我们的数据源以及JPA(Hibernate) 44 | ```aidl 45 | #配置模板 46 | #https://docs.spring.io/spring-boot/docs/${springboot.version}/reference/html/common-application-properties.html 47 | 48 | #数据源 49 | spring.datasource.druid.write.url=jdbc:mysql://localhost:3306/jpa 50 | spring.datasource.druid.write.username=root 51 | spring.datasource.druid.write.password=1 52 | spring.datasource.druid.write.driver-class-name=com.mysql.jdbc.Driver 53 | 54 | spring.datasource.druid.read.url=jdbc:mysql://localhost:3306/jpa 55 | spring.datasource.druid.read.username=root 56 | spring.datasource.druid.read.password=1 57 | spring.datasource.druid.read.driver-class-name=com.mysql.jdbc.Driver 58 | 59 | #JPA (JpaBaseConfiguration, HibernateJpaAutoConfiguration) 60 | spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect 61 | spring.jpa.database=mysql 62 | spring.jpa.generate-ddl=true 63 | #就是hibernate.hbm2ddl.auto,具体说明可以看README 64 | spring.jpa.hibernate.ddl-auto=update 65 | #通过方法名解析sql的策略,具体说明可以看README,这里就不配置了 66 | spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultComponentSafeNamingStrategy 67 | spring.jpa.show-sql=true 68 | #spring.jpa.properties.* 69 | #spring.jpa.properties.hibernate.hbm2ddl.auto=update 70 | #spring.jpa.properties.hibernate.show_sql=true 71 | #spring.jpa.properties.hibernate.use-new-id-generator-mappings=true 72 | ``` 73 | 74 | ## druid数据源注入 75 | ```aidl 76 | @Configuration 77 | public class DruidDataSourceConfig { 78 | /** 79 | * DataSource 配置 80 | * @return 81 | */ 82 | @ConfigurationProperties(prefix = "spring.datasource.druid.read") 83 | @Bean(name = "readDruidDataSource") 84 | public DataSource readDruidDataSource() { 85 | return new DruidDataSource(); 86 | } 87 | 88 | 89 | /** 90 | * DataSource 配置 91 | * @return 92 | */ 93 | @ConfigurationProperties(prefix = "spring.datasource.druid.write") 94 | @Bean(name = "writeDruidDataSource") 95 | @Primary 96 | public DataSource writeDruidDataSource() { 97 | return new DruidDataSource(); 98 | } 99 | } 100 | 101 | ``` 102 | 103 | ## EntityManagerFactory实例注入 104 | EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory 105 | 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session, 106 | mybatis的sqlSession. 107 | 注入EntityManagerFactory有两种方式,一种是直接注入EntityManagerFactory,另一种是通过 108 | LocalContainerEntityManagerFactoryBean来间接注入.虽说这两种方法都是基于 109 | LocalContainerEntityManagerFactoryBean的,但是在配置上还是有一些区别. 110 | 111 | + 1.直接注入EntityManagerFactory 112 | 113 | 配置:通过spring.jpa.properties.*来配置Hibernate的属性 114 | ```aidl 115 | spring.jpa.properties.hibernate.hbm2ddl.auto=update 116 | spring.jpa.properties.hibernate.show_sql=true 117 | spring.jpa.properties.hibernate.use-new-id-generator-mappings=true 118 | ``` 119 | ```aidl 120 | @Configuration 121 | @EnableJpaRepositories(value = "com.lengchuan.springBoot.jpa.repository", 122 | entityManagerFactoryRef = "writeEntityManagerFactory", 123 | transactionManagerRef="writeTransactionManager") 124 | public class WriteDataSourceConfig { 125 | 126 | @Autowired 127 | JpaProperties jpaProperties; 128 | 129 | @Autowired 130 | @Qualifier("writeDruidDataSource") 131 | private DataSource writeDruidDataSource; 132 | 133 | /** 134 | * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory 135 | * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session, 136 | * mybatis的sqlSession. 137 | * @return 138 | */ 139 | @Bean(name = "writeEntityManagerFactory") 140 | @Primary 141 | public EntityManagerFactory writeEntityManagerFactory() { 142 | HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 143 | LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 144 | factory.setJpaVendorAdapter(vendorAdapter); 145 | factory.setPackagesToScan("com.lengchuan.springBoot.jpa.entity"); 146 | factory.setDataSource(writeDruidDataSource);//数据源 147 | 148 | factory.setJpaPropertyMap(jpaProperties.getProperties()); 149 | factory.afterPropertiesSet();//在完成了其它所有相关的配置加载以及属性设置后,才初始化 150 | return factory.getObject(); 151 | } 152 | 153 | /** 154 | * 配置事物管理器 155 | * @return 156 | */ 157 | @Bean(name = "writeTransactionManager") 158 | @Primary 159 | public PlatformTransactionManager writeTransactionManager() { 160 | JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(); 161 | jpaTransactionManager.setEntityManagerFactory(this.writeEntityManagerFactory()); 162 | return jpaTransactionManager; 163 | } 164 | } 165 | ``` 166 | + 2.先注入LocalContainerEntityManagerFactoryBean,再获取EntityManagerFactory 167 | 168 | 配置: 169 | ```aidl 170 | spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect 171 | spring.jpa.database=mysql 172 | spring.jpa.generate-ddl=true 173 | #就是hibernate.hbm2ddl.auto,具体说明可以看README 174 | spring.jpa.hibernate.ddl-auto=update 175 | #通过方法名解析sql的策略,具体说明可以看README,这里就不配置了 176 | spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultComponentSafeNamingStrategy 177 | spring.jpa.show-sql=true 178 | ``` 179 | ```aidl 180 | @Configuration 181 | @EnableJpaRepositories(value = "com.lengchuan.springBoot.jpa.repository", 182 | entityManagerFactoryRef = "writeEntityManagerFactory", 183 | transactionManagerRef = "writeTransactionManager") 184 | public class WriteDataSourceConfig1 { 185 | 186 | @Autowired 187 | JpaProperties jpaProperties; 188 | 189 | @Autowired 190 | @Qualifier("writeDruidDataSource") 191 | private DataSource writeDruidDataSource; 192 | 193 | /** 194 | * 我们通过LocalContainerEntityManagerFactoryBean来获取EntityManagerFactory实例 195 | * @return 196 | */ 197 | @Bean(name = "writeEntityManagerFactoryBean") 198 | @Primary 199 | public LocalContainerEntityManagerFactoryBean writeEntityManagerFactoryBean(EntityManagerFactoryBuilder builder) { 200 | return builder 201 | .dataSource(writeDruidDataSource) 202 | .properties(jpaProperties.getProperties()) 203 | .packages("com.lengchuan.springBoot.jpa.entity") //设置实体类所在位置 204 | .persistenceUnit("writePersistenceUnit") 205 | .build(); 206 | //.getObject();//不要在这里直接获取EntityManagerFactory 207 | } 208 | 209 | /** 210 | * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory 211 | * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session, 212 | * mybatis的sqlSession. 213 | * @param builder 214 | * @return 215 | */ 216 | @Bean(name = "writeEntityManagerFactory") 217 | @Primary 218 | public EntityManagerFactory writeEntityManagerFactory(EntityManagerFactoryBuilder builder) { 219 | return this.writeEntityManagerFactoryBean(builder).getObject(); 220 | } 221 | 222 | /** 223 | * 配置事物管理器 224 | * @return 225 | */ 226 | @Bean(name = "writeTransactionManager") 227 | @Primary 228 | public PlatformTransactionManager writeTransactionManager(EntityManagerFactoryBuilder builder) { 229 | return new JpaTransactionManager(writeEntityManagerFactory(builder)); 230 | } 231 | } 232 | 233 | ``` 234 | 对于这个配置 235 | ```aidl 236 | @Bean(name = "writeEntityManagerFactoryBean") 237 | @Primary 238 | public LocalContainerEntityManagerFactoryBean writeEntityManagerFactoryBean(EntityManagerFactoryBuilder builder) { 239 | return builder 240 | .dataSource(writeDruidDataSource) 241 | .properties(jpaProperties.getProperties()) 242 | .packages("com.lengchuan.springBoot.jpa.entity") //设置实体类所在位置 243 | .persistenceUnit("writePersistenceUnit") 244 | .build(); 245 | //.getObject();//不要在这里直接获取EntityManagerFactory 246 | } 247 | ``` 248 | getObject()方法可以获取到EntityManagerFactory的实例,看似跟第一种没有什么区别,但是我们不能直接用 249 | getObject(),不然会获取不到,报空指针异常. 250 | 251 | ## 读写分离配置 252 | 253 | ### 自定义注入AbstractRoutingDataSource 254 | ``` 255 | @Configuration 256 | public class DataSourceConfig { 257 | 258 | private final static String WRITE_DATASOURCE_KEY = "writeDruidDataSource"; 259 | private final static String READ_DATASOURCE_KEY = "readDruidDataSource"; 260 | 261 | /** 262 | * 注入AbstractRoutingDataSource 263 | * @param readDruidDataSource 264 | * @param writeDruidDataSource 265 | * @return 266 | * @throws Exception 267 | */ 268 | @Bean 269 | public AbstractRoutingDataSource routingDataSource( 270 | @Qualifier(READ_DATASOURCE_KEY) DataSource readDruidDataSource, 271 | @Qualifier(WRITE_DATASOURCE_KEY) DataSource writeDruidDataSource 272 | ) throws Exception { 273 | DynamicDataSource dataSource = new DynamicDataSource(); 274 | 275 | Map targetDataSources = new HashMap(); 276 | targetDataSources.put(WRITE_DATASOURCE_KEY, writeDruidDataSource); 277 | targetDataSources.put(READ_DATASOURCE_KEY, readDruidDataSource); 278 | dataSource.setTargetDataSources(targetDataSources); 279 | dataSource.setDefaultTargetDataSource(writeDruidDataSource); 280 | return dataSource; 281 | } 282 | } 283 | ``` 284 | 285 | ### 自定义注解 286 | ``` 287 | @Target({ElementType.METHOD, ElementType.TYPE}) 288 | @Retention(RetentionPolicy.RUNTIME) 289 | @Documented 290 | public @interface TargetDataSource { 291 | String dataSource() default "";//数据源 292 | } 293 | 294 | ``` 295 | 296 | 297 | ### 使用ThreadLocal使数据源与线程绑定 298 | ``` 299 | public class DynamicDataSourceHolder { 300 | //使用ThreadLocal把数据源与当前线程绑定 301 | private static final ThreadLocal dataSources = new ThreadLocal(); 302 | 303 | public static void setDataSource(String dataSourceName) { 304 | dataSources.set(dataSourceName); 305 | } 306 | 307 | public static String getDataSource() { 308 | return (String) dataSources.get(); 309 | } 310 | 311 | public static void clearDataSource() { 312 | dataSources.remove(); 313 | } 314 | } 315 | ``` 316 | 317 | ``` 318 | public class DynamicDataSource extends AbstractRoutingDataSource { 319 | @Override 320 | protected Object determineCurrentLookupKey() { 321 | 322 | //可以做一个简单的负载均衡策略 323 | String lookupKey = DynamicDataSourceHolder.getDataSource(); 324 | System.out.println("------------lookupKey---------"+lookupKey); 325 | 326 | return lookupKey; 327 | } 328 | } 329 | ``` 330 | 331 | ### 定义切面 332 | ``` 333 | @Aspect 334 | @Component 335 | public class DynamicDataSourceAspect { 336 | @Around("execution(public * com.lengchuan.springBoot.jpa.service..*.*(..))") 337 | public Object around(ProceedingJoinPoint pjp) throws Throwable { 338 | MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); 339 | Method targetMethod = methodSignature.getMethod(); 340 | if (targetMethod.isAnnotationPresent(TargetDataSource.class)) { 341 | String targetDataSource = targetMethod.getAnnotation(TargetDataSource.class).dataSource(); 342 | System.out.println("----------数据源是:" + targetDataSource + "------"); 343 | DynamicDataSourceHolder.setDataSource(targetDataSource); 344 | } 345 | Object result = pjp.proceed();//执行方法 346 | DynamicDataSourceHolder.clearDataSource(); 347 | 348 | return result; 349 | } 350 | } 351 | 352 | ``` 353 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | SpringBoot-Study 7 | com.lengchuan 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | com.lengchuan 13 | SpringBoot-SpringDataJPA 14 | jar 15 | 16 | 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-dependencies 22 | ${springboot.version} 23 | pom 24 | import 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | mysql 33 | mysql-connector-java 34 | 6.0.3 35 | 36 | 37 | 38 | 39 | com.alibaba 40 | druid 41 | 1.0.29 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-test 46 | test 47 | 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-starter-data-jpa 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-maven-plugin 62 | 63 | 64 | 65 | repackage 66 | 67 | 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/App.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @author lengchuan 8 | * @date 17-4-13 9 | */ 10 | @SpringBootApplication() 11 | public class App { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(App.class, args); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/config/ReadAndWrite/annotation/TargetDataSource.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.config.ReadAndWrite.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * 切换数据源 7 | * 8 | * @author lengchuan 9 | * @date 17-4-5 10 | */ 11 | @Target({ElementType.METHOD, ElementType.TYPE}) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Documented 14 | public @interface TargetDataSource { 15 | String dataSource() default "";//数据源 16 | } 17 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/config/ReadAndWrite/aspect/DynamicDataSourceAspect.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.config.ReadAndWrite.aspect; 2 | 3 | 4 | import com.lengchuan.springBoot.jpa.config.ReadAndWrite.annotation.TargetDataSource; 5 | import com.lengchuan.springBoot.jpa.config.ReadAndWrite.config.DynamicDataSourceHolder; 6 | import org.aspectj.lang.ProceedingJoinPoint; 7 | import org.aspectj.lang.annotation.Around; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.reflect.MethodSignature; 10 | import org.springframework.stereotype.Component; 11 | 12 | import java.lang.reflect.Method; 13 | 14 | /** 15 | * aop 配置动态切换数据源 16 | * 17 | * @author lengchuan 18 | * @date 17-4-5 19 | */ 20 | @Aspect 21 | @Component 22 | public class DynamicDataSourceAspect { 23 | @Around("execution(public * com.lengchuan.springBoot.jpa.service..*.*(..))") 24 | public Object around(ProceedingJoinPoint pjp) throws Throwable { 25 | MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); 26 | Method targetMethod = methodSignature.getMethod(); 27 | if (targetMethod.isAnnotationPresent(TargetDataSource.class)) { 28 | String targetDataSource = targetMethod.getAnnotation(TargetDataSource.class).dataSource(); 29 | System.out.println("----------数据源是:" + targetDataSource + "------"); 30 | DynamicDataSourceHolder.setDataSource(targetDataSource); 31 | } 32 | Object result = pjp.proceed();//执行方法 33 | return result; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/config/ReadAndWrite/config/DataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.config.ReadAndWrite.config; 2 | 3 | import org.springframework.beans.factory.annotation.Qualifier; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 7 | 8 | import javax.sql.DataSource; 9 | import java.util.HashMap; 10 | import java.util.Map; 11 | 12 | /** 13 | * @author lengchuan 14 | * @date 17 -4-5 15 | */ 16 | @Configuration 17 | public class DataSourceConfig { 18 | 19 | private final static String WRITE_DATASOURCE_KEY = "writeDruidDataSource"; 20 | private final static String READ_DATASOURCE_KEY = "readDruidDataSource"; 21 | 22 | /** 23 | * 注入AbstractRoutingDataSource 24 | * @param readDruidDataSource 25 | * @param writeDruidDataSource 26 | * @return 27 | * @throws Exception 28 | */ 29 | @Bean 30 | public AbstractRoutingDataSource routingDataSource( 31 | @Qualifier(READ_DATASOURCE_KEY) DataSource readDruidDataSource, 32 | @Qualifier(WRITE_DATASOURCE_KEY) DataSource writeDruidDataSource 33 | ) throws Exception { 34 | DynamicDataSource dataSource = new DynamicDataSource(); 35 | 36 | Map targetDataSources = new HashMap(); 37 | targetDataSources.put(WRITE_DATASOURCE_KEY, writeDruidDataSource); 38 | targetDataSources.put(READ_DATASOURCE_KEY, readDruidDataSource); 39 | dataSource.setTargetDataSources(targetDataSources); 40 | dataSource.setDefaultTargetDataSource(writeDruidDataSource); 41 | return dataSource; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/config/ReadAndWrite/config/DynamicDataSource.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.config.ReadAndWrite.config; 2 | 3 | import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 4 | 5 | /** 6 | * @author lengchuan 7 | * @date 17-4-5 8 | */ 9 | public class DynamicDataSource extends AbstractRoutingDataSource { 10 | @Override 11 | protected Object determineCurrentLookupKey() { 12 | 13 | //可以做一个简单的负载均衡策略 14 | String lookupKey = DynamicDataSourceHolder.getDataSource(); 15 | System.out.println("------------lookupKey---------"+lookupKey); 16 | 17 | return lookupKey; 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/config/ReadAndWrite/config/DynamicDataSourceHolder.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.config.ReadAndWrite.config; 2 | 3 | /** 4 | * @author lengchuan 5 | * @date 17-4-5 6 | */ 7 | public class DynamicDataSourceHolder { 8 | //使用ThreadLocal把数据源与当前线程绑定 9 | private static final ThreadLocal dataSources = new ThreadLocal(); 10 | 11 | public static void setDataSource(String dataSourceName) { 12 | dataSources.set(dataSourceName); 13 | } 14 | 15 | public static String getDataSource() { 16 | return dataSources.get(); 17 | } 18 | 19 | public static void clearDataSource() { 20 | dataSources.remove(); 21 | } 22 | } -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/config/dataSource/DruidDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.config.dataSource; 2 | 3 | import com.alibaba.druid.pool.DruidDataSource; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.context.annotation.Primary; 8 | 9 | import javax.sql.DataSource; 10 | 11 | /** 12 | * @author lengchuan 13 | * @date 17-4-17 14 | */ 15 | @Configuration 16 | public class DruidDataSourceConfig { 17 | /** 18 | * DataSource 配置 19 | * @return 20 | */ 21 | @ConfigurationProperties(prefix = "spring.datasource.druid.read") 22 | @Bean(name = "readDruidDataSource") 23 | public DataSource readDruidDataSource() { 24 | return new DruidDataSource(); 25 | } 26 | 27 | 28 | /** 29 | * DataSource 配置 30 | * @return 31 | */ 32 | @ConfigurationProperties(prefix = "spring.datasource.druid.write") 33 | @Bean(name = "writeDruidDataSource") 34 | @Primary 35 | public DataSource writeDruidDataSource() { 36 | return new DruidDataSource(); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/config/dataSource/ReadDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.config.dataSource; 2 | 3 | /** 4 | * write数据源配置 5 | * 6 | * @author lengchuan 7 | * @date 17-4-13 8 | */ 9 | //@Configuration 10 | //@EnableJpaRepositories(value = "com.lengchuan.springBoot.jpa.repository", 11 | // entityManagerFactoryRef ="readEntityManagerFactory", 12 | // transactionManagerRef = "readTransactionManager") 13 | public class ReadDataSourceConfig { 14 | 15 | // @Autowired 16 | // private JpaProperties jpaProperties; 17 | // 18 | // @Autowired 19 | // @Qualifier("readDruidDataSource") 20 | // private DataSource readDruidDataSource; 21 | // 22 | // /** 23 | // * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory 24 | // * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session, 25 | // * mybatis的sqlSession. 26 | // * @return 27 | // */ 28 | // @Bean(name = "readEntityManagerFactory") 29 | // public EntityManagerFactory readEntityManagerFactory() { 30 | // HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 31 | // LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 32 | // factory.setJpaVendorAdapter(vendorAdapter); 33 | // factory.setPackagesToScan("com.lengchuan.springBoot.jpa.entity");//要扫描的实体 34 | // factory.setDataSource(readDruidDataSource);//数据源 35 | // Properties properties = new Properties(); 36 | // properties.setProperty("hibernate.ddl-auto","true"); 37 | // factory.setJpaProperties(properties); 38 | // 39 | // factory.setJpaPropertyMap(jpaProperties.getProperties()); 40 | // factory.afterPropertiesSet();//在完成了其它所有相关的配置加载以及属性设置后,才初始化 41 | // return factory.getObject(); 42 | // } 43 | // 44 | // /** 45 | // * 配置事物管理器 46 | // * @return 47 | // */ 48 | // @Bean(name = "readTransactionManager") 49 | // public PlatformTransactionManager readTransactionManager() { 50 | // JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(); 51 | // jpaTransactionManager.setEntityManagerFactory(this.readEntityManagerFactory()); 52 | // return jpaTransactionManager; 53 | // } 54 | } 55 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/config/dataSource/ReadDataSourceConfig1.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.config.dataSource; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Qualifier; 5 | import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; 6 | import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 10 | import org.springframework.orm.jpa.JpaTransactionManager; 11 | import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 12 | import org.springframework.transaction.PlatformTransactionManager; 13 | 14 | import javax.persistence.EntityManagerFactory; 15 | import javax.sql.DataSource; 16 | 17 | /** 18 | * write数据源配置 19 | * 20 | * @author lengchuan 21 | * @date 17-4-13 22 | */ 23 | @Configuration 24 | @EnableJpaRepositories(value = "com.lengchuan.springBoot.jpa.repository", 25 | entityManagerFactoryRef = "readEntityManagerFactory", 26 | transactionManagerRef = "readTransactionManager") 27 | public class ReadDataSourceConfig1 { 28 | 29 | @Autowired 30 | private JpaProperties jpaProperties; 31 | 32 | @Autowired 33 | @Qualifier("readDruidDataSource") 34 | private DataSource readDruidDataSource; 35 | 36 | /** 37 | * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory 38 | * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session, 39 | * mybatis的sqlSession. 40 | * @return 41 | */ 42 | @Bean(name = "readEntityManagerFactoryBean") 43 | public LocalContainerEntityManagerFactoryBean readEntityManagerFactoryBean(EntityManagerFactoryBuilder builder) { 44 | return builder 45 | .dataSource(readDruidDataSource) 46 | .properties(jpaProperties.getProperties()) 47 | .packages("com.lengchuan.springBoot.jpa.entity") //设置实体类所在位置 48 | .persistenceUnit("readPersistenceUnit")//持久化单元名称 49 | .build(); 50 | //.getObject(); 51 | } 52 | 53 | /** 54 | * 55 | * @param builder 56 | * @return 57 | */ 58 | @Bean(name = "readEntityManagerFactory") 59 | public EntityManagerFactory readEntityManagerFactory(EntityManagerFactoryBuilder builder) { 60 | return this.readEntityManagerFactoryBean(builder).getObject(); 61 | } 62 | 63 | /** 64 | * 配置事物管理器 65 | * @return 66 | */ 67 | @Bean(name = "readTransactionManager") 68 | public PlatformTransactionManager readTransactionManager(EntityManagerFactoryBuilder builder) { 69 | return new JpaTransactionManager(readEntityManagerFactory(builder)); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/config/dataSource/WriteDataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.config.dataSource; 2 | 3 | /** 4 | * write数据源配置 5 | * 6 | * @author lengchuan 7 | * @date 17-4-13 8 | */ 9 | //@Configuration 10 | //@EnableJpaRepositories(value = "com.lengchuan.springBoot.jpa.repository", 11 | // entityManagerFactoryRef = "writeEntityManagerFactory", 12 | // transactionManagerRef="writeTransactionManager") 13 | public class WriteDataSourceConfig { 14 | 15 | // @Autowired 16 | // JpaProperties jpaProperties; 17 | // 18 | // @Autowired 19 | // @Qualifier("writeDruidDataSource") 20 | // private DataSource writeDruidDataSource; 21 | // 22 | // /** 23 | // * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory 24 | // * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session, 25 | // * mybatis的sqlSession. 26 | // * @return 27 | // */ 28 | // @Bean(name = "writeEntityManagerFactory") 29 | // @Primary 30 | // public EntityManagerFactory writeEntityManagerFactory() { 31 | // HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 32 | // LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 33 | // factory.setJpaVendorAdapter(vendorAdapter); 34 | // factory.setPackagesToScan("com.lengchuan.springBoot.jpa.entity"); 35 | // factory.setDataSource(writeDruidDataSource);//数据源 36 | // 37 | // factory.setJpaPropertyMap(jpaProperties.getProperties()); 38 | // factory.afterPropertiesSet();//在完成了其它所有相关的配置加载以及属性设置后,才初始化 39 | // return factory.getObject(); 40 | // } 41 | // 42 | // /** 43 | // * 配置事物管理器 44 | // * @return 45 | // */ 46 | // @Bean(name = "writeTransactionManager") 47 | // @Primary 48 | // public PlatformTransactionManager writeTransactionManager() { 49 | // JpaTransactionManager jpaTransactionManager = new JpaTransactionManager(); 50 | // jpaTransactionManager.setEntityManagerFactory(this.writeEntityManagerFactory()); 51 | // return jpaTransactionManager; 52 | // } 53 | } 54 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/config/dataSource/WriteDataSourceConfig1.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.config.dataSource; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.beans.factory.annotation.Qualifier; 5 | import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; 6 | import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; 7 | import org.springframework.context.annotation.Bean; 8 | import org.springframework.context.annotation.Configuration; 9 | import org.springframework.context.annotation.Primary; 10 | import org.springframework.data.jpa.repository.config.EnableJpaRepositories; 11 | import org.springframework.orm.jpa.JpaTransactionManager; 12 | import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; 13 | import org.springframework.transaction.PlatformTransactionManager; 14 | 15 | import javax.persistence.EntityManagerFactory; 16 | import javax.sql.DataSource; 17 | 18 | /** 19 | * write数据源配置 20 | * 21 | * @author lengchuan 22 | * @date 17-4-13 23 | */ 24 | @Configuration 25 | @EnableJpaRepositories(value = "com.lengchuan.springBoot.jpa.repository", 26 | entityManagerFactoryRef = "writeEntityManagerFactory", 27 | transactionManagerRef = "writeTransactionManager") 28 | public class WriteDataSourceConfig1 { 29 | 30 | @Autowired 31 | JpaProperties jpaProperties; 32 | 33 | @Autowired 34 | @Qualifier("writeDruidDataSource") 35 | private DataSource writeDruidDataSource; 36 | 37 | /** 38 | * 我们通过LocalContainerEntityManagerFactoryBean来获取EntityManagerFactory实例 39 | * @return 40 | */ 41 | @Bean(name = "writeEntityManagerFactoryBean") 42 | @Primary 43 | public LocalContainerEntityManagerFactoryBean writeEntityManagerFactoryBean(EntityManagerFactoryBuilder builder) { 44 | return builder 45 | .dataSource(writeDruidDataSource) 46 | .properties(jpaProperties.getProperties()) 47 | .packages("com.lengchuan.springBoot.jpa.entity") //设置实体类所在位置 48 | .persistenceUnit("writePersistenceUnit") 49 | .build(); 50 | //.getObject();//不要在这里直接获取EntityManagerFactory 51 | } 52 | 53 | /** 54 | * EntityManagerFactory类似于Hibernate的SessionFactory,mybatis的SqlSessionFactory 55 | * 总之,在执行操作之前,我们总要获取一个EntityManager,这就类似于Hibernate的Session, 56 | * mybatis的sqlSession. 57 | * @param builder 58 | * @return 59 | */ 60 | @Bean(name = "writeEntityManagerFactory") 61 | @Primary 62 | public EntityManagerFactory writeEntityManagerFactory(EntityManagerFactoryBuilder builder) { 63 | return this.writeEntityManagerFactoryBean(builder).getObject(); 64 | } 65 | 66 | /** 67 | * 配置事物管理器 68 | * @return 69 | */ 70 | @Bean(name = "writeTransactionManager") 71 | @Primary 72 | public PlatformTransactionManager writeTransactionManager(EntityManagerFactoryBuilder builder) { 73 | return new JpaTransactionManager(writeEntityManagerFactory(builder)); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/entity/City.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012-2013 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.lengchuan.springBoot.jpa.entity; 18 | 19 | import javax.persistence.*; 20 | import java.io.Serializable; 21 | 22 | @Entity 23 | @Table(name = "city") 24 | public class City implements Serializable { 25 | 26 | private static final long serialVersionUID = 1L; 27 | 28 | @Id 29 | @GeneratedValue 30 | private Long id; 31 | 32 | @Column(nullable = false, unique = true, length = 64) 33 | private String name; 34 | 35 | @Column(nullable = false) 36 | private String state; 37 | 38 | @Column(nullable = false) 39 | private String country; 40 | 41 | @Column(nullable = false) 42 | private String map; 43 | 44 | public City() { 45 | } 46 | 47 | public City(String name, String country) { 48 | super(); 49 | this.name = name; 50 | this.country = country; 51 | } 52 | 53 | public String getName() { 54 | return this.name; 55 | } 56 | 57 | public String getState() { 58 | return this.state; 59 | } 60 | 61 | public String getCountry() { 62 | return this.country; 63 | } 64 | 65 | public String getMap() { 66 | return this.map; 67 | } 68 | 69 | public Long getId() { 70 | return id; 71 | } 72 | 73 | public void setId(Long id) { 74 | this.id = id; 75 | } 76 | 77 | public void setName(String name) { 78 | this.name = name; 79 | } 80 | 81 | public void setState(String state) { 82 | this.state = state; 83 | } 84 | 85 | public void setCountry(String country) { 86 | this.country = country; 87 | } 88 | 89 | public void setMap(String map) { 90 | this.map = map; 91 | } 92 | 93 | @Override 94 | public String toString() { 95 | return getName() + "," + getState() + "," + getCountry(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/repository/CityRepository.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.repository; 2 | 3 | import com.lengchuan.springBoot.jpa.entity.City; 4 | import org.springframework.data.domain.Page; 5 | import org.springframework.data.domain.Pageable; 6 | import org.springframework.data.jpa.repository.JpaRepository; 7 | import org.springframework.stereotype.Repository; 8 | 9 | /** 10 | * @author lengchuan 11 | * @date 17-4-16 12 | */ 13 | @Repository 14 | public interface CityRepository extends JpaRepository { 15 | 16 | /** 17 | * 通过id查询 18 | * @param id 19 | * @return 20 | */ 21 | City findById(Long id); 22 | 23 | /** 24 | * 通过country字段查询 25 | * @param country 26 | * @return 27 | */ 28 | City findByCountryEquals(String country); 29 | 30 | /** 31 | * 分页查询 32 | * @param pageable 33 | * @return 34 | */ 35 | Page findAll(Pageable pageable); 36 | 37 | /** 38 | * 分页查询 name和country 39 | * @param name 40 | * @param country 41 | * @param pageable 42 | * @return 43 | */ 44 | Page findByNameContainingAndCountryContainingAllIgnoringCase(String name, 45 | String country, Pageable pageable); 46 | 47 | /** 48 | * 分页查询 name和country,忽略大小写 49 | * @param name 50 | * @param country 51 | * @return 52 | */ 53 | City findByNameAndCountryAllIgnoringCase(String name, String country); 54 | } 55 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/service/CityService.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.service; 2 | 3 | import com.lengchuan.springBoot.jpa.entity.City; 4 | import org.springframework.data.domain.Page; 5 | import org.springframework.data.domain.Pageable; 6 | 7 | /** 8 | * @author lengchuan 9 | * @date 17-4-16 10 | */ 11 | public interface CityService { 12 | 13 | /** 14 | * 通过id查询 15 | * @param id 16 | * @return 17 | */ 18 | City findById(Long id); 19 | 20 | /** 21 | * 通过country字段查询 22 | * @param country 23 | * @return 24 | */ 25 | City findByCountryEquals(String country); 26 | 27 | /** 28 | * 分页查询 29 | * @param pageable 30 | * @return 31 | */ 32 | Page findAll(Pageable pageable); 33 | 34 | /** 35 | * 分页查询 name和country 36 | * @param name 37 | * @param country 38 | * @param pageable 39 | * @return 40 | */ 41 | Page findByNameContainingAndCountryContainingAllIgnoringCase(String name, 42 | String country, Pageable pageable); 43 | 44 | /** 45 | * 分页查询 name和country,忽略大小写 46 | * @param name 47 | * @param country 48 | * @return 49 | */ 50 | City findByNameAndCountryAllIgnoringCase(String name, String country); 51 | 52 | /** 53 | * 创建 54 | * @param city 55 | * @return 56 | */ 57 | City createCity(City city); 58 | } 59 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/java/com/lengchuan/springBoot/jpa/service/impl/CityServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.service.impl; 2 | 3 | import com.lengchuan.springBoot.jpa.config.ReadAndWrite.annotation.TargetDataSource; 4 | import com.lengchuan.springBoot.jpa.entity.City; 5 | import com.lengchuan.springBoot.jpa.repository.CityRepository; 6 | import com.lengchuan.springBoot.jpa.service.CityService; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.data.domain.Page; 9 | import org.springframework.data.domain.Pageable; 10 | import org.springframework.stereotype.Service; 11 | import org.springframework.transaction.annotation.Transactional; 12 | 13 | /** 14 | * @author lengchuan 15 | * @date 17-4-16 16 | */ 17 | @Service 18 | public class CityServiceImpl implements CityService { 19 | 20 | @Autowired 21 | private CityRepository cityRepository; 22 | /** 23 | * 通过id查询 24 | * @param id 25 | * @return 26 | */ 27 | public City findById(Long id) { 28 | return null; 29 | } 30 | 31 | /** 32 | * 通过country字段查询 33 | * @param country 34 | * @return 35 | */ 36 | public City findByCountryEquals(String country) { 37 | return null; 38 | } 39 | 40 | /** 41 | * 分页查询 42 | * @param pageable 43 | * @return 44 | */ 45 | public Page findAll(Pageable pageable) { 46 | return null; 47 | } 48 | 49 | /** 50 | * 分页查询 name和country 51 | * @param name 52 | * @param country 53 | * @param pageable 54 | * @return 55 | */ 56 | public Page findByNameContainingAndCountryContainingAllIgnoringCase(String name, String country, Pageable pageable) { 57 | return null; 58 | } 59 | 60 | /** 61 | * 分页查询 name和country,忽略大小写 62 | * @param name 63 | * @param country 64 | * @return 65 | */ 66 | public City findByNameAndCountryAllIgnoringCase(String name, String country) { 67 | return null; 68 | } 69 | 70 | @TargetDataSource(dataSource = "writeDruidDataSource") 71 | @Transactional(value = "writeTransactionManager") 72 | public City createCity(City city) { 73 | return cityRepository.save(city); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #配置模板 2 | #https://docs.spring.io/spring-boot/docs/${springboot.version}/reference/html/common-application-properties.html 3 | 4 | #数据源 5 | spring.datasource.druid.write.url=jdbc:mysql://localhost:3306/jpa 6 | spring.datasource.druid.write.username=root 7 | spring.datasource.druid.write.password=1 8 | spring.datasource.druid.write.driver-class-name=com.mysql.jdbc.Driver 9 | 10 | spring.datasource.druid.read.url=jdbc:mysql://localhost:3306/jpa 11 | spring.datasource.druid.read.username=root 12 | spring.datasource.druid.read.password=1 13 | spring.datasource.druid.read.driver-class-name=com.mysql.jdbc.Driver 14 | 15 | #JPA (JpaBaseConfiguration, HibernateJpaAutoConfiguration) 16 | spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect 17 | spring.jpa.database=mysql 18 | spring.jpa.generate-ddl=true 19 | #就是hibernate.hbm2ddl.auto,具体说明可以看README 20 | spring.jpa.hibernate.ddl-auto=update 21 | #通过方法名解析sql的策略,具体说明可以看README,这里就不配置了 22 | spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultComponentSafeNamingStrategy 23 | spring.jpa.show-sql=true 24 | #spring.jpa.properties.* 25 | #spring.jpa.properties.hibernate.hbm2ddl.auto=update 26 | #spring.jpa.properties.hibernate.show_sql=true 27 | #spring.jpa.properties.hibernate.use-new-id-generator-mappings=true 28 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/test/java/com/BaseTest.java: -------------------------------------------------------------------------------- 1 | package com; 2 | 3 | import org.junit.runner.RunWith; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 6 | 7 | /** 8 | * @author lengchuan 9 | * @date 17-4-16 10 | */ 11 | @RunWith(SpringJUnit4ClassRunner.class) 12 | @SpringBootTest 13 | public class BaseTest { 14 | } 15 | -------------------------------------------------------------------------------- /SpringBoot-SpringDataJPA/src/test/java/com/lengchuan/springBoot/jpa/service/impl/CityServiceImplTest.java: -------------------------------------------------------------------------------- 1 | package com.lengchuan.springBoot.jpa.service.impl; 2 | 3 | import com.BaseTest; 4 | import com.lengchuan.springBoot.jpa.entity.City; 5 | import com.lengchuan.springBoot.jpa.service.CityService; 6 | import org.junit.Test; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | 9 | /** 10 | * @author lengchuan 11 | * @date 17-4-16 12 | */ 13 | public class CityServiceImplTest extends BaseTest{ 14 | 15 | @Autowired 16 | private CityService cityService; 17 | @Test 18 | public void findById() throws Exception { 19 | } 20 | 21 | @Test 22 | public void findByCountryEquals() throws Exception { 23 | } 24 | 25 | @Test 26 | public void findAll() throws Exception { 27 | } 28 | 29 | @Test 30 | public void findByNameContainingAndCountryContainingAllIgnoringCase() throws Exception { 31 | } 32 | 33 | @Test 34 | public void findByNameAndCountryAllIgnoringCase() throws Exception { 35 | } 36 | 37 | @Test 38 | public void createCity() throws Exception { 39 | City city = new City(); 40 | city.setCountry("china"); 41 | city.setMap("map"); 42 | city.setName("beijing"); 43 | city.setState("state"); 44 | cityService.createCity(city); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.lengchuan 8 | SpringBoot-Study 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 2.2.6.RELEASE 17 | 18 | 19 | 20 | SpringBoot-HelloWorld-1 21 | SpringBoot-HelloWorld-2 22 | SpringBoot-GlobalExceptionHandler 23 | SpringBoot-FastJson 24 | SpringBoot-JuintTest 25 | SpringBoot-Mybatis 26 | SpringBoot-Druid 27 | SpringBoot-SpringDataJPA 28 | SpringBoot-Redis 29 | SpringBoot-Dubbo 30 | 31 | 32 | 33 | 34 | nexus-aliyun 35 | Nexus aliyun 36 | default 37 | http://maven.aliyun.com/nexus/content/groups/public 38 | 39 | false 40 | 41 | 42 | true 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | org.springframework.boot 52 | spring-boot-maven-plugin 53 | 2.0.4.RELEASE 54 | 55 | 56 | 57 | 58 | --------------------------------------------------------------------------------