├── GC ├── G1收集器.pdf ├── Hotspot VM中Oop Maps的含义?.md ├── JVM中CMS收集器.pdf ├── Java 内存结构备忘录.pdf ├── Java值传递的一些理解 .pdf ├── Java性能权威指南学习笔记.md ├── Java服务GC参数调优案例.pdf ├── Minor GC vs Major GC vs Full GC.pdf ├── java垃圾回收机制.pdf ├── jvm参数陷阱.md ├── tomcat调优以及tomcat7、8性能对比.md ├── 关于jvm中卡表和写屏障的讨论.pdf ├── 垃圾回收器是什么.pdf ├── 深入理解JVM.pdf ├── 细述 Java垃圾回收机制 │ ├── 细述 Java垃圾回收机制→How Java Garbage Collection Works- - Android .pdf │ ├── 细述 Java垃圾回收机制→Java Garbage Collection Introduction - Android .pdf │ ├── 细述 Java垃圾回收机制→Java Garbage Collection Monitoring and Analysis.pdf │ └── 细述 Java垃圾回收机制→Types of Java Garbage Collectors .pdf └── 调整G1收集器窍门.pdf ├── JAVA8 ├── ConcurrentHashMap从jdk1.7到jdk1.8的变化.md ├── Java 8 Predicates and Functions.md ├── Java 8之Stream的强大工具Collector.md ├── Java 8系列之重构和定制收集器.md ├── Java中的泛型方法.md ├── Java8新特性总览.md ├── Predicate和Consumer接口– Java 8中java.util.function包下的接口.md ├── Spring 4 支持的 Java8特性.md ├── jdk源码解读 │ └── Java 容器源码分析之 Deque 与 ArrayDeque.md └── 你真的开始用JDK8了吗?.md ├── Java集合类详解 ├── 第一章 Java常用集合类总览.pdf ├── 第三章 LinkedList源码解析.pdf └── 第二章 ArrayList源码解析.pdf ├── Linux ├── 1 计算机;GPL等开源协议;Linux 哲学思想的炼成;MBR & GPT.pdf ├── Linux(CentOS)中常用软件安装,使用及异常——MySQL,VmTools.html ├── Mariadb │ ├── Mariadb数据库备份恢复系列(一):mysqldump逻辑备份工具实战.pdf │ ├── Mariadb数据库备份恢复系列(三):xtrabackup物理备份工具之增量备份.pdf │ ├── Mariadb数据库备份恢复系列(二):xtrabackup物理备份工具之完全备份.pdf │ ├── Mariadb数据库复制系列(一):主从复制.pdf │ ├── Mariadb数据库复制系列(三):半同步复制.pdf │ ├── Mariadb数据库复制系列(二):主主复制.pdf │ ├── Mariadb数据库复制系列(五):基于SSL的复制.pdf │ ├── Mariadb数据库复制系列(四):复制过滤器的实现.pdf │ └── corosync+pacemaker对mariadb实现高可用.pdf ├── Nginx反向代理、负载均衡的实现.md ├── ansible配置详解.pdf ├── varnish详解.md ├── 文本处理工具之AWK.md └── 网络管理实战(子网划分、单网卡多IP、多网卡单IP、Linux路由实现).md ├── NIO ├── 01 Java的NIO概述.md ├── 02 Java的NIO之Channel通道.md ├── 03 NIO中的heap Buffer和direct Buffer区别.md ├── 04 NIO中Buffer缓冲区的实现.md ├── 05 Java的NIO之Scatter和Gather.md ├── 06 Java的NIO之不同channel之间传输数据.md ├── 07 Java的NIO之FileChannel.md ├── 08 Java的NIO之网络通信的SocketChannel.md ├── 09 Java的NIO之服务端的ServerSocketChannel的使用.md ├── 10 Java的NIO之用于UDP的DatagramChannel.md ├── 11 Java的NIO之Selector的使用.md ├── 12 NIO的Selector机制 之 Selector.open().md ├── 13 NIO的Selector机制 之 SelectableChannel.register(Selector sel, int ops)).md ├── 14 NIO的Selector机制 之 Selector.select().md ├── 15 Java NIO总结.md ├── BIO与NIO区别以及例子.md ├── Java的NIO与IO的区别.md ├── MappedByteBuffer以及mmap的底层原理.md └── 补充源码解读:InterruptibleChannel 与可中断 IO.md ├── README.md ├── docker ├── 10张图带你深入理解Docker容器和镜像.md └── 10张图带你深入理解Docker容器和镜像.pdf ├── git └── GIT常用经验.pdf ├── java技术栈.md ├── mybatis ├── mybatis如何根据mapper接口生成其实现类.md ├── mybatis学习笔记 │ ├── mybatis学习笔记(1)-对原生jdbc程序中的问题总结.md │ ├── mybatis学习笔记(10)-一对一查询.md │ ├── mybatis学习笔记(11)-一对多查询.md │ ├── mybatis学习笔记(12)-多对多查询.md │ ├── mybatis学习笔记(13)-延迟加载.md │ ├── mybatis学习笔记(14)-查询缓存之一级缓存.md │ ├── mybatis学习笔记(15)-查询缓存之二级缓存.md │ ├── mybatis学习笔记(16)-mybatis整合ehcache.md │ ├── mybatis学习笔记(17)-spring和mybatis整合.md │ ├── mybatis学习笔记(18)-mybatis逆向工程.md │ ├── mybatis学习笔记(2)-mybatis概述.md │ ├── mybatis学习笔记(3)-入门程序一.md │ ├── mybatis学习笔记(3)-入门程序二.md │ ├── mybatis学习笔记(4)-开发dao方法.md │ ├── mybatis学习笔记(5)-配置文件.md │ ├── mybatis学习笔记(6)-输入映射.md │ ├── mybatis学习笔记(7)-输出映射.md │ ├── mybatis学习笔记(8)-动态sql.md │ └── mybatis学习笔记(9)-订单商品数据模型分析.md ├── mybatis的mapper返回map结果集.md ├── mybatis的statement的解析与加载.md └── mybatis结果的组装.md ├── mypics ├── 1552756959199.png ├── 20161205164730067.png ├── ByteBuffer 逻辑视图.png ├── ByteBuffer初始化.png ├── CollectedHeap Universecreate_heap.png ├── Java IO vs NIO.png ├── Java IO.jpg ├── Java NIO的核心组件.png ├── KQueueSelectorProvider.jpg ├── Linux进程在虚拟内存中的标准内存段布局.jpg ├── NIO具备的新特性.png ├── NioEndpoint 处理请求具体流程如图.png ├── NioEndpoint处理的的时序图.png ├── ServerSocketServer.jpg ├── _传统数据拷贝过程.jpg ├── act end()逻辑.jpg ├── buffer.compact()调用前.png ├── buffer.compact()调用后.png ├── buffer.rewind.png ├── buffers-modes.png ├── create_heap.png ├── doselect()实现.png ├── flip.png ├── gather.png ├── implRegister().jpg ├── linux2.4+transferTo().jpg ├── nonBlocking IO.jpg ├── overview-channels-buffers.png ├── overview-channels-buffers1.png ├── overview-selectors.png ├── read系统调用原理.gif ├── scatter.png ├── sd可中断IO场景.jpg ├── selector 整体图.jpg ├── sendfile.jpg ├── slice新bytebuffer.png ├── timg.jpg ├── tomcat-Connector.jpg ├── tomcat产生访问时事件流向.jpg ├── transferTo().jpg ├── webflux_backpressure.png ├── 从SocketProcessor开始执行一次请求的时序图.png ├── 内存映射原理.gif ├── 原始ByteBuffer.png ├── 段页式机制Linux.png ├── 用户态与内核态.jpg ├── 系统IO调用01.png └── 系统IO调用02.png ├── mysql ├── MySQL explain执行计划解读.md ├── MySQL主从复制.md ├── MySQL基本概念--数据类型.md ├── MySQL基本概念--索引&索引类型.md ├── MySQL基本概念--锁.md ├── MySQL存储引擎--MyISAM与InnoDB区别.md ├── MySQL数据恢复--binlog.md ├── MySQL详解--锁.md ├── MysqlReport解析.md ├── 《高性能MySQL》读书笔记--MySQL逻辑架构.md ├── 《高性能MySQL》读书笔记--Schema与数据类型优化.md ├── 《高性能MySQL》读书笔记--优化服务器设置.md ├── 《高性能MySQL》读书笔记--多版本并发控制算法.md ├── 《高性能MySQL》读书笔记--查询性能优化.md ├── 《高性能MySQL》读书笔记--查询缓存.md ├── 《高性能MySQL》读书笔记--索引.md ├── 《高性能MySQL》读书笔记--锁、事务、隔离级别.md ├── 影响MySQL性能的五大配置参数.md └── 我必须得告诉大家的MySQL优化原理.md ├── netty ├── 990532-20161224164013807-193335423.png └── ChannelPipeline.md ├── redis ├── Redis 3.2安装及主从复制详细配置.pdf ├── redis3.2 最新版本启动配置文件redis.conf详细说明 .pdf ├── redis在排行榜中的使用总结.md └── redis的面试题.md ├── rpc框架涉及知识点 ├── CopyOnWriteArrayList的详解.md ├── Java里实现链式编程风格.md ├── commons.pool2 对象池的使用.md ├── netty 数据分包、组包、粘包处理机制(部分).md ├── netty 数据分包、组包、粘包处理机制(部分).pdf ├── 通过Lombok来简化你的代码.md └── 通过Lombok来简化你的代码.pdf ├── scala ├── Akka(0):聊聊对Akka的初步了解和想法.md └── Akka(1):Actor - 靠消息驱动的运算器.md ├── spring ├── springmvc学习笔记 │ ├── springmvc学习笔记(1)-框架原理和入门配置.md │ ├── springmvc学习笔记(10)-springmvc注解开发之商品修改功能.md │ ├── springmvc学习笔记(11)-springmvc注解开发之简单参数绑定.md │ ├── springmvc学习笔记(12)-springmvc注解开发之包装类型参数绑定.md │ ├── springmvc学习笔记(13)-springmvc注解开发之集合类型参数绑定.md │ ├── springmvc学习笔记(14)-springmvc校验.md │ ├── springmvc学习笔记(15)-数据回显.md │ ├── springmvc学习笔记(16)-异常处理器.md │ ├── springmvc学习笔记(17)-上传图片.md │ ├── springmvc学习笔记(18)-json数据交互.md │ ├── springmvc学习笔记(19)-RESTful支持.md │ ├── springmvc学习笔记(2)-非注解的处理器映射器和适配器.md │ ├── springmvc学习笔记(20)-拦截器.md │ ├── springmvc学习笔记(21)-springmvc整合mybatis遇到的问题及解决小结.md │ ├── springmvc学习笔记(22)-springmvc开发小结.md │ ├── springmvc学习笔记(3)-注解的处理器映射器和适配器.md │ ├── springmvc学习笔记(4)-前端控制器.md │ ├── springmvc学习笔记(5)-入门程序小结.md │ ├── springmvc学习笔记(6)-springmvc整合mybatis(IDEA中通过maven构建).md │ ├── springmvc学习笔记(7)-springmvc整合mybatis之mapper.md │ ├── springmvc学习笔记(8)-springmvc整合mybatis之service.md │ └── springmvc学习笔记(9)-springmvc整合mybatis之controller.md └── spring的@Transactional注解详细用法.pdf ├── springcloud ├── Spring Cloud源码分析(一)Eureka.md ├── Spring Cloud源码分析(二)Ribbon.md ├── springboot │ ├── Spring Boot的自动配置.md │ ├── SpringBoot配置属性之DataSource.md │ ├── SpringBoot配置属性之MQ.md │ ├── SpringBoot配置属性之MVC.md │ ├── SpringBoot配置属性之Migration.md │ ├── SpringBoot配置属性之NOSQL.md │ ├── SpringBoot配置属性之Security.md │ ├── SpringBoot配置属性之Server.md │ ├── SpringBoot配置属性之其他.md │ └── SpringBoot集成mybatis.md └── 项目研究 │ └── 基于Spring Boot、Spring Cloud、Docker的微服务系统架构实践--PiggyMetrics.md ├── tomcat └── Tomcat中Connector常用配置.md ├── 企业项目开发 ├── README.md ├── 第一章 企业项目开发--maven+springmvc+spring+mybatis+velocity整合.pdf ├── 第七章 企业项目开发--本地缓存guava cache.pdf ├── 第三章 企业项目开发--企业中的项目架构以及多环境分配.pdf ├── 第九章 企业项目开发--分布式缓存Redis(1).pdf ├── 第二章 企业项目开发--maven父子模块.pdf ├── 第五章 企业项目开发--mybatis注解与xml并用.pdf ├── 第八章 企业项目开发--分布式缓存memcached.pdf ├── 第六章 企业项目开发--cookie.pdf ├── 第十一章 企业项目开发--消息队列activemq.pdf ├── 第十章 企业项目开发--分布式缓存Redis(2).pdf └── 第四章 企业项目开发--切分配置文件.pdf ├── 前端 ├── js高级程序设计--阅读笔记.md ├── vue │ ├── Role Based Authentication using Vue.js 2.md │ └── jQuery转Vue项目实践总结.md └── 谷歌开发者工具 │ ├── 安全面板 │ ├── 为什么说 HTTPS 很重要.md │ └── 了解安全问题.md │ └── 控制台面板 │ └── 使用控制台.md ├── 实战经验 ├── Guava 学习.md ├── 基于Github的敏捷开发.md ├── 多线程处理中Future的妙用.md ├── 新商城秒杀系统设计.md └── 校验 │ ├── Hibernate Validation使用示例及讲解.md │ ├── Hibernate validator使用和自定义validator及整合Spring MVC].md │ └── Hibernate-validator校验框架使用.md ├── 并发 ├── Java 线程池框架核心代码分析.pdf ├── ThreadLocal │ ├── ThreadLocal 内存泄露的实例分析.pdf │ └── 深入分析 ThreadLocal 内存泄漏问题.pdf ├── jdk8 版本并发源码解读 │ ├── 第七章 ReentrantLock总结.pdf │ ├── 第三章 CopyOnWriteArrayList源码解析.pdf │ ├── 第二章 ConcurrentHashMap源码分析(JDK8版本).pdf │ ├── 第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock().pdf │ ├── 第六章 ReentrantLock源码解析2--释放锁unlock().pdf │ └── 第四章 CopyOnWriteArraySet源码解析.pdf ├── 访问 NULL 指针错误背后的原理.pdf └── 读书笔记之《Java并发编程的艺术》 │ ├── 读书笔记之《Java并发编程的艺术》-java中的锁.md │ ├── 读书笔记之《Java并发编程的艺术》-并发编程基础.md │ ├── 读书笔记之《Java并发编程的艺术》-并发编程容器和框架(重要).md │ └── 读书笔记之《Java并发编程的艺术》-线程池和Executor的子孙们.md ├── 开源框架源码分析 ├── RocketMQ源码分析系列 │ ├── RocketMQ学习(一):简介和QuickStart.md │ ├── RocketMQ学习(七):消息的生命周期下之消息的消费.md │ ├── RocketMQ学习(三):rocketmq-namesrv介绍.md │ ├── RocketMQ学习(九):顺序消息.md │ ├── RocketMQ学习(二):依赖关系和模块功能介绍.md │ ├── RocketMQ学习(五):Pull和Push.md │ ├── RocketMQ学习(八):事务消息.md │ ├── RocketMQ学习(六):消息的生命周期上之消息的产生.md │ └── RocketMQ学习(四):rocketmq-filtersrv介绍和filter原理.md ├── dubbo源码分析系列.md └── hsweb-easy-orm 开发实践.md ├── 模板引擎 └── FreeMarker模板引擎与动态页面静态化.md ├── 源码 └── ssm学习笔记sourcecode │ ├── learnssm-firstssm │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── iot │ │ │ └── learnssm │ │ │ └── firstssm │ │ │ ├── controller │ │ │ ├── ItemsController.java │ │ │ ├── JsonTest.java │ │ │ ├── LoginController.java │ │ │ ├── MyJsonTest.java │ │ │ └── converter │ │ │ │ ├── CustomDateConverter.java │ │ │ │ └── validation │ │ │ │ ├── ValidGroup1.java │ │ │ │ └── ValidGroup2.java │ │ │ ├── exception │ │ │ ├── CustomException.java │ │ │ └── CustomExceptionResolver.java │ │ │ ├── interceptor │ │ │ ├── HandlerInterceptor1.java │ │ │ ├── HandlerInterceptor2.java │ │ │ └── LoginInterceptor.java │ │ │ ├── mapper │ │ │ ├── ItemsMapper.java │ │ │ ├── ItemsMapperCustom.java │ │ │ ├── OrderdetailMapper.java │ │ │ ├── OrdersMapper.java │ │ │ └── UserMapper.java │ │ │ ├── po │ │ │ ├── Items.java │ │ │ ├── ItemsCustom.java │ │ │ ├── ItemsExample.java │ │ │ ├── ItemsQueryVo.java │ │ │ ├── Orderdetail.java │ │ │ ├── OrderdetailExample.java │ │ │ ├── Orders.java │ │ │ ├── OrdersExample.java │ │ │ ├── User.java │ │ │ └── UserExample.java │ │ │ └── service │ │ │ ├── ItemsService.java │ │ │ └── impl │ │ │ └── ItemsServiceImpl.java │ │ ├── resources │ │ ├── CustomValidationMessages.properties │ │ ├── com │ │ │ └── iot │ │ │ │ └── learnssm │ │ │ │ └── firstssm │ │ │ │ └── mapper │ │ │ │ ├── ItemsMapper.xml │ │ │ │ ├── ItemsMapperCustom.xml │ │ │ │ ├── OrderdetailMapper.xml │ │ │ │ ├── OrdersMapper.xml │ │ │ │ └── UserMapper.xml │ │ ├── db.properties │ │ ├── log4j.properties │ │ ├── mybatis │ │ │ └── sqlMapConfig.xml │ │ └── spring │ │ │ ├── applicationContext-dao.xml │ │ │ ├── applicationContext-service.xml │ │ │ ├── applicationContext-transaction.xml │ │ │ └── springmvc.xml │ │ └── webapp │ │ ├── WEB-INF │ │ ├── jsp │ │ │ ├── error.jsp │ │ │ ├── items │ │ │ │ ├── editItems.jsp │ │ │ │ ├── editItemsQuery.jsp │ │ │ │ └── itemsList.jsp │ │ │ ├── login.jsp │ │ │ └── success.jsp │ │ └── web.xml │ │ ├── js │ │ └── jquery-1.4.4.min.js │ │ └── jsonTest.jsp │ ├── mybatis-generator │ ├── generatorConfig-base.xml │ ├── generatorConfig-business.xml │ ├── generatorConfig.xml │ ├── lib │ │ ├── log4j-1.2.16.jar │ │ ├── mybatis-3.2.3.jar │ │ ├── mybatis-generator-core-1.3.2.jar │ │ ├── mysql-connector-java-5.1.28-bin.jar │ │ └── ojdbc14.jar │ └── src │ │ ├── GeneratorSqlmap.java │ │ └── log4j.properties │ ├── mybatis-spring │ ├── config │ │ ├── db.properties │ │ ├── log4j.properties │ │ ├── mybatis │ │ │ └── SqlMapConfig.xml │ │ ├── spring │ │ │ └── applicationContext.xml │ │ └── sqlmap │ │ │ └── User.xml │ ├── lib │ │ ├── aopalliance-1.0.jar │ │ ├── asm-3.3.1.jar │ │ ├── aspectjweaver-1.6.11.jar │ │ ├── cglib-2.2.2.jar │ │ ├── commons-dbcp-1.2.2.jar │ │ ├── commons-logging-1.1.1.jar │ │ ├── commons-pool-1.3.jar │ │ ├── javassist-3.17.1-GA.jar │ │ ├── jstl-1.2.jar │ │ ├── junit-4.9.jar │ │ ├── log4j-1.2.17.jar │ │ ├── log4j-api-2.0-rc1.jar │ │ ├── log4j-core-2.0-rc1.jar │ │ ├── mybatis-3.2.7.jar │ │ ├── mybatis-spring-1.2.2.jar │ │ ├── mysql-connector-java-5.1.7-bin.jar │ │ ├── slf4j-api-1.7.5.jar │ │ ├── slf4j-log4j12-1.7.5.jar │ │ ├── spring-aop-3.2.0.RELEASE.jar │ │ ├── spring-aspects-3.2.0.RELEASE.jar │ │ ├── spring-beans-3.2.0.RELEASE.jar │ │ ├── spring-context-3.2.0.RELEASE.jar │ │ ├── spring-context-support-3.2.0.RELEASE.jar │ │ ├── spring-core-3.2.0.RELEASE.jar │ │ ├── spring-expression-3.2.0.RELEASE.jar │ │ ├── spring-jdbc-3.2.0.RELEASE.jar │ │ ├── spring-orm-3.2.0.RELEASE.jar │ │ ├── spring-test-3.2.0.RELEASE.jar │ │ ├── spring-tx-3.2.0.RELEASE.jar │ │ ├── spring-web-3.2.0.RELEASE.jar │ │ └── spring-webmvc-3.2.0.RELEASE.jar │ ├── src │ │ └── com │ │ │ └── iot │ │ │ └── ssm │ │ │ ├── dao │ │ │ ├── UserDao.java │ │ │ └── UserDaoImpl.java │ │ │ ├── mapper │ │ │ ├── ItemsMapper.java │ │ │ ├── ItemsMapper.xml │ │ │ ├── UserMapper.java │ │ │ └── UserMapper.xml │ │ │ └── po │ │ │ ├── Items.java │ │ │ ├── ItemsExample.java │ │ │ └── User.java │ └── test │ │ └── com │ │ └── iot │ │ └── ssm │ │ ├── dao │ │ └── UserDaoImplTest.java │ │ └── mapper │ │ ├── ItemsMapperTest.java │ │ └── UserMapperTest.java │ ├── mybatis │ ├── config │ │ ├── SqlMapConfig.xml │ │ ├── db.properties │ │ ├── ehcache.xml │ │ ├── log4j.properties │ │ ├── mapper │ │ │ └── UserMapper.xml │ │ └── sqlmap │ │ │ └── User.xml │ ├── lib │ │ ├── asm-3.3.1.jar │ │ ├── cglib-2.2.2.jar │ │ ├── commons-logging-1.1.1.jar │ │ ├── ehcache-core-2.6.5.jar │ │ ├── javassist-3.17.1-GA.jar │ │ ├── junit-4.9.jar │ │ ├── log4j-1.2.17.jar │ │ ├── log4j-api-2.0-rc1.jar │ │ ├── log4j-core-2.0-rc1.jar │ │ ├── mybatis-3.2.7.jar │ │ ├── mybatis-ehcache-1.0.2.jar │ │ ├── mysql-connector-java-5.1.7-bin.jar │ │ ├── slf4j-api-1.7.5.jar │ │ └── slf4j-log4j12-1.7.5.jar │ ├── src │ │ └── com │ │ │ └── iot │ │ │ └── mybatis │ │ │ ├── dao │ │ │ ├── UserDao.java │ │ │ └── UserDaoImpl.java │ │ │ ├── first │ │ │ └── MybatisFirst.java │ │ │ ├── jdbc │ │ │ └── JdbcTest.java │ │ │ ├── mapper │ │ │ ├── OrdersMapperCustom.java │ │ │ ├── OrdersMapperCustom.xml │ │ │ ├── UserMapper.java │ │ │ └── UserMapper.xml │ │ │ └── po │ │ │ ├── Items.java │ │ │ ├── Orderdetail.java │ │ │ ├── Orders.java │ │ │ ├── OrdersCustom.java │ │ │ ├── User.java │ │ │ ├── UserCustom.java │ │ │ └── UserQueryVo.java │ └── test │ │ └── com │ │ └── iot │ │ └── mybatis │ │ ├── dao │ │ └── UserDaoImplTest.java │ │ └── mapper │ │ ├── OrdersMapperCustomTest.java │ │ └── UserMapperTest.java │ ├── springmvcfirst │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── iot │ │ │ └── ssm │ │ │ ├── controller │ │ │ ├── ItemsController.java │ │ │ └── ItemsController2.java │ │ │ └── po │ │ │ ├── Items.java │ │ │ ├── Orderdetail.java │ │ │ ├── Orders.java │ │ │ └── User.java │ │ ├── resources │ │ └── springmvc.xml │ │ └── webapp │ │ └── WEB-INF │ │ ├── jsp │ │ └── items │ │ │ └── itemsList.jsp │ │ ├── lib │ │ ├── jstl.jar │ │ └── standard.jar │ │ └── web.xml │ ├── springmvcsecond │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── com │ │ │ └── iot │ │ │ └── ssm │ │ │ ├── controller │ │ │ ├── ItemsController.java │ │ │ └── ItemsController3.java │ │ │ └── po │ │ │ ├── Items.java │ │ │ ├── Orderdetail.java │ │ │ ├── Orders.java │ │ │ └── User.java │ │ ├── resources │ │ └── springmvc.xml │ │ └── webapp │ │ └── WEB-INF │ │ ├── jsp │ │ └── items │ │ │ └── itemsList.jsp │ │ ├── lib │ │ ├── jstl.jar │ │ └── standard.jar │ │ └── web.xml │ └── sql │ ├── create.sql │ └── data.sql ├── 神经元坑 └── java shell命令工具类.md ├── 经验总结 ├── Intellij IDEA 神器还有这些小技巧.md ├── static class 静态类详解.md ├── static class 静态类详解.pdf ├── 最佳日志实践 v2.0.md └── 深入Java核心.md ├── 集成测试环境搭建 ├── Jenkins Gitlab持续集成打包平台搭建.md └── 手把手教你搭建Jenkins+Github持续集成环境.md └── 面试 ├── Java面试题全集-社招篇.md ├── database ├── DATABASE.md ├── MySQL_PASS.md ├── MySQL常见问题总结.md ├── MySQL常见问题总结.pdf ├── mysql常用语句大全.md └── mysql语句大全2.md ├── redis面试总结.md ├── select、poll、epoll之间的区别总结[整理].md └── 一致性Hash算法的实现.md /GC/G1收集器.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/G1收集器.pdf -------------------------------------------------------------------------------- /GC/Hotspot VM中Oop Maps的含义?.md: -------------------------------------------------------------------------------- 1 | # Hotspot VM中Oop Maps的含义? 2 | 3 | Oop Maps是记录Java栈中引用对象的数据结构。它的主要作用是发现Java栈中的GC Roots对象,当对象被移动到Java堆中更新该对象的应用。 4 | 5 | 有三种类型的Oop Maps: 6 | 7 | - 解释执行型Oop Maps。采用延迟计算算法,当GC发生时,通过字节码流分析。 8 | - JIT编译型Oop Maps。JIT编译期间被触发,并内置于编译后的代码当中,当对象被引用时VM通过Java栈中的指令快速找出,并进行注册。 9 | - 触发共享运行时副本型Oop Maps。开发者手动创建这些maps-运行时副本的作者。 -------------------------------------------------------------------------------- /GC/JVM中CMS收集器.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/JVM中CMS收集器.pdf -------------------------------------------------------------------------------- /GC/Java 内存结构备忘录.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/Java 内存结构备忘录.pdf -------------------------------------------------------------------------------- /GC/Java值传递的一些理解 .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/Java值传递的一些理解 .pdf -------------------------------------------------------------------------------- /GC/Java服务GC参数调优案例.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/Java服务GC参数调优案例.pdf -------------------------------------------------------------------------------- /GC/Minor GC vs Major GC vs Full GC.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/Minor GC vs Major GC vs Full GC.pdf -------------------------------------------------------------------------------- /GC/java垃圾回收机制.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/java垃圾回收机制.pdf -------------------------------------------------------------------------------- /GC/jvm参数陷阱.md: -------------------------------------------------------------------------------- 1 | # jvm参数陷阱 2 | 3 | ## 序 4 | 5 | 本文主要记录一些jvm参数的使用陷阱。 6 | 7 | ## -XX:MaxTenuringThreshold 8 | 9 | -XX:MaxTenuringThreshold只对串行回收器和ParNew有效,对ParallGC无效。存活次数在串行和ParNew方式中可通过-XX:MaxTenuringThreshold来设置,ParallelScavenge则根据运行状态来决定。 10 | 11 | ## -XX:PretenureSizeThreshold 12 | 13 | -XX:PretenureSizeThreshold,设置大对象直接进入年老代的阈值。-XX:PretenureSizeThreshold只对串行回收器和ParNew有效,对ParallGC无效。默认该值为0,即不指定最大的晋升大小,一切由运行情况决定。 14 | 15 | ## -verbose:gc与-XX:+PrintGC 16 | 17 | -XX:+PrintGC 与 -verbose:gc 是一样的,可以认为-verbose:gc 是 -XX:+PrintGC的别名.-XX:+PrintGCDetails 在启动脚本可以自动开启-XX:+PrintGC , 如果在命令行使用jinfo开启的话,不会自动开启-XX:+PrintGC 18 | 19 | ## -XX:ConcGCThreads并发线程数 20 | 21 | CMS默认启动的并发线程数是(ParallelGCThreads+3)/4。 22 | 23 | 当有4个并行线程时,有1个并发线程;当有5~8个并行线程时,有2个并发线程。 24 | 25 | ParallelGCThreads表示的是GC并行时使用的线程数,如果新生代使用ParNew,那么ParallelGCThreads也就是新生代GC线程数。默认情况下,当CPU数量小于8时,ParallelGCThreads的值就是CPU的数量,当CPU数量大于8时,ParallelGCThreads的值等于3+5*cpuCount/8。 26 | 27 | ParallelGCThreads = (ncpus <= 8) ? ncpus : 3 + ((ncpus * 5) / 8) 28 | 29 | 可以通过-XX:ConcGCThreads或者-XX:ParallelCMSThreads来指定。 30 | 31 | 并发是指垃圾收集器和应用程序交替执行,并行是指应用程序停止,同时由多个线程一起执行GC。因此并行回收器不是并发的。因为并行回收器执行时,应用程序完全挂起,不存在交替执行的步骤。 32 | 33 | ## -XX:+UseCMSInitiatingOccupancyOnly 34 | 35 | 始终基于设定的阈值,不根据运行情况进行调整。 36 | 37 | 如果没有 -XX:+UseCMSInitiatingOccupancyOnly 这个参数, 只有第一次会使用CMSInitiatingPermOccupancyFraction=65 这个值. 后面的情况会自动调整。 38 | 39 | 我们用-XX+UseCMSInitiatingOccupancyOnly标志来命令JVM不基于运行时收集的数据来启动CMS垃圾收集周期。而是,当该标志被开启时,JVM通过CMSInitiatingOccupancyFraction的值进行每一次CMS收集,而不仅仅是第一次。然而,请记住大多数情况下,JVM比我们自己能作出更好的垃圾收集决策。因此,只有当我们充足的理由(比如测试)并且对应用程序产生的对象的生命周期有深刻的认知时,才应该使用该标志。 40 | 41 | ## -XX:CMSInitiatingOccupancyFraction 42 | 43 | 由于CMS收集器不是独占式的回收器,在CMS回收过程中,应用程序仍然在不停地工作。在应用程序工作过程中,又会不断产生垃圾。这些新垃圾在当前CMS回收过程中是无法清除的。同时,因为应用程序没有中断,所以在CMS回收过程中,还应该确保应用程序由足够的内存可用。因此,CMS回收器不会等待堆内存饱和时才进行垃圾回收,而是当堆内存使用率达到某一阈值时便开始进行回收,以确保应用程序在CMS工作中仍然有足够的空间支持应用程序运行。 44 | 45 | -XX:CMSInitiatingOccupancyFraction,默认为68,即当年老代的空间使用率达到68%时,会执行一次CMS回收。如果应用程序的内存使用率增长很快,在CMS的执行过程中,已经出现了内存不足,此时,CMS回收就会失败,虚拟机将启动SerialOld串行收集器进行垃圾回收。如果这样,应用程序将完全中断,直到垃圾回收完成,这时,应用程序的停顿时间可能会较长。 46 | 47 | 因此,根据应用特点,可以对该值进行调优,如果内存增长缓慢,则可以设置一个稍大的值,大的阈值可以有效降低CMS的触发频率,减少年老代回收的次数可以较为明显地改善应用程序性能。 48 | 49 | 反之,如果应用程序内存使用率增长很快,则应该降低这个阈值,以避免频繁触发年老代串行收集器。 50 | 51 | ## CMS相关 52 | 53 | -XX:+UseCMSCompactAtFullCollection:在CMS垃圾收集后,进行一次内存碎片整理。 54 | -XX:CMSFullGCsBeforeCompaction:在进行多少次CMS回收后,进行一次内存压缩。 55 | -XX:+CMSClassUnloadingEnabled,使用CMS回收Perm区 56 | 57 | ## 参考 58 | 59 | - [[HotSpot VM\] JVM调优的"标准参数"的各种陷阱](http://hllvm.group.iteye.com/group/topic/27945) -------------------------------------------------------------------------------- /GC/关于jvm中卡表和写屏障的讨论.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/关于jvm中卡表和写屏障的讨论.pdf -------------------------------------------------------------------------------- /GC/垃圾回收器是什么.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/垃圾回收器是什么.pdf -------------------------------------------------------------------------------- /GC/深入理解JVM.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/深入理解JVM.pdf -------------------------------------------------------------------------------- /GC/细述 Java垃圾回收机制/细述 Java垃圾回收机制→How Java Garbage Collection Works- - Android .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/细述 Java垃圾回收机制/细述 Java垃圾回收机制→How Java Garbage Collection Works- - Android .pdf -------------------------------------------------------------------------------- /GC/细述 Java垃圾回收机制/细述 Java垃圾回收机制→Java Garbage Collection Introduction - Android .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/细述 Java垃圾回收机制/细述 Java垃圾回收机制→Java Garbage Collection Introduction - Android .pdf -------------------------------------------------------------------------------- /GC/细述 Java垃圾回收机制/细述 Java垃圾回收机制→Java Garbage Collection Monitoring and Analysis.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/细述 Java垃圾回收机制/细述 Java垃圾回收机制→Java Garbage Collection Monitoring and Analysis.pdf -------------------------------------------------------------------------------- /GC/细述 Java垃圾回收机制/细述 Java垃圾回收机制→Types of Java Garbage Collectors .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/细述 Java垃圾回收机制/细述 Java垃圾回收机制→Types of Java Garbage Collectors .pdf -------------------------------------------------------------------------------- /GC/调整G1收集器窍门.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/GC/调整G1收集器窍门.pdf -------------------------------------------------------------------------------- /JAVA8/Java中的泛型方法.md: -------------------------------------------------------------------------------- 1 | # Java中的泛型方法 2 | 3 | 泛型是什么意思在这就不多说了,而Java中泛型类的定义也比较简单,例如:public class Test{}。这样就定义了一个泛型类Test,在实例化该类时,必须指明泛型T的具体类型,例如:Test t = new Test();,指明泛型T的类型为Object。 4 | 5 | ​ 但是Java中的泛型方法就比较复杂了。 6 | 7 | ​ 泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型。 8 | 9 | 10 | 11 | ​ **定义泛型方法**语法格式如下: 12 | 13 | ![img](http://images.cnitblog.com/blog/471788/201304/09221852-b0d764f4340946baa1a063da5a0d993e.png) 14 | 15 | ​ 16 | 17 | ​ **调用泛型方法**语法格式如下: 18 | 19 | ![img](http://images.cnitblog.com/blog/471788/201304/09222350-5e3bf238febe4b2ebba99973c69e0054.png) 20 | 21 | 22 | 23 | ​ 说明一下,定义泛型方法时,必须在返回值前边加一个,来声明这是一个泛型方法,持有一个泛型T,然后才可以用泛型T作为方法的返回值。 24 | 25 | ​ Class的作用就是指明泛型的具体类型,而Class类型的变量c,可以用来创建泛型类的对象。 26 | 27 | ​ 为什么要用变量c来创建对象呢?既然是泛型方法,就代表着我们不知道具体的类型是什么,也不知道构造方法如何,因此没有办法去new一个对象,但可以利用变量c的newInstance方法去创建对象,也就是利用反射创建对象。 28 | 29 | ​ 泛型方法要求的参数是Class类型,而Class.forName()方法的返回值也是Class,因此可以用Class.forName()作为参数。其中,forName()方法中的参数是何种类型,返回的Class就是何种类型。在本例中,forName()方法中传入的是User类的完整路径,因此返回的是Class类型的对象,因此调用泛型方法时,变量c的类型就是Class,因此泛型方法中的泛型T就被指明为User,因此变量obj的类型为User。 30 | 31 | ​ 当然,泛型方法不是仅仅可以有一个参数Class,可以根据需要添加其他参数。 32 | 33 | ​ 为什么要使用泛型方法呢?因为泛型类要在实例化的时候就指明类型,如果想换一种类型,不得不重新new一次,可能不够灵活;而泛型方法可以在调用的时候指明类型,更加灵活。 34 | 35 | -------------------------------------------------------------------------------- /Java集合类详解/第一章 Java常用集合类总览.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Java集合类详解/第一章 Java常用集合类总览.pdf -------------------------------------------------------------------------------- /Java集合类详解/第三章 LinkedList源码解析.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Java集合类详解/第三章 LinkedList源码解析.pdf -------------------------------------------------------------------------------- /Java集合类详解/第二章 ArrayList源码解析.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Java集合类详解/第二章 ArrayList源码解析.pdf -------------------------------------------------------------------------------- /Linux/1 计算机;GPL等开源协议;Linux 哲学思想的炼成;MBR & GPT.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/1 计算机;GPL等开源协议;Linux 哲学思想的炼成;MBR & GPT.pdf -------------------------------------------------------------------------------- /Linux/Mariadb/Mariadb数据库备份恢复系列(一):mysqldump逻辑备份工具实战.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/Mariadb/Mariadb数据库备份恢复系列(一):mysqldump逻辑备份工具实战.pdf -------------------------------------------------------------------------------- /Linux/Mariadb/Mariadb数据库备份恢复系列(三):xtrabackup物理备份工具之增量备份.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/Mariadb/Mariadb数据库备份恢复系列(三):xtrabackup物理备份工具之增量备份.pdf -------------------------------------------------------------------------------- /Linux/Mariadb/Mariadb数据库备份恢复系列(二):xtrabackup物理备份工具之完全备份.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/Mariadb/Mariadb数据库备份恢复系列(二):xtrabackup物理备份工具之完全备份.pdf -------------------------------------------------------------------------------- /Linux/Mariadb/Mariadb数据库复制系列(一):主从复制.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/Mariadb/Mariadb数据库复制系列(一):主从复制.pdf -------------------------------------------------------------------------------- /Linux/Mariadb/Mariadb数据库复制系列(三):半同步复制.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/Mariadb/Mariadb数据库复制系列(三):半同步复制.pdf -------------------------------------------------------------------------------- /Linux/Mariadb/Mariadb数据库复制系列(二):主主复制.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/Mariadb/Mariadb数据库复制系列(二):主主复制.pdf -------------------------------------------------------------------------------- /Linux/Mariadb/Mariadb数据库复制系列(五):基于SSL的复制.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/Mariadb/Mariadb数据库复制系列(五):基于SSL的复制.pdf -------------------------------------------------------------------------------- /Linux/Mariadb/Mariadb数据库复制系列(四):复制过滤器的实现.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/Mariadb/Mariadb数据库复制系列(四):复制过滤器的实现.pdf -------------------------------------------------------------------------------- /Linux/Mariadb/corosync+pacemaker对mariadb实现高可用.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/Mariadb/corosync+pacemaker对mariadb实现高可用.pdf -------------------------------------------------------------------------------- /Linux/ansible配置详解.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/Linux/ansible配置详解.pdf -------------------------------------------------------------------------------- /NIO/01 Java的NIO概述.md: -------------------------------------------------------------------------------- 1 | # 01 Java的NIO概述 2 | 3 | 4 | 5 | ## NIO的核心组成部分 6 | 7 | 1. Channel 8 | 2. Buffers 9 | 3. Selectors 10 | 11 | ## Channel和Buffer 12 | 13 | 基本上,所有的IO在NIO中都从一个Channel开始。Channel有点象流。数据可以从Channel读到Buffer中,也可以从Buffer写到Channel中。这里有个图示: 14 | 15 | ![](https://github.com/muyinchen/woker/blob/master/mypics/overview-channels-buffers.png?raw=true) 16 | 17 | 18 | Channel和Buffer有好几种类型。下面是JAVA NIO中的一些主要Channel的实现: 19 | - FileChannel 20 | - DatagramChannel 21 | - SocketChannel 22 | - ServerSocketChannel 23 | 24 | 正如你所看到的,这些通道涵盖了UDP 和 TCP 网络IO,以及文件IO。 25 | 26 | 27 | 以下是Java NIO里关键的Buffer实现: 28 | 29 | - ByteBuffer 30 | - CharBuffer 31 | - DoubleBuffer 32 | - FloatBuffer 33 | - IntBuffer 34 | - LongBuffer 35 | - ShortBuffer 36 | 37 | 这些Buffer覆盖了你能通过IO发送的基本数据类型:byte, short, int, long, float, double 和 char。 38 | 39 | Java NIO 还有个 MappedByteBuffer,用于表示内存映射文件. 40 | 41 | ## Selector 42 | Selector允许单线程处理多个 Channel。如果你的应用打开了多个连接(通道),但每个连接的流量都很低,使用Selector就会很方便。例如,在一个聊天服务器中。 43 | 44 | 这是在一个单线程中使用一个Selector处理3个Channel的图示: 45 | 46 | ![](https://github.com/muyinchen/woker/blob/master/mypics/overview-selectors.png?raw=true) 47 | 48 | 49 | 要使用Selector,得向Selector注册Channel,然后调用它的select()方法。这个方法会一直阻塞到某个注册的通道有事件就绪。一旦这个方法返回,线程就可以处理这些事件,事件的例子有如新连接进来,数据接收等。 50 | 51 | -------------------------------------------------------------------------------- /NIO/02 Java的NIO之Channel通道.md: -------------------------------------------------------------------------------- 1 | # 02 Java的NIO之Channel通道 2 | 3 | 4 | 5 | ## 1.Channel 通道的简介 6 | 7 | java的NIO的通道类似流,但是又有一些不同: 8 | 9 | - 既可以从Channel中读数据也可以往Channel里面写数据;但是流的读写一般是单向的。 10 | - Channel可以异步的读写; 11 | - Channel的读写是通过Buffer这个中介实现的。数据总是要先读到一个Buffer,或者总是要从一个Buffer中写入。如下图所示: 12 | 13 | ![](https://github.com/muyinchen/woker/blob/master/mypics/overview-channels-buffers.png?raw=true) 14 | 15 | 引用一段关于描述Channel的文字: 16 | 17 | > 其中Channel对应以前的流,Buffer不是什么新东西,Selector是因为NIO可以使用异步的非堵塞模式才加入的东西。 18 | > 19 | > 以前的流总是堵塞的,一个线程只要对它进行操作,其它操作就会被堵塞,也就相当于水管没有阀门,你伸手接水的时候,不管水到了没有,你就都只能耗在接水(流)上。 20 | > 21 | > NIO的Channel的加入,相当于增加了水龙头(有阀门),虽然一个时刻也只能接一个水管的水,但依赖轮换策略,在水量不大的时候,各个水管里流出来的水,都可以得到妥善接纳,这个关键之处就是增加了一个接水工,也就是Selector,他负责协调,也就是看哪根水管有水了的话,在当前水管的水接到一定程度的时候,就切换一下:临时关上当前水龙头,试着打开另一个水龙头(看看有没有水)。 22 | > 23 | > 当其他人需要用水的时候,不是直接去接水,而是事前提了一个水桶给接水工,这个水桶就是Buffer。也就是,其他人虽然也可能要等,但不会在现场等,而是回家等,可以做其它事去,水接满了,接水工会通知他们。 24 | > 这其实也是非常接近当前社会分工细化的现实,也是统分利用现有资源达到并发效果的一种很经济的手段,而不是动不动就来个并行处理,虽然那样是最简单的,但也是最浪费资源的方式。 25 | > 上面的比方还是相当清晰的描述了Channel、Buffer和Selector的作用。 26 | 27 | ## 2.Channel的最重要的几个实现以及使用场景 28 | 29 | 下面是Java的NIO的最重要的几个channel的实现: 30 | 31 | 1. FileChannel 主要是用于文件的读写 32 | 33 | 2. DatagramChannel 主要用于UDP读写网络中的数据 34 | 35 | 3. SocketChannel 通过TCP读写网络中的数据。 36 | 37 | 4. ServerSocketChannel 主要用于服务端:可以监听新进来的TCP连接,像Web服务器那样。对每一个新进来的连接都会创建一个SocketChannel。 38 | 39 | 40 | 41 | ## 3. 一个FileChannel的基本实例; 42 | 43 | ``` java 44 | RandomAccessFile accessFile = new RandomAccessFile("data.txt", "rw"); 45 | FileChannel inchannel = accessFile.getChannel();//获取 FileChannel 46 | 47 | ByteBuffer buffer = ByteBuffer.allocate(48);//申请48字节的缓冲区 48 | 49 | int bytesRead = inchannel.read(buffer);// 读取数据放入缓冲区 50 | 51 | while(bytesRead != -1){ 52 | System.out.println("read " + bytesRead); 53 | Thread.sleep(500); 54 | buffer.flip(); 55 | bytesRead=-1; 56 | } 57 | while(buffer.hasRemaining()){ 58 | System.out.print((char) buffer.get()); 59 | } 60 | buffer.clear(); 61 | bytesRead = inchannel.read(buffer); 62 | accessFile.close(); 63 | ``` 64 | -------------------------------------------------------------------------------- /NIO/03 NIO中的heap Buffer和direct Buffer区别.md: -------------------------------------------------------------------------------- 1 | # 03 NIO中的heap Buffer和direct Buffer区别 2 | 3 | ## heap buffer 和 direct buffer区别 4 | 5 | 在Java的NIO中,我们一般采用ByteBuffer缓冲区来传输数据,一般情况下我们创建Buffer对象是通过ByteBuffer的两个静态方法: 6 | 7 | ```java 8 | 9 | ByteBuffer.allocate(int capacity); 10 | ByteBuffer.wrap(byte[] array); 11 | 12 | ``` 13 | 14 | 查看JDK的NIO的源代码关于这两个部分: 15 | 16 | ```java 17 | /**allocate()函数的源码**/ 18 | public static ByteBuffer allocate(int capacity) { 19 | if (capacity < 0) 20 | throw new IllegalArgumentException(); 21 | return new HeapByteBuffer(capacity, capacity); 22 | } 23 | 24 | /**wrap()函数的源码**/ 25 | public static ByteBuffer wrap(byte[] array) { 26 | return wrap(array, 0, array.length); 27 | } 28 | // 29 | public static ByteBuffer wrap(byte[] array, 30 | int offset, int length) 31 | { 32 | try { 33 | return new HeapByteBuffer(array, offset, length); 34 | } catch (IllegalArgumentException x) { 35 | throw new IndexOutOfBoundsException(); 36 | } 37 | } 38 | 39 | ``` 40 | 我们可以很清楚的发现,这两个方法都是实例化HeapByteBuffer来创建的ByteBuffer对象,也就是heap buffer. 其实除了heap buffer以外还有一种buffer,叫做direct buffer。我们也可以创建这一种buffer,通过ByteBuffer.allocateDirect(int capacity)方法,查看JDK源码如下: 41 | 42 | ``` java 43 | public static ByteBuffer allocateDirect(int capacity) { 44 | return new DirectByteBuffer(capacity); 45 | } 46 | ``` 47 | 我们发现该函数调用的是DirectByteBuffer(capacity)这个类,这个类就是创建了direct buffer。 48 | 49 | ## 那么heap buffer和direct buffer有什么区别呢? 50 | 51 | 首先解释一下两者的区别: 52 | 53 | heap buffer这种缓冲区是分配在堆上面的,直接由Java虚拟机负责垃圾回收,可以直接想象成一个字节数组的包装类。 54 | 55 | direct buffer则是通过JNI在Java的虚拟机外的内存中分配了一块缓冲区(所以即使在运行时通过-Xmx指定了Java虚拟机的最大堆内存,还是可以实例化超出该大小的Direct ByteBuffer),该块并不直接由Java虚拟机负责垃圾回收收集,但是在direct buffer包装类被回收时,会通过Java Reference机制来释放该内存块。(但Direct Buffer的JAVA对象是归GC管理的,只要GC回收了它的JAVA对象,操作系统才会释放Direct Buffer所申请的空间) 56 | 57 | 两者各有优劣势:direct buffer对比 heap buffer: 58 | 59 | 劣势:创建和释放Direct Buffer的代价比Heap Buffer得要高; 60 | 61 | 优势:当我们把一个Direct Buffer写入Channel的时候,就好比是“内核缓冲区”的内容直接写入了Channel,这样显然快了,减少了数据拷贝(因为我们平时的read/write都是需要在I/O设备与应用程序空间之间的“内核缓冲区”中转一下的)。而当我们把一个Heap Buffer写入Channel的时候,实际上底层实现会先构建一个临时的Direct Buffer,然后把Heap Buffer的内容复制到这个临时的Direct Buffer上,再把这个Direct Buffer写出去。当然,如果我们多次调用write方法,把一个Heap Buffer写入Channel,底层实现可以重复使用临时的Direct Buffer,这样不至于因为频繁地创建和销毁Direct Buffer影响性能。 62 | 63 | 结论:Direct Buffer创建和销毁的代价很高,所以要用在尽可能重用的地方。 比如周期长传输文件大采用direct buffer,不然一般情况下就直接用heap buffer 就好。 64 | -------------------------------------------------------------------------------- /NIO/05 Java的NIO之Scatter和Gather.md: -------------------------------------------------------------------------------- 1 | # 05 Java的NIO之Scatter和Gather 2 | 3 | Java的NIO开始支持scatter/gather,scatter/gather用于描述从channel中读取数据或则写入数据到channel的操作: 4 | 5 | > 分散(scatter) 从Channel中读取是指在读操作时将读取的数据写入多个buffer中。因此,Channel将从Channel中读取的数据“分散(scatter)”到多个Buffer中。 6 | > 7 | > 聚集(gather)写入Channel是指在写操作时将多个buffer的数据写入同一个Channel,因此,Channel 将多个Buffer中的数据“聚集(gather)”后发送到Channel。 8 | > 9 | 10 | scatter / gather经常用于需要将传输的数据分开处理的场合,例如传输一个由消息头和消息体组成的消息,你可能会将消息体和消息头分散到不同的buffer中,这样你可以方便的处理消息头和消息体。 11 | 12 | ## 5.1 Scattering读数据 13 | Scatter是指从一个channel读取数据到多个buffer中。如下图描述: 14 | 15 | ![](https://github.com/muyinchen/woker/blob/master/mypics/scatter.png?raw=true) 16 | 17 | 示例代码如下: 18 | ```java 19 | ByteBuffer header = ByteBuffer.allocate(128); 20 | ByteBuffer body = ByteBuffer.allocate(1024); 21 | ByteBuffer[] bufferArray = { header, body }; 22 | channel.read(bufferArray); 23 | ``` 24 | 注意buffer首先被插入到数组,然后再将数组作为channel.read() 的输入参数。read()方法按照buffer在数组中的顺序将从channel中读取的数据写入到buffer,当一个buffer被写满后,channel紧接着向另一个buffer中写。 25 | 26 | Scattering Reads在移动下一个buffer前,必须填满当前的buffer,这也意味着它不适用于动态消息(译者注:消息大小不固定)。换句话说,如果存在消息头和消息体,消息头必须完成填充(例如 128byte),Scattering Reads才能正常工作。 27 | 28 | ## 5.2 Gather写入数据到channel 29 | Gather是指数据从多个buffer写入到同一个channel。如下图描述: 30 | 31 | ![](https://github.com/muyinchen/woker/blob/master/mypics/gather.png?raw=true) 32 | 33 | 34 | 示例代码如下: 35 | ```java 36 | ByteBuffer header = ByteBuffer.allocate(128); 37 | ByteBuffer body = ByteBuffer.allocate(1024); 38 | //write data into buffers 39 | ByteBuffer[] bufferArray = { header, body }; 40 | channel.write(bufferArray); 41 | ``` 42 | buffers数组是write()方法的入参,write()方法会按照buffer在数组中的顺序,将数据写入到channel,注意只有position和limit之间的数据才会被写入。因此,如果一个buffer的容量为128byte,但是仅仅包含58byte的数据,那么这58byte的数据将被写入到channel中。因此与Scattering Reads相反,Gathering Writes能较好的处理动态消息。 43 | -------------------------------------------------------------------------------- /NIO/06 Java的NIO之不同channel之间传输数据.md: -------------------------------------------------------------------------------- 1 | # 06 Java的NIO之不同channel之间传输数据 2 | 3 | ## 不同通道channel之间传输数据 4 | 在Java的NIO中,如果两个通道中有一个是FileChannel,那么我们可以直接将数据从一个channel传输到另外一个channel中。两个通道之间传输数据的方式有两种,分别是: 5 | - transferFrom() 6 | - transferTo() 7 | 8 | ## 6.1 transferFrom() 9 | FileChannel 的transferFrom()方法可以将数据从源通道传输到FileChannel中(这个方法在JDK文档中解释为将字节从给定的可读取字节通道传输到此通道的文件中)。下面是一个简单的例子: 10 | ``` java 11 | RandomAccessFile fromFile = new RandomAccessFile("fromFile.txt", "rw"); 12 | FileChannel fromChannel = fromFile.getChannel();//获取source的通道; 13 | 14 | RandomAccessFile toFile = new RandomAccessFile("toFile.txt", "rw"); 15 | FileChannel toChannel = toFile.getChannel();//获取dest的通道; 16 | 17 | long position = 0; 18 | long count = fromChannel.size(); 19 | 20 | long result = toChannel.transferFrom(fromChannel, position, count); 21 | 22 | LogUtil.log_debug(""+result); 23 | ``` 24 | 方法的输入参数 25 | - position表示从position处开始向目标文件写入数据, 26 | - count表示最多传输的字节数。如果源通道的剩余空间小于count个字节,则所传输的字节数要小于请求的字节数。 27 | 28 | 此外要注意,在SoketChannel的实现中,SocketChannel只会传输此刻准备好的数据(可能不足count字节)。因此,SocketChannel可能不会将请求的所有数据(count个字节)全部传输到FileChannel中。 29 | 30 | ## 6.2 transferTo()方法 31 | transferTo()方法将数据从FileChannel传输到其他的channel中。下面是一个简单的例子: 32 | ``` java 33 | RandomAccessFile fromFile = new RandomAccessFile("fromFile.txt", "rw"); 34 | FileChannel fromChannel = fromFile.getChannel();//获取source的通道; 35 | 36 | RandomAccessFile toFile = new RandomAccessFile("toFile.txt", "rw"); 37 | FileChannel toChannel = toFile.getChannel();//获取dest的通道; 38 | 39 | long position = 0; 40 | long count = fromChannel.size(); 41 | long result = fromChannel.transferTo(position, count, toChannel); 42 | LogUtil.log_debug(""+result); 43 | ``` 44 | 观察一下就可以发现,其实这两个例子其实非常的相似,如果仅仅从文件IO的角度来看,就是两个文件之间的数据复制; 45 | 46 | 上面所说的关于SocketChannel的问题在transferTo()方法中同样存在。SocketChannel会一直传输数据直到目标buffer被填满。 47 | -------------------------------------------------------------------------------- /NIO/07 Java的NIO之FileChannel.md: -------------------------------------------------------------------------------- 1 | # 07 Java的NIO之FileChannel 2 | 3 | ## FileChannel文件通道 4 | Java的NIO中的FileChannel是一个连接到文件的通道,文件可以通过这个通道来进行读写操作。 5 | 6 | 值得注意的是:FileChannel无法设置成非阻塞模式,它总是工作在阻塞模式下。 7 | 8 | 下面介绍一下FileChannel的用法: 9 | 10 | ## 7.1 打开一个FileChannel 11 | 在使用FileChannel之前我们必须先打开一个FileChannel;但是我们无法直接打开一个FileChannel,必须通过使用一个InputStream、OutputStream或则是RandomAccessFile来获取到FileChannel实例。我们在前面的内容中,我们已经多次用到了通过RandomAccessFile对象来获取FileChannel实例,下面再次重复的给出一个示例,加强理解; 12 | ``` java 13 | RandomAccessFile fromFile = new RandomAccessFile("fromFile.txt", "rw"); 14 | FileChannel fromChannel = fromFile.getChannel();//获取source的通道; 15 | ``` 16 | ## 7.2 从FileChannel通道中读取数据 17 | 通过在channel上面调用read()方法,就可以从file channel中读取数据,比如如下例子所示: 18 | ``` java 19 | ByteBuffer buffer = ByteBuffer.allocate(100); 20 | int bytesRead = inChannel.read(buffer); 21 | ``` 22 | 上面的代码:首先分配一个100个字节的buffer,然后调用read()方法从channel中读取数据放入buffer中。read()方法将返回的int值表示有多少个字节被读入到了Buffer中。如果返回-1就表示到了文件末尾。 23 | 24 | ## 7.3 向FileChannel中写入数据: 25 | 使用FileChannel的write()方法向FileChannel中写数据,该方法的参数也是一个buffer。 26 | ``` java 27 | String newData = "New String to write to file..." + System.currentTimeMillis(); 28 | 29 | ByteBuffer buf = ByteBuffer.allocate(48); 30 | buf.clear(); 31 | buf.put(newData.getBytes()); 32 | 33 | buf.flip(); 34 | 35 | while(buf.hasRemaining()) { 36 | channel.write(buf); 37 | } 38 | ``` 39 | 注意FileChannel.write()是在while循环中调用的。因为无法保证write()方法一次能向FileChannel写入多少字节,因此需要重复调用write()方法,直到Buffer中已经没有尚未写入通道的字节。 40 | 41 | ## 7.4 关闭FileChannel 42 | 用完了FileChannel后必须将其关闭: 43 | ``` java 44 | channel.close(); 45 | ``` 46 | ## 7.5 FileChannel的position方法: 47 | 有时候我们可能需要对FileChannle中特定的位置进行读写操作,这时我们首先要获取FileChannel的位置,position()函数可以返回FileChannel的当前位置:此外,我们也可以调用position(long pos)来设置FileChannel的当前位置。 48 | 49 | 下面通过两个例子来说明: 50 | ``` java 51 | long pos = channel.position(); 52 | channel.position(pos +123); 53 | ``` 54 | 这里如果将position设置在了文件结束符之后,然后从文件通道里面读数据,read()方法将返回-1,标志文件结束; 55 | 56 | 这里如果将position设置在了文件结束符之后,然后向文件通道写数据,文件将撑大到当前位置并写入数据。这可能导致“文件空洞”,磁盘上物理文件中写入的数据间有空隙。 57 | 58 | ## 7.6 FileChannel的size()方法 59 | FileChannel实例的size()方法将返回该实例所关联文件的大小。使用如下例: 60 | ``` java 61 | long fileSize = channel.size(); 62 | ``` 63 | ## 7.7 FileChannel的truncate方法截取文件: 64 | 可以使用FileChannel.truncate()方法截取一个文件。截取文件时,文件指定长度后面的部分将被删除。如: 65 | ``` java 66 | channel.truncate(1024); 67 | ``` 68 | 这个例子截取文件的前1024个字节。 69 | 70 | ## 7.8 FileChannel的force方法 71 | FileChannel.force()方法将通道里尚未写入磁盘的数据强制写到磁盘上。出于性能方面的考虑,操作系统会将数据缓存在内存中,所以无法保证写入到FileChannel里的数据一定会即时写到磁盘上。要保证这一点,需要调用force()方法。 72 | 73 | force()方法有一个boolean类型的参数,指明是否同时将文件元数据(权限信息等)写到磁盘上。 74 | 75 | 下面的例子同时将文件数据和元数据强制写到磁盘上: 76 | ``` java 77 | channel.force(true); 78 | ``` -------------------------------------------------------------------------------- /NIO/08 Java的NIO之网络通信的SocketChannel.md: -------------------------------------------------------------------------------- 1 | # 08 Java的NIO之网络通信的SocketChannel 2 | 3 | Java的NIO中的SocketChannel是一个连接到TCP网络套接字的通道(SocketChannel这个通道一般用于客户端,服务端一般使用ServerSocketChannel)。可以通过以下2种方式创建SocketChannel: 4 | 1. 打开一个SocketChannel并连接到互联网的某台服务器上。 5 | 2. 一个新的连接到达ServerSocketChannel时,server端会创建一个SocketChannel。 6 | 7 | 下面分节讲解一下SocketChannel的用法: 8 | 9 | ## 8.1 打开SocketChannel: 10 | 下面是SocketChanel打打开方式: 11 | ``` java 12 | SocketChannel socketChannel = SocketChannel.open(); 13 | //这里必须填写域名才能正确返回 14 | boolean result = socketChannel.connect(new InetSocketAddress("120.25.12.92", 80)); 15 | LogUtil.log_debug(""+result); 16 | socketChannel.close(); 17 | ///~output 18 | // true 19 | ``` 20 | ## 8.2 关闭SocketChannel 21 | 我们要养成良好的习惯,用完了通道之后一定要记得关闭,释放资源。关闭SocketChannel通过调用SocketChannel.close()实现。 22 | 23 | ## 8.3 从SocketChannel中读取数据 24 | 要从SocketChannel中读取数据,调用一个read()方法,下面是一个示例。 25 | ``` java 26 | ByteBuffer buffer = ByteBuffer.allocate(1024); 27 | int bytesRead = socketChannel.read(buffer); 28 | ``` 29 | 上面的代码首先分配了一个Buffer,然后调用SocketChannel.read()方法从channel中读取到的数据存放进这个Buffer中。read()方法的返回值表示读了多少字节进Buffer里。如果返回的是-1,表示已经读到了流的末尾(连接关闭了)。 30 | 31 | ## 8.4 写入SocketChannel 32 | 写数据到SocketChannel用的是SocketChannel.write()方法,该方法以一个Buffer作为参数。示例如下: 33 | ``` java 34 | String newData = "New String to write to file..." + System.currentTimeMillis(); 35 | 36 | ByteBuffer buffer = ByteBuffer.allocate(48); 37 | buffer.clear(); 38 | buffer.put(newData.getBytes()); 39 | 40 | buffer.flip();//把buffer切换到读模式,将buffer中数据读出来然后写入通道 41 | 42 | while(buffer.hasRemaining()) { 43 | channel.write(buffer); 44 | } 45 | ``` 46 | ## 8.5 非阻塞模式 47 | 可以设置 SocketChannel 为非阻塞模式(non-blocking mode).设置之后,就可以在异步模式下调用connect(), read() 和write()了。 48 | 49 | ### connect() 50 | 51 | 如果SocketChannel在非阻塞模式下,此时调用connect(),该方法可能在连接建立之前就返回了。为了确定连接是否建立,可以调用finishConnect()的方法。像这样: 52 | ``` java 53 | socketChannel.configureBlocking(false); 54 | socketChannel.connect(new InetSocketAddress("120.25.12.92", 80)); 55 | 56 | while(! socketChannel.finishConnect() ){ 57 | //wait, or do something else... 58 | } 59 | ``` 60 | ### write() 61 | 62 | 非阻塞模式下,write()方法在尚未写出任何内容时可能就返回了。所以需要在循环中调用write()。前面已经有例子了,这里就不赘述了。 63 | 64 | ### read() 65 | 66 | 非阻塞模式下,read()方法在尚未读取到任何数据时可能就返回了。所以需要关注它的int返回值,它会告诉你读取了多少字节。 67 | 68 | ## 8.6 非阻塞模式与选择器 69 | 非阻塞模式与选择器搭配会工作的更好,通过将一或多个SocketChannel注册到Selector,可以询问选择器哪个通道已经准备好了读取,写入等 70 | -------------------------------------------------------------------------------- /NIO/09 Java的NIO之服务端的ServerSocketChannel的使用.md: -------------------------------------------------------------------------------- 1 | # 09 Java的NIO之服务端的ServerSocketChannel的使用 2 | 3 | ## ServerSocketChannel 4 | Java的NIO中的ServerSocketChannel是一个可以监听新进来的TCP连接的通道, 就像标准IO中的ServerSocket一样。所以不难想象ServerSocketChannel是运行在服务端的。ServerSocketChannel类在java.nio.channels包中。 5 | 6 | 下面有个简单的例子: 7 | ``` java 8 | ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); 9 | serverSocketChannel.socket().bind(new InetSocketAddress(9999)); 10 | while(true){ 11 | SocketChannel socketChannel = 12 | serverSocketChannel.accept(); 13 | //do something with socketChannel... 14 | } 15 | ``` 16 | ## 9.1 打开ServerSocketChannel 17 | 通过调用ServerSocketChannel.open()方法来打开ServerSocketChannel.如: 18 | ``` java 19 | ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); 20 | ``` 21 | ## 9.2 关闭ServerSocketChannel 22 | 通过调用ServerSocketChannel.close() 方法来关闭ServerSocketChannel. 23 | 24 | ## 9.3 监听新进来的连接 25 | 通过ServerSocketChannel.accept()方法监听新进来的连接。当 accept()方法返回的时候,它返回一个包含新进来的连接的SocketChannel。因此, accept()方法会一直阻塞到有新连接到达。 26 | 27 | 通常不会仅仅只监听一个连接,在while循环中调用 accept()方法. 如下面的例子: 28 | ``` java 29 | while(true){ 30 | SocketChannel socketChannel = 31 | serverSocketChannel.accept(); 32 | //do something with socketChannel... 33 | 34 | } 35 | ``` 36 | 当然,也可以在while循环中使用除了true以外的其它退出准则。 37 | 38 | ## 9.4 非阻塞工作模式: 39 | ServerSocketChannel可以设置成非阻塞模式。在非阻塞模式下,accept() 方法会立刻返回,如果还没有新进来的连接,返回的将是null。 因此,需要检查返回的SocketChannel是否是null.如: 40 | ``` java 41 | ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); 42 | 43 | serverSocketChannel.socket().bind(new InetSocketAddress(8080)); 44 | serverSocketChannel.configureBlocking(false); 45 | 46 | while(true){ 47 | SocketChannel socketChannel = 48 | serverSocketChannel.accept(); 49 | 50 | if(socketChannel != null){ 51 | //do something with socketChannel... 52 | } 53 | } 54 | ``` -------------------------------------------------------------------------------- /NIO/10 Java的NIO之用于UDP的DatagramChannel.md: -------------------------------------------------------------------------------- 1 | # 10 Java的NIO之用于UDP的DatagramChannel 2 | Java NIO中的DatagramChannel是一个能 收发 UDP包的通道。因为UDP是无连接的网络协议,所以不能像其它通道那样读取和写入。它发送和接收的是数据包。 3 | 4 | ## 10.1 打开 DatagramChannel 5 | 下面是打开DatagramChannel的方式: 6 | ``` java 7 | DatagramChannel channel = DatagramChannel.open(); 8 | channel.socket().bind(new InetSocketAddress(8000)); 9 | ``` 10 | 这个例子打开的 DatagramChannel可以在UDP端口8000上接收数据包。 11 | 12 | ## 10.2 接收数据 13 | 通过receive()方法从DatagramChannel接收数据,如: 14 | ``` java 15 | ByteBuffer buffer = ByteBuffer.allocate(100); 16 | buffer.clear(); 17 | channel.receive(buffer); 18 | ``` 19 | receive()方法会将接收到的数据包内容复制到指定的Buffer. 如果Buffer容不下收到的数据,多出的数据将被丢弃。 20 | 21 | ## 10.3 发送数据 22 | 通过send()方法从DatagramChannel发送数据,如: 23 | ``` java 24 | String newData = "New String to write to file..." + System.currentTimeMillis(); 25 | 26 | ByteBuffer buffer = ByteBuffer.allocate(100); 27 | buffer.clear(); 28 | buffer.put(newData.getBytes()); 29 | buffer.flip();//将buffer切换到读模式 30 | 31 | int bytesSent = channel.send(buffer, new InetSocketAddress("120.25.12.92", 80)); 32 | ``` 33 | 这个例子发送一串字符到”120.25.12.92”服务器的UDP端口80。 因为服务端并没有监控这个端口,所以什么也不会发生。也不会通知你发出的数据包是否已收到,因为UDP在数据传送方面没有任何保证。 34 | 35 | ## 10.4 将DatagramChannel通道连接到特定的地址 36 | 可以将DatagramChannel“连接”到网络中的特定地址的。由于UDP是无连接的,连接到特定地址并不会像TCP通道那样创建一个真正的连接。而是锁住DatagramChannel ,让其只能从特定地址收发数据。 37 | 38 | 下面是个示例: 39 | ``` java 40 | channel.connect(new InetSocketAddress("120.25.12.92", 80)); 41 | ``` 42 | 当连接后,也可以使用read()和write()方法,就像在用传统的通道一样。只是在数据传送方面没有任何保证。这里有几个例子: 43 | ``` java 44 | int bytesRead = channel.read(buffer); 45 | int bytesWritten = channel.write(but); 46 | ``` -------------------------------------------------------------------------------- /NIO/Java的NIO与IO的区别.md: -------------------------------------------------------------------------------- 1 | # Java的NIO与IO的区别 2 | 3 | NIO是JDK1.4引入的异步IO,NIO核心部分就是三点: 4 | 5 | Channel 6 | Buffer 7 | Selector 8 | 9 | ### NIO与IO对比 10 | 11 | NIO与IO的区别,总体上来说体现在三个方面: 12 | 13 | - IO 基于流(Stream oriented), 而 NIO 基于 Buffer (Buffer oriented) 14 | 15 | - IO 操作是阻塞的, 而 NIO 操作是非阻塞的 16 | - IO 没有 selector 概念, 而 NIO 有 selector 概念. 17 | 18 | #### 基于 Stream 与基于 Buffer 19 | 20 | 传统的 IO 是面向字节流或字符流的, 而在 NIO 中, 我们抛弃了传统的 IO 流, 而是引入了 Channel 和 Buffer 的概念。在 NIO 中, 我只能从 Channel 中读取数据到 Buffer 中或将数据从 Buffer 中写入到 Channel。 21 | 22 | 那么什么是 基于流 呢? 在一般的 Java IO 操作中, 我们以流式的方式顺序地从一个 Stream 中读取一个或多个字节, 因此我们也就不能随意改变读取指针的位置。 23 | 而 基于 Buffer 就显得有点不同了. 我们首先需要从 Channel 中读取数据到 Buffer 中, 当 Buffer 中有数据后, 我们就可以对这些数据进行操作了。不像 IO 那样是顺序操作, NIO 中我们可以随意地读取任意位置的数据。 24 | 25 | ### 阻塞和非阻塞 26 | 27 | Java 提供的各种 Stream 操作都是阻塞的, 例如我们调用一个 read 方法读取一个文件的内容, 那么调用 read 的线程会被阻塞住, 直到 read 操作完成。而 NIO 的非阻塞模式允许我们非阻塞地进行 IO 操作.。例如我们需要从网络中读取数据, 在 NIO 的非阻塞模式中, 当我们调用 read 方法时, 如果此时有数据, 则 read 读取并返回; 如果此时没有数据, 则 read 直接返回, 而不会阻塞当前线程。 28 | 29 | ### selector 30 | 31 | selector 是 NIO 中才有的概念, 它是 Java NIO 之所以可以非阻塞地进行 IO 操作的关键。通过 Selector, 一个线程可以监听多个 Channel 的 IO 事件, 当我们向一个 Selector 中注册了 Channel 后, Selector 内部的机制就可以自动地为我们不断地查询(select) 这些注册的 Channel 是否有已就绪的 IO 事件(例如可读, 可写, 网络连接完成等)。通过这样的 Selector 机制, 我们就可以很简单地使用一个线程高效地管理多个 Channel 了。 -------------------------------------------------------------------------------- /NIO/MappedByteBuffer以及mmap的底层原理.md: -------------------------------------------------------------------------------- 1 | # MappedByteBuffer以及mmap的底层原理 2 | 3 | 最近在用java中的ByteBuffer,一直不明所以,尤其是对MappedByteBuffer使用的内存映射这个概念云里雾里。 4 | 5 | 于是首先补了物理内存、虚拟内存、页面文件、交换区的只是:[小科普——物理内存、页面文件、交换区和虚拟内存](http://www.guokr.com/blog/62218/) 6 | 7 | 然后阅读了ByteBuffer的文章:[ByteBuffer使用和实现以及文件内存映射](http://www.molotang.com/articles/997.html)。 8 | 9 | Bytebuffer分为两种:间接地和直接的,所谓直接就是指MappedByteBuffer,直接使用内存映射(java的话就意味着在JVM之外分配虚拟地址空间);而间接的ByteBuffer是在JVM的堆上面的,说白了就是管理一群byte数组的包装。 10 | 11 | 这里面最核心最关键的也即是内存映射了,下面的内容来自这篇文章:[内存映射文件原理探索](http://blog.csdn.net/mg0832058/article/details/5890688) 12 | 13 | 内存映射: 14 | 15 | ## 原理 16 | 17 | 首先,“映射”这个词,就和数学课上说的“一一映射”是一个意思,就是建立一种一一对应关系,在这里主要是只 硬盘上文件 的位置与进程 逻辑地址空间 中一块大小相同的区域之间的一一对应,如图1中过程1所示。这种对应关系纯属是逻辑上的概念,物理上是不存在的,原因是进程的逻辑地址空间本身就是不存在的。在内存映射的过程中,并没有实际的数据拷贝,文件没有被载入内存,只是逻辑上被放入了内存,具体到代码,就是建立并初始化了相关的数据结构(struct address_space),这个过程有系统调用mmap()实现,所以建立内存映射的效率很高。 18 | 19 | ![img](https://github.com/muyinchen/woker/blob/master/mypics/%E5%86%85%E5%AD%98%E6%98%A0%E5%B0%84%E5%8E%9F%E7%90%86.gif?raw=true) 20 | 21 | ​ 图1.内存映射原理 22 | 23 | 24 | 25 | 既然建立内存映射没有进行实际的数据拷贝,那么进程又怎么能最终直接通过内存操作访问到硬盘上的文件呢?那就要看内存映射之后的几个相关的过程了。 26 | 27 | mmap()会返回一个指针ptr,它指向进程逻辑地址空间中的一个地址,这样以后,进程无需再调用read或write对文件进行读写,而只需要通过ptr就能够操作文件。但是ptr所指向的是一个逻辑地址,要操作其中的数据,必须通过MMU将逻辑地址转换成物理地址,如图1中过程2所示。这个过程与内存映射无关。 28 | 29 | 前面讲过,建立内存映射并没有实际拷贝数据,这时,MMU在地址映射表中是无法找到与ptr相对应的物理地址的,也就是MMU失败,将产生一个缺页中断,缺页中断的中断响应函数会在swap中寻找相对应的页面,如果找不到(也就是该文件从来没有被读入内存的情况),则会通过mmap()建立的映射关系,从硬盘上将文件读取到物理内存中,如图1中过程3所示。这个过程与内存映射无关。 30 | 31 | 如果在拷贝数据时,发现物理内存不够用,则会通过虚拟内存机制(swap)将暂时不用的物理页面交换到硬盘上,如图1中过程4所示。这个过程也与内存映射无关。 32 | 33 | 34 | 35 | ## 效率 36 | 37 | 从代码层面上看,从硬盘上将文件读入内存,都要经过文件系统进行数据拷贝,并且数据拷贝操作是由文件系统和硬件驱动实现的,理论上来说,拷贝数据的效率是一样的。但是通过内存映射的方法访问硬盘上的文件,效率要比read和write系统调用高,这是为什么呢?原因是read()是系统调用,其中进行了数据拷贝,它首先将文件内容从硬盘拷贝到内核空间的一个缓冲区,如图2中过程1,然后再将这些数据拷贝到用户空间,如图2中过程2,在这个过程中,实际上完成了 两次数据拷贝 ;而mmap()也是系统调用,如前所述,mmap()中没有进行数据拷贝,真正的数据拷贝是在缺页中断处理时进行的,由于mmap()将文件直接映射到用户空间,所以中断处理函数根据这个映射关系,直接将文件从硬盘拷贝到用户空间,只进行了 一次数据拷贝 。因此,内存映射的效率要比read/write效率高。 38 | 39 | 40 | 41 | 42 | 43 | ![img](https://github.com/muyinchen/woker/blob/master/mypics/read%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8%E5%8E%9F%E7%90%86.gif?raw=true) 44 | 45 | ​ 图2.read系统调用原理 46 | 47 | -------------------------------------------------------------------------------- /docker/10张图带你深入理解Docker容器和镜像.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/docker/10张图带你深入理解Docker容器和镜像.pdf -------------------------------------------------------------------------------- /git/GIT常用经验.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/git/GIT常用经验.pdf -------------------------------------------------------------------------------- /mybatis/mybatis的mapper返回map结果集.md: -------------------------------------------------------------------------------- 1 | # mybatis的mapper返回map结果集 2 | 3 | ## 通过MapKey指定map的key值 4 | 5 | ```java 6 | @MapKey("id") 7 | Map getUserInfoMap(); 8 | 9 | @MapKey("id") 10 | Map> getUserValueMap(); 11 | ``` 12 | 13 | ## map的value为java类 14 | 15 | ```xml 16 | 17 | 18 | 19 | 20 | 21 | 24 | ``` 25 | 26 | ## map的value为map 27 | 28 | ```xml 29 | 33 | ``` -------------------------------------------------------------------------------- /mypics/1552756959199.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/1552756959199.png -------------------------------------------------------------------------------- /mypics/20161205164730067.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/20161205164730067.png -------------------------------------------------------------------------------- /mypics/ByteBuffer 逻辑视图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/ByteBuffer 逻辑视图.png -------------------------------------------------------------------------------- /mypics/ByteBuffer初始化.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/ByteBuffer初始化.png -------------------------------------------------------------------------------- /mypics/CollectedHeap Universecreate_heap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/CollectedHeap Universecreate_heap.png -------------------------------------------------------------------------------- /mypics/Java IO vs NIO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/Java IO vs NIO.png -------------------------------------------------------------------------------- /mypics/Java IO.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/Java IO.jpg -------------------------------------------------------------------------------- /mypics/Java NIO的核心组件.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/Java NIO的核心组件.png -------------------------------------------------------------------------------- /mypics/KQueueSelectorProvider.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/KQueueSelectorProvider.jpg -------------------------------------------------------------------------------- /mypics/Linux进程在虚拟内存中的标准内存段布局.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/Linux进程在虚拟内存中的标准内存段布局.jpg -------------------------------------------------------------------------------- /mypics/NIO具备的新特性.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/NIO具备的新特性.png -------------------------------------------------------------------------------- /mypics/NioEndpoint 处理请求具体流程如图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/NioEndpoint 处理请求具体流程如图.png -------------------------------------------------------------------------------- /mypics/NioEndpoint处理的的时序图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/NioEndpoint处理的的时序图.png -------------------------------------------------------------------------------- /mypics/ServerSocketServer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/ServerSocketServer.jpg -------------------------------------------------------------------------------- /mypics/_传统数据拷贝过程.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/_传统数据拷贝过程.jpg -------------------------------------------------------------------------------- /mypics/act end()逻辑.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/act end()逻辑.jpg -------------------------------------------------------------------------------- /mypics/buffer.compact()调用前.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/buffer.compact()调用前.png -------------------------------------------------------------------------------- /mypics/buffer.compact()调用后.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/buffer.compact()调用后.png -------------------------------------------------------------------------------- /mypics/buffer.rewind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/buffer.rewind.png -------------------------------------------------------------------------------- /mypics/buffers-modes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/buffers-modes.png -------------------------------------------------------------------------------- /mypics/create_heap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/create_heap.png -------------------------------------------------------------------------------- /mypics/doselect()实现.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/doselect()实现.png -------------------------------------------------------------------------------- /mypics/flip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/flip.png -------------------------------------------------------------------------------- /mypics/gather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/gather.png -------------------------------------------------------------------------------- /mypics/implRegister().jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/implRegister().jpg -------------------------------------------------------------------------------- /mypics/linux2.4+transferTo().jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/linux2.4+transferTo().jpg -------------------------------------------------------------------------------- /mypics/nonBlocking IO.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/nonBlocking IO.jpg -------------------------------------------------------------------------------- /mypics/overview-channels-buffers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/overview-channels-buffers.png -------------------------------------------------------------------------------- /mypics/overview-channels-buffers1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/overview-channels-buffers1.png -------------------------------------------------------------------------------- /mypics/overview-selectors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/overview-selectors.png -------------------------------------------------------------------------------- /mypics/read系统调用原理.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/read系统调用原理.gif -------------------------------------------------------------------------------- /mypics/scatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/scatter.png -------------------------------------------------------------------------------- /mypics/sd可中断IO场景.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/sd可中断IO场景.jpg -------------------------------------------------------------------------------- /mypics/selector 整体图.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/selector 整体图.jpg -------------------------------------------------------------------------------- /mypics/sendfile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/sendfile.jpg -------------------------------------------------------------------------------- /mypics/slice新bytebuffer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/slice新bytebuffer.png -------------------------------------------------------------------------------- /mypics/timg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/timg.jpg -------------------------------------------------------------------------------- /mypics/tomcat-Connector.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/tomcat-Connector.jpg -------------------------------------------------------------------------------- /mypics/tomcat产生访问时事件流向.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/tomcat产生访问时事件流向.jpg -------------------------------------------------------------------------------- /mypics/transferTo().jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/transferTo().jpg -------------------------------------------------------------------------------- /mypics/webflux_backpressure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/webflux_backpressure.png -------------------------------------------------------------------------------- /mypics/从SocketProcessor开始执行一次请求的时序图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/从SocketProcessor开始执行一次请求的时序图.png -------------------------------------------------------------------------------- /mypics/内存映射原理.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/内存映射原理.gif -------------------------------------------------------------------------------- /mypics/原始ByteBuffer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/原始ByteBuffer.png -------------------------------------------------------------------------------- /mypics/段页式机制Linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/段页式机制Linux.png -------------------------------------------------------------------------------- /mypics/用户态与内核态.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/用户态与内核态.jpg -------------------------------------------------------------------------------- /mypics/系统IO调用01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/系统IO调用01.png -------------------------------------------------------------------------------- /mypics/系统IO调用02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/mypics/系统IO调用02.png -------------------------------------------------------------------------------- /mysql/MySQL基本概念--锁.md: -------------------------------------------------------------------------------- 1 | # MySQL基本概念--锁 2 | 3 | 介绍下对于MySQL锁机制的理解 4 | 5 | 从基本概念开始: 6 | 7 | ### **共享锁** 8 | 9 | 共享锁的代号是S,是Share的缩写,共享锁的锁粒度是行或者元组(多个行)。一个事务获取了共享锁之后,可以对锁定范围内的数据执行读操作。 10 | 11 | ### **排它锁** 12 | 13 | 排它锁的代号是X,是`eXclusive`的缩写,排它锁的粒度与共享锁相同,也是行或者元组。一个事务获取了排它锁之后,可以对锁定范围内的数据执行写操作。 14 | 15 | 假设有两个事务t1和t2 16 | 17 | 如果事务t1获取了一个元组的共享锁,事务t2还可以立即获取这个元组的共享锁,但不能立即获取这个元组的排它锁(必须等到t1释放共享锁之后)。 18 | 19 | 如果事务t1获取了一个元组的排它锁,事务t2不能立即获取这个元组的共享锁,也不能立即获取这个元组的排它锁(必须等到t1释放排它锁之后) 20 | 21 | ### **意向锁** 22 | 23 | 意向锁是一种表锁,锁定的粒度是整张表,分为意向共享锁(IS)和意向排它锁(IX)两类。意向共享锁表示一个事务有意对数据上共享锁或者排它锁。“有意”这两个字表达的意思比较微妙,说的明白点就是指事务想干这个事但还没真去干。举例说明下意向共享锁,比如一个事务t执行了这样一个语句:`select * from table lock in share model` ,如果这个语句执行成功,就对表table上了一个意向共享锁。**lock in share model**就是说事务t1在接下来要执行的语句中要获取S锁。如果t1的`select * from table lock in share model`执行成功,那么接下来t1应该可以畅通无阻的去执行只需要共享锁的语句了。意向排它锁的含义同理可知,上例中要获取意向排它锁,可以使用`select * from table for update**** `。 24 | 25 | **lock in share model 和 for update**这两个东西在数据率理论中还有个学名叫悲观锁,与悲观锁相对的当然还有乐观锁。大家可以看到各种锁都是成双成对出现的。关于悲观锁和乐观锁的问题暂且不表,下文再来详述。 26 | 27 | ### **锁的互斥与兼容关系** 28 | 29 | 锁和锁之间的关系,要么是相容的,要么是互斥的。 30 | 31 | 锁a和锁b相容是指:操作同样一组数据时,如果事务t1获取了锁a,另一个事务t2还可以获取锁b; 32 | 33 | 锁a和锁b互斥是指:操作同样一组数据时,如果事务t1获取了锁a,另一个事务t2在t1释放锁a之前无法获取锁b。 34 | 35 | 上面提到的共享锁、排它锁、意向共享锁、意向排它锁相互之前都是有兼容/互斥关系的,可以用一个兼容性矩阵表示(y表示兼容,n表示不兼容): 36 | 37 | > ```java 38 | > X S IX IS 39 | > X n n n n 40 | > S n y n y 41 | > IX n n y y 42 | > IS n y y y 43 | > ``` 44 | 45 | 兼容性矩阵为什么是这个样子的? 46 | 47 | X和S的相互关系在上文中解释过了,IX和IS的相互关系全部是兼容,这也很好理解,因为它们都只是“有意”,还处于YY阶段,没有真干,所以是可以兼容的; 48 | 49 | 剩下的就是X和IX,X和IS, S和IX, S和IS的关系了,我们可以由X和S的关系推导出这四组关系。 50 | 51 | 简单的说:X和IX的=X和X的关系。为什么呢?因为事务在获取IX锁后,接下来就有权利获取X锁。如果X和IX兼容的话,就会出现两个事务都获取了X锁的情况,这与我们已知的X与X互斥是矛盾的,所以X与IX只能是互斥关系。其余的三组关系同理,可用同样的方式推导出来。 52 | 53 | 54 | 55 | **对于 UPDATE、DELETE和INSERT语句,InnoDB会自动给涉及数据集加排他锁(X);对于普通SELECT语句,InnoDB不会加任何锁; 事务可以通过显式给记录集加共享锁或排他锁。** 56 | 57 | ### **其它:** 58 | 59 | #### 一致性非阻塞读 60 | 61 | select... lock in share mode和select ... for update的区别 62 | 63 | 索引记录锁 64 | 65 | 间隙锁 66 | 67 | 后码锁 68 | 69 | 各种语句对应的锁类型 70 | 71 | 在有索引的情况下是以后码锁为基础的行级锁,在固定索引键查找的情况下是索引记录锁,在没有可用索引的情况下上升到表锁 72 | 73 | 有索引的情况: 74 | 75 | select ... from 一致性非阻塞读,不上锁。在serializable隔离级别下例外,在这个隔离级别下上共享后码锁 76 | 77 | select ... from ... lock in share mode 共享后码锁 78 | 79 | select ... from ... for update 排它后码锁 80 | 81 | update .... where 排它后码锁 82 | 83 | delete from .... where 排它后码锁 84 | 85 | insert ... 排它索引记录锁,如果发生键值唯一性冲突则转成共享锁 86 | 87 | insert ... on duplicate key update ,一直都是排它锁 88 | 89 | replace ... 一直都是排它锁 -------------------------------------------------------------------------------- /mysql/MySQL存储引擎--MyISAM与InnoDB区别.md: -------------------------------------------------------------------------------- 1 | # MySQL存储引擎--MyISAM与InnoDB区别 2 | 3 | `MyISAM `和`InnoDB` 讲解   4 | 5 | `InnoDB`和`MyISAM`是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定。基本的差别为:`MyISAM`类型不支持事务处理等高级处理,而`InnoDB`类型支持。`MyISAM`类型的表强调的是性能,其执行数度比`InnoDB`类型更快,但是不提供事务支持,而`InnoDB`提供事务支持以及外部键等高级数据库功能。   6 | 7 | 以下是一些细节和具体实现的差别:  8 | 9 |  ◆1.`InnoDB`不支持FULLTEXT类型的索引。  10 | 11 |  ◆2.`InnoDB` 中不保存表的具体行数,也就是说,执行`select count(*) from table`时,`InnoDB`要扫描一遍整个表来计算有多少行,但是`MyISAM`只要简单的读出保存好的行数即可。注意的是,当`count(*)`语句包含 `where`条件时,两种表的操作是一样的。  12 | 13 |  ◆3.对于`AUTO_INCREMENT`类型的字段,`InnoDB`中必须包含只有该字段的索引,但是在`MyISAM`表中,可以和其他字段一起建立联合索引。  14 | 15 |  ◆4.`DELETE FROM table`时,`InnoDB`不会重新建立表,而是一行一行的删除。  16 | 17 |  ◆5.`LOAD TABLE FROM MASTER`操作对`InnoDB`是不起作用的,解决方法是首先把`InnoDB`表改成`MyISAM`表,导入数据后再改成`InnoDB`表,但是对于使用的额外的`InnoDB`特性(例如外键)的表不适用。   18 | 19 | 另外,`InnoDB`表的行锁也不是绝对的,假如在执行一个SQL语句时MySQL不能确定要扫描的范围,`InnoDB`表同样会锁全表,例如`update table set num=1 where name like “%aaa%”` 20 | 21 | **两种类型最主要的差别就是`InnoDB` 支持事务处理与外键和行级锁。**而`MyISAM`不支持.所以`MyISAM`往往就容易被人认为只适合在小项目中使用。 22 | 23 |   作为使用MySQL的用户角度出发,`InnoDB`和`MyISAM`都是比较喜欢的,如果数据库平台要达到需求:99.9%的稳定性,方便的扩展性和高可用性来说的话,`MyISAM`绝对是首选。  24 | 25 |  原因如下:  26 | 27 |  1、平台上承载的大部分项目是读多写少的项目,而`MyISAM`的读性能是比`InnoDB`强不少的。  28 | 29 |  2、`MyISAM`的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而`InnoDB`是索引和数据是紧密捆绑的,没有使用压缩从而会造成`InnoDB`比`MyISAM`体积庞大不小。  30 | 31 |  3、经常隔1,2个月就会发生应用开发人员不小心update一个表where写的范围不对,导致这个表没法正常用了,这个时候`MyISAM`的优越性就体现出来了,随便从当天拷贝的压缩包取出对应表的文件,随便放到一个数据库目录下,然后dump成sql再导回到主库,并把对应的binlog补上。如果是`InnoDB`,恐怕不可能有这么快速度,别和我说让`InnoDB`定期用导出xxx.sql机制备份,因为最小的一个数据库实例的数据量基本都是几十G大小。   32 | 33 | 4、从接触的应用逻辑来说,`select count(*)`和`order by` 是最频繁的,大概能占了整个sql总语句的60%以上的操作,而这种操作`Innodb`其实也是会锁表的,很多人以为`Innodb`是行级锁,那个只是`where`对它主键是有效,非主键的都会锁全表的。  34 | 35 |  5、还有就是经常有很多应用部门需要我给他们定期某些表的数据,`MyISAM`的话很方便,只要发给他们对应那表的`frm.MYD,MYI`的文件,让他们自己在对应版本的数据库启动就行,而`Innodb`就需要导出`xxx.sql`了,因为光给别人文件,受字典数据文件的影响,对方是无法使用的。  36 |  6、如果和``MyISAM``比`insert`写操作的话,`Innodb`还达不到`MyISAM`的写性能,如果是针对基于索引的`update`操作,虽然`MyISAM`可能会逊色`Innodb`,但是那么高并发的写,从库能否追的上也是一个问题,还不如通过多实例分库分表架构来解决。  37 |  7、如果是用`MyISAM`的话,`merge`引擎可以大大加快应用部门的开发速度,他们只要对这个`merge`表做一些`select count(*)`操作,非常适合大项目总量约几亿的`rows`某一类型(如日志,调查统计)的业务表。  38 |   当然`Innodb`也不是绝对不用,用事务的项目就用`Innodb`的。另外,可能有人会说你MyISAM无法抗太多写操作,但是可以通过架构来弥补。 -------------------------------------------------------------------------------- /mysql/《高性能MySQL》读书笔记--MySQL逻辑架构.md: -------------------------------------------------------------------------------- 1 | # 《高性能MySQL》读书笔记--MySQL逻辑架构 2 | 3 | ## 一、MySQL逻辑架构 4 | 5 | MySQL最重要的、最与众不同的特性是它的存储引擎架构,这种构架的设计将查询处理及其它系统任务和数据的存储/提取相分离。 6 | 7 | ![](http://og0sybnix.bkt.clouddn.com/%E4%B8%8B%E8%BD%BD%20%284%29.png) 8 | 9 | 第一层,服务层,最上层的服务并不是MySQL独有的,大多数基于网络的客户端/服务端的工具或者服务都有类似的架构。主要为请求做连接处理,授权认证,安全等。 10 | 11 | 第二层,核心层,大多数MySQL的核心服务功能都在这一层,包括查询解析,分析,优化,缓存,以及所有的内置函数(例如日期、时间、数学和加密函数),所有跨存储引擎的功能都在这一层实现:存储过程,触发器,视图等。 12 | 13 | 第三层,存储引擎,存储引擎负责MySQL中数据的存储和提取。服务器通过API与存储引擎进行通信。这些接口屏蔽了不同存储引擎之间的差异,使得这些差异对上层的查询过程透明。存储引擎不会去解析SQL,不同存储引擎之间也不会相互通信,而只是简单地响应上层服务的请求。 14 | 15 | 16 | 17 | ## 连接管理与安全性(第一层 服务层) 18 | 19 | 20 | 21 | ** > 连接流程** 22 | 23 | ![](http://og0sybnix.bkt.clouddn.com/%E4%B8%8B%E8%BD%BD%20%283%29.png) 24 | 25 | Δ 每个连接的查询都在一个进程中的线程完成。 Δ 服务器负责缓存线程,所以服务层不需要为每个新建的连接创建或者销毁线程(可以使用线程池)。**> 认证流程**1、当客户端(应用)连接到MySQL服务器时,服务器需要对其进行认证。认证基于用户名、原始主机信息和密码。如果使用了安全套接字的方式连接,还可以使用X.509证书认证。2、一旦客户端连接成功,服务器会继续验证该客户是否具有执行某个查询的权限(例如对某个库某张表执行查询语句) 26 | 27 | ![](http://og0sybnix.bkt.clouddn.com/%E4%B8%8B%E8%BD%BD%20%282%29.png) 28 | 29 | ## 优化与执行 30 | 31 | 1、MySQL会解释查询,并创建内部[数据结构](http://lib.csdn.net/base/datastructure)(解析树),然后对其进行各种优化,包括重写查询、决定表的读取顺序,以及选择合适的索引等。 32 | 33 | 2、 对于SELECT语句,在解析查询之前,服务器会先检查查询缓存,如果能命中,服务器就不必再执行查询解析、优化和执行的整个过程,直接返回查询缓存中的结果集。 34 | 35 | ![](http://og0sybnix.bkt.clouddn.com/%E4%B8%8B%E8%BD%BD%20%281%29.png) -------------------------------------------------------------------------------- /netty/990532-20161224164013807-193335423.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/netty/990532-20161224164013807-193335423.png -------------------------------------------------------------------------------- /redis/Redis 3.2安装及主从复制详细配置.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/redis/Redis 3.2安装及主从复制详细配置.pdf -------------------------------------------------------------------------------- /redis/redis3.2 最新版本启动配置文件redis.conf详细说明 .pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/redis/redis3.2 最新版本启动配置文件redis.conf详细说明 .pdf -------------------------------------------------------------------------------- /rpc框架涉及知识点/Java里实现链式编程风格.md: -------------------------------------------------------------------------------- 1 | # Java里实现链式编程风格 2 | 3 | #### 链式编程 4 | 5 | 所谓的链式编程,则是类似与StringBuffer的append方法的写法: 6 | 7 | ```java 8 | StringBuffer buffer = new StringBuffer(); 9 | // 链式编程 10 | buffer.append("aaa").append("bbb").append("ccc"); 11 | ``` 12 | 13 | #### 如何实现 14 | 15 | 那么问题来了,怎么实现这种炫酷的连写的代码呢? 16 | 其实很简单,那就是在方法的最后写上`return this`; 17 | 如果大家去看看`StringBuffer`的`append`的源代码,也可以发现,它里面也是这么写的,我们除了在拼接字符串的时候这么用,在什么时候也可以用链式编程呢? 18 | 我认为在创建实体`bean`对象的时候,可以这么写。 19 | 如下: 20 | 21 | ```java 22 | public class Dog { 23 | 24 | private int weight; 25 | private String color; 26 | private String dogTye; 27 | 28 | public Dog setWegith(int weight) { 29 | this.weight = weight; 30 | return this; 31 | } 32 | 33 | public Dog setColor(String color) { 34 | this.color = color; 35 | return this; 36 | } 37 | 38 | public Dog setDogType(String dogType) { 39 | this.dogType = dogType; 40 | return this; 41 | } 42 | } 43 | ``` 44 | 45 | 我们在创建这个实体的时候就可以这么写: 46 | 47 | ```java 48 | Dog dog = new Dog(); 49 | // 常规赋值风格 50 | dog.setWeght(20); 51 | dog.setColor("金黄色"); 52 | dog.setDogType("金毛犬"); 53 | // 链式编程风格 54 | dog.setWeght(20).setColor("金黄色").setDogType("金毛犬"); 55 | ``` 56 | 57 | 这样子看起来是不是很简洁呢???反正我觉得这么些挺不错的。 -------------------------------------------------------------------------------- /rpc框架涉及知识点/netty 数据分包、组包、粘包处理机制(部分).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/rpc框架涉及知识点/netty 数据分包、组包、粘包处理机制(部分).pdf -------------------------------------------------------------------------------- /rpc框架涉及知识点/通过Lombok来简化你的代码.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/rpc框架涉及知识点/通过Lombok来简化你的代码.pdf -------------------------------------------------------------------------------- /spring/springmvc学习笔记/springmvc学习笔记(12)-springmvc注解开发之包装类型参数绑定.md: -------------------------------------------------------------------------------- 1 | # springmvc学习笔记(12)-springmvc注解开发之包装类型参数绑定 2 | 3 | 标签: springmvc 4 | 5 | --- 6 | 7 | **Contents** 8 | 9 | - [需求](#需求) 10 | - [实现方法](#实现方法) 11 | - [页面参数和controller方法形参定义](#页面参数和controller方法形参定义) 12 | 13 | 14 | 15 | --- 16 | 17 | 本文主要介绍注解开发的介绍包装类型的参数绑定 18 | 19 | 20 | ## 需求 21 | 22 | 商品查询controller方法中实现商品查询条件传入。 23 | 24 | ## 实现方法 25 | 26 | - 第一种方法:在形参中添加`HttpServletRequest request`参数,通过request接收查询条件参数。 27 | - 第二种方法:在形参中让包装类型的pojo接收查询条件参数。 28 | 29 | 分析: 30 | 31 | 页面传参数的特点:复杂,多样性。条件包括:用户账号、商品编号、订单信息。。。 32 | 33 | 如果将用户账号、商品编号、订单信息等放在简单pojo(属性是简单类型)中,pojo类属性比较多,比较乱。建议使用包装类型的pojo,pojo中属性是pojo。 34 | 35 | ## 页面参数和controller方法形参定义 36 | 37 | - 页面参数: 38 | 39 | 商品名称:`` 40 | 41 | **注意:itemsCustom和包装pojo中的属性名一致即可。** 42 | 43 | 44 | - controller方法形参: 45 | 46 | `public ModelAndView queryItems(HttpServletRequest request, ItemsQueryVo itemsQueryVo) throws Exception` 47 | 48 | - 包装类ItemsQueryVo中部分属性: 49 | 50 | ```java 51 | public class ItemsQueryVo { 52 | 53 | //商品信息 54 | private Items items; 55 | 56 | //为了系统 可扩展性,对原始生成的po进行扩展 57 | private ItemsCustom itemsCustom; 58 | ``` 59 | 60 | 可见,`ItemsQueryVo`中属性`itemsCustom`和页面参数中一致 61 | 62 | 63 | 64 | ---- 65 | 66 | > 作者[@brianway](http://brianway.github.io/)更多文章:[个人网站](http://brianway.github.io/) `|` [CSDN](http://blog.csdn.net/h3243212/) `|` [oschina](http://my.oschina.net/brianway) 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /spring/springmvc学习笔记/springmvc学习笔记(15)-数据回显.md: -------------------------------------------------------------------------------- 1 | # springmvc学习笔记(15)-数据回显 2 | 3 | 标签: springmvc 4 | 5 | --- 6 | 7 | **Contents** 8 | 9 | - [pojo数据回显方法](#pojo数据回显方法) 10 | - [简单类型数据回显](#简单类型数据回显) 11 | 12 | 13 | 14 | --- 15 | 16 | 17 | 18 | 本文介绍springmvc中数据回显的几种实现方法 19 | 20 | 21 | 数据回显:提交后,如果出现错误,将刚才提交的数据回显到刚才的提交页面。 22 | 23 | 24 | ## pojo数据回显方法 25 | 26 | 1.springmvc默认对pojo数据进行回显。 27 | 28 | **pojo数据传入controller方法后,springmvc自动将pojo数据放到request域,key等于pojo类型(首字母小写)** 29 | 30 | 使用`@ModelAttribute`指定pojo回显到页面在request中的key 31 | 32 | 2.`@ModelAttribute`还可以将方法的返回值传到页面 33 | 34 | 在商品查询列表页面,通过商品类型查询商品信息。在controller中定义商品类型查询方法,最终将商品类型传到页面。 35 | 36 | ```java 37 | // 商品分类 38 | //itemtypes表示最终将方法返回值放在request中的key 39 | @ModelAttribute("itemtypes") 40 | public Map getItemTypes() { 41 | 42 | Map itemTypes = new HashMap(); 43 | itemTypes.put("101", "数码"); 44 | itemTypes.put("102", "母婴"); 45 | 46 | return itemTypes; 47 | } 48 | ``` 49 | 50 | 页面上可以得到itemTypes数据。 51 | 52 | 53 | ```jsp 54 | 55 | 商品名称: 56 | 商品类型: 57 | 62 | 63 | ``` 64 | 65 | 3.使用最简单方法使用model,可以不用`@ModelAttribute` 66 | 67 | ```java 68 | //可以直接使用model将提交pojo回显到页面 69 | //model.addAttribute("items", itemsCustom); 70 | ``` 71 | 72 | 73 | ## 简单类型数据回显 74 | 75 | 使用最简单方法使用model 76 | 77 | `model.addAttribute("id", id);` 78 | 79 | 80 | 81 | 82 | ---- 83 | 84 | > 作者[@brianway](http://brianway.github.io/)更多文章:[个人网站](http://brianway.github.io/) `|` [CSDN](http://blog.csdn.net/h3243212/) `|` [oschina](http://my.oschina.net/brianway) 85 | -------------------------------------------------------------------------------- /spring/springmvc学习笔记/springmvc学习笔记(4)-前端控制器.md: -------------------------------------------------------------------------------- 1 | # springmvc学习笔记(4)-前端控制器 2 | 3 | 标签: springmvc 4 | 5 | --- 6 | 7 | **Contents** 8 | 9 | 10 | 11 | 12 | --- 13 | 14 | 15 | 本文通过前端控制器源码分析springmvc执行过程 16 | 17 | 18 | 1.前端控制器接收请求 19 | 20 | 调用`doDispatch`方法 21 | 22 | ```java 23 | protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { 24 | HttpServletRequest processedRequest = request; 25 | HandlerExecutionChain mappedHandler = null; 26 | boolean multipartRequestParsed = false; 27 | 28 | 。。。。。 29 | } 30 | ``` 31 | 32 | 33 | 2.前端控制器调用`HandlerMapping`(处理器映射器)根据url查找Handler 34 | 35 | 36 | ```java 37 | // Determine handler for the current request. 38 | mappedHandler = getHandler(processedRequest); 39 | ``` 40 | 41 | ```java 42 | /** 43 | * Return the HandlerExecutionChain for this request. 44 | *

Tries all handler mappings in order. 45 | * @param request current HTTP request 46 | * @return the HandlerExecutionChain, or {@code null} if no handler could be found 47 | */ 48 | protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception { 49 | for (HandlerMapping hm : this.handlerMappings) { 50 | if (logger.isTraceEnabled()) { 51 | logger.trace( 52 | "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'"); 53 | } 54 | HandlerExecutionChain handler = hm.getHandler(request); 55 | if (handler != null) { 56 | return handler; 57 | } 58 | } 59 | return null; 60 | } 61 | ``` 62 | 63 | 3.调用处理器适配器执行Handler,得到执行的结果`ModelAndView mv` 64 | 65 | 在`doDispatch`方法中 66 | 67 | ```java 68 | // Actually invoke the handler. 69 | mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); 70 | ``` 71 | 72 | 4.视图渲染,将model数据填充到request域 73 | 74 | `doDispatch`->`processDispatchResult`->`render` 75 | 76 | 在`render`方法中,视图解析得到view 77 | 78 | ```java 79 | // We need to resolve the view name. 80 | view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request); 81 | 82 | ``` 83 | 84 | 调用view的渲染方法,将model数据填充到request域 85 | 86 | 在`render`方法中,调用`View`接口的`render`方法 87 | 88 | ```java 89 | view.render(mv.getModelInternal(), request, response); 90 | ``` 91 | 92 | 93 | 程序我也没细读,感觉分析比较浅,很多还没弄懂,等我系统阅读源码后会整理一篇好点的。 94 | 95 | 96 | 97 | ---- 98 | 99 | > 作者[@brianway](http://brianway.github.io/)更多文章:[个人网站](http://brianway.github.io/) `|` [CSDN](http://blog.csdn.net/h3243212/) `|` [oschina](http://my.oschina.net/brianway) 100 | -------------------------------------------------------------------------------- /spring/spring的@Transactional注解详细用法.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/spring/spring的@Transactional注解详细用法.pdf -------------------------------------------------------------------------------- /springcloud/springboot/SpringBoot配置属性之Migration.md: -------------------------------------------------------------------------------- 1 | # SpringBoot配置属性之Migration 2 | 3 | ## 序 4 | 5 | SpringBoot支持了两种数据库迁移工具,一个是flyway,一个是liquibase。其本身也支持sql script,在初始化数据源之后执行指定的脚本。 6 | 7 | ## flyway 8 | 9 | - flyway.baseline-description对执行迁移时基准版本的描述. 10 | - flyway.baseline-on-migrate当迁移时发现目标schema非空,而且带有没有元数据的表时,是否自动执行基准迁移,默认false. 11 | - flyway.baseline-version开始执行基准迁移时对现有的schema的版本打标签,默认值为1. 12 | - flyway.check-location检查迁移脚本的位置是否存在,默认false. 13 | - flyway.clean-on-validation-error当发现校验错误时是否自动调用clean,默认false. 14 | - flyway.enabled是否开启flywary,默认true. 15 | - flyway.encoding设置迁移时的编码,默认UTF-8. 16 | - flyway.ignore-failed-future-migration当读取元数据表时是否忽略错误的迁移,默认false. 17 | - flyway.init-sqls当初始化好连接时要执行的SQL. 18 | - flyway.locations迁移脚本的位置,默认db/migration. 19 | - flyway.out-of-order是否允许无序的迁移,默认false. 20 | - flyway.password目标数据库的密码. 21 | - flyway.placeholder-prefix设置每个placeholder的前缀,默认${. 22 | - flyway.placeholder-replacementplaceholders是否要被替换,默认true. 23 | - flyway.placeholder-suffix设置每个placeholder的后缀,默认}. 24 | - flyway.placeholders.[placeholder name]设置placeholder的value 25 | - flyway.schemas设定需要flywary迁移的schema,大小写敏感,默认为连接默认的schema. 26 | - flyway.sql-migration-prefix迁移文件的前缀,默认为V. 27 | - flyway.sql-migration-separator迁移脚本的文件名分隔符,默认__ 28 | - flyway.sql-migration-suffix迁移脚本的后缀,默认为.sql 29 | - flyway.tableflyway使用的元数据表名,默认为schema_version 30 | - flyway.target迁移时使用的目标版本,默认为latest version 31 | - flyway.url迁移时使用的JDBC URL,如果没有指定的话,将使用配置的主数据源 32 | - flyway.user迁移数据库的用户名 33 | - flyway.validate-on-migrate迁移时是否校验,默认为true. 34 | 35 | ## liquibase 36 | 37 | - liquibase.change-logChange log 配置文件的路径,默认值为classpath:/db/changelog/db.changelog-master.yaml 38 | - liquibase.check-change-log-location是否坚持change log的位置是否存在,默认为true. 39 | - liquibase.contexts逗号分隔的运行时context列表. 40 | - liquibase.default-schema默认的schema. 41 | - liquibase.drop-first是否首先drop schema,默认为false 42 | - liquibase.enabled是否开启liquibase,默认为true. 43 | - liquibase.password目标数据库密码 44 | - liquibase.url要迁移的JDBC URL,如果没有指定的话,将使用配置的主数据源. 45 | - liquibase.user目标数据用户名 -------------------------------------------------------------------------------- /springcloud/springboot/SpringBoot配置属性之其他.md: -------------------------------------------------------------------------------- 1 | # SpringBoot配置属性之其他 2 | 3 | ## aop 4 | 5 | - spring.aop.auto是否支持@EnableAspectJAutoProxy,默认为: true 6 | - spring.aop.proxy-target-classtrue为使用CGLIB代理,false为JDK代理,默认为false 7 | 8 | ## application 9 | 10 | - spring.application.admin.enabled是否启用admin特性,默认为: false 11 | - spring.application.admin.jmx-name指定admin MBean的名称,默认为: org.springframework.boot:type=Admin,name=SpringApplication 12 | 13 | ## autoconfig 14 | 15 | - spring.autoconfigure.exclude配置要排除的Auto-configuration classes. 16 | 17 | ## batch 18 | 19 | - spring.batch.initializer.enabled是否在必要时创建batch表,默认为true 20 | - spring.batch.job.enabled是否在启动时开启batch job,默认为true 21 | - spring.batch.job.names指定启动时要执行的job的名称,逗号分隔,默认所有job都会被执行 22 | - spring.batch.schema指定要初始化的sql语句路径,默认:classpath:org/springframework/batch/core/schema-@@platform@@.sql) 23 | - spring.batch.table-prefix指定批量处理的表的前缀. 24 | 25 | ## jmx 26 | 27 | - spring.jmx.default-domain指定JMX domain name. 28 | - spring.jmx.enabled是否暴露jmx,默认为true 29 | - spring.jmx.server指定MBeanServer bean name. 默认为: mbeanServer) 30 | 31 | ## mail 32 | 33 | - spring.mail.default-encoding指定默认MimeMessage的编码,默认为: UTF-8 34 | - spring.mail.host指定SMTP server host. 35 | - spring.mail.jndi-name指定mail的jndi名称 36 | - spring.mail.password指定SMTP server登陆密码. 37 | - spring.mail.port指定SMTP server port. 38 | - spring.mail.properties指定JavaMail session属性. 39 | - spring.mail.protocol指定SMTP server使用的协议,默认为: smtp 40 | - spring.mail.test-connection指定是否在启动时测试邮件服务器连接,默认为false 41 | - spring.mail.username指定SMTP server的用户名. 42 | 43 | ## sendgrid 44 | 45 | - spring.sendgrid.password指定SendGrid password. 46 | - spring.sendgrid.proxy.host指定SendGrid proxy host. 47 | - spring.sendgrid.proxy.port指定SendGrid proxy port. 48 | - spring.sendgrid.username指定SendGrid username. 49 | 50 | ## social 51 | 52 | - spring.social.auto-connection-views是否开启连接状态的视图,默认为false 53 | - spring.social.facebook.app-id指定应用id 54 | - spring.social.facebook.app-secret指定应用密码 55 | - spring.social.linkedin.app-id指定应用id 56 | - spring.social.linkedin.app-secret指定应用密码 57 | - spring.social.twitter.app-id指定应用ID. 58 | - spring.social.twitter.app-secret指定应用密码 -------------------------------------------------------------------------------- /企业项目开发/README.md: -------------------------------------------------------------------------------- 1 | 本系列文档源码:https://github.com/muyinchen/ssm 2 | -------------------------------------------------------------------------------- /企业项目开发/第一章 企业项目开发--maven+springmvc+spring+mybatis+velocity整合.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第一章 企业项目开发--maven+springmvc+spring+mybatis+velocity整合.pdf -------------------------------------------------------------------------------- /企业项目开发/第七章 企业项目开发--本地缓存guava cache.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第七章 企业项目开发--本地缓存guava cache.pdf -------------------------------------------------------------------------------- /企业项目开发/第三章 企业项目开发--企业中的项目架构以及多环境分配.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第三章 企业项目开发--企业中的项目架构以及多环境分配.pdf -------------------------------------------------------------------------------- /企业项目开发/第九章 企业项目开发--分布式缓存Redis(1).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第九章 企业项目开发--分布式缓存Redis(1).pdf -------------------------------------------------------------------------------- /企业项目开发/第二章 企业项目开发--maven父子模块.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第二章 企业项目开发--maven父子模块.pdf -------------------------------------------------------------------------------- /企业项目开发/第五章 企业项目开发--mybatis注解与xml并用.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第五章 企业项目开发--mybatis注解与xml并用.pdf -------------------------------------------------------------------------------- /企业项目开发/第八章 企业项目开发--分布式缓存memcached.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第八章 企业项目开发--分布式缓存memcached.pdf -------------------------------------------------------------------------------- /企业项目开发/第六章 企业项目开发--cookie.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第六章 企业项目开发--cookie.pdf -------------------------------------------------------------------------------- /企业项目开发/第十一章 企业项目开发--消息队列activemq.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第十一章 企业项目开发--消息队列activemq.pdf -------------------------------------------------------------------------------- /企业项目开发/第十章 企业项目开发--分布式缓存Redis(2).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第十章 企业项目开发--分布式缓存Redis(2).pdf -------------------------------------------------------------------------------- /企业项目开发/第四章 企业项目开发--切分配置文件.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/企业项目开发/第四章 企业项目开发--切分配置文件.pdf -------------------------------------------------------------------------------- /前端/谷歌开发者工具/安全面板/为什么说 HTTPS 很重要.md: -------------------------------------------------------------------------------- 1 | # 为什么说 HTTPS 很重要 2 | 3 | 您应始终使用 HTTPS 保护您的所有网站,即使这些网站并不处理敏感的通信。 除了为网站和用户的个人信息提供关键的安全性和数据完整性外,许多新的浏览器功能,特别是 [Progressive Web App](https://developers.google.com/web/progressive-web-apps/) 所需的那些功能也要求使用 HTTPS。 4 | 5 | ### TL;DR 6 | 7 | - 善意的或恶意的入侵者会利用您的网站和用户之间传输的每个未受保护的资源。 8 | - 许多入侵者都会查看汇总的行为以识别您的用户。 9 | - HTTPS 不仅可阻止您的网站被滥用,也是许多先进功能不可或缺的一部分,可作为类似应用功能(如服务工作线程)的实现技术。 10 | 11 | ## HTTPS 可保护您的网站的完整性。 12 | 13 | HTTPS 有助于防止入侵者篡改您的网站和用户浏览器之间的通信。 入侵者包括故意进行恶意攻击的攻击者,以及合法但具有侵犯性的公司,如将广告注入网页的 ISP 或酒店。 14 | 15 | 入侵者会利用未受保护的通信欺骗您的用户提供敏感信息或安装恶意软件,或将他们自己的广告插入您的资源中。例如,有些第三方向网站注入可能会损害用户体验和产生安全漏洞的广告。 16 | 17 | 入侵者会利用您的网站和用户之间传输的每个未受保护的资源。 图像、Cookie、脚本、HTML 等都会被利用。 入侵在网络中随时都会发生,包括入侵用户的电脑、Wi-Fi 热点或已泄露的 ISP 等。 18 | 19 | ## HTTPS 可保护您的用户的隐私和安全 20 | 21 | HTTPS 可防止入侵者能够被动地侦听您的网站和您的用户之间的通信。 22 | 23 | 人们对 HTTPS 有一个普遍的错误认识,认为只有处理敏感通信的网站才需要 HTTPS。 每个未受保护的 HTTP 请求都可能暴露与您的用户行为和身份有关的信息。尽管访问一次未受保护的网站可能看上去无害,但一些入侵者会查看汇总的用户浏览活动,以推断他们的行为和意图,从而进行[去匿名化](https://en.wikipedia.org/wiki/De-anonymization)攻击,查出匿名用户的身份。例如,员工可能在阅读未受保护的医疗文章时不经意地向其雇主泄露敏感的健康信息。 24 | 25 | ## HTTPS 是网络的未来发展方向 26 | 27 | 强大的全新网络平台功能,如拍照或使用 `getUserMedia()` 录制音频,或通过服务工作线程启用离线应用体验,或构建 Progressive Web App,在执行前均需要用户的明确许可。还将更新许多较旧的 API,以要求执行权限,如 [geolocation](https://developer.mozilla.org/en-US/docs/Web/API/Geolocation/Using_geolocation)API。HTTPS 是这些新功能和更新的 API 的权限工作流的一个关键组件。 -------------------------------------------------------------------------------- /前端/谷歌开发者工具/安全面板/了解安全问题.md: -------------------------------------------------------------------------------- 1 | # 了解安全问题 2 | 3 | HTTPS 为您的网站和将个人信息委托给您的网站的人提供了[重要的安全性和数据完整性](https://developers.google.com/web/fundamentals/security/encrypt-in-transit/why-https)。在 Chrome DevTools 中使用 Security 面板调试安全问题,确保您已在自己的网站上恰当地实现 HTTPS。 4 | 5 | ### TL;DR 6 | 7 | - 使用 Security Overview 可以立即查看当前页面是否安全。 8 | - 检查各个源以查看连接和证书详情(安全源)或找出具体哪些请求未受保护(非安全源)。 9 | 10 | ## Security Overview 11 | 12 | 要查看页面的整体安全性,请打开 DevTools,然后转至 Security 面板。 13 | 14 | 您首先会看到 Security Overview。Security Overview 会一目了然地告诉您页面是否安全。 安全页面会通过消息 `This page is secure (valid HTTPS).` 指示 15 | 16 | ![Security Overview,安全页面](https://developers.google.com/web/tools/chrome-devtools/images/overview-secure.png) 17 | 18 | 点击 **View certificate** 查看[主源](https://en.wikipedia.org/wiki/Same-origin_policy)的服务器证书。 19 | 20 | ![查看证书](https://developers.google.com/web/tools/chrome-devtools/images/view-certificate.png) 21 | 22 | 非安全页面会通过消息 `This page is not secure.` 指示 23 | 24 | Security 面板可以区分两种非安全页面。 如果请求的页面通过 HTTP 提供,则主源会被标记为不安全。 25 | 26 | ![Security Overview,非安全主源](https://developers.google.com/web/tools/chrome-devtools/images/overview-non-secure.png) 27 | 28 | 如果请求的页面通过 HTTPS 检索,但页面会继续使用 HTTP 检索其他源的内容,然后页面仍然会被标记为不安全。这称为[混合内容](https://developers.google.com/web/fundamentals/security/prevent-mixed-content/what-is-mixed-content)页面。 混合内容页面仅受部分保护,因为 HTTP 内容可以被嗅探器获取到且易受到中间人攻击。 29 | 30 | ![Security Overview,混合内容](https://developers.google.com/web/tools/chrome-devtools/images/overview-mixed.png) 31 | 32 | 点击 **View request in Network Panel** 打开 Network 面板的过滤视图,然后查看具体是哪些请求通过 HTTP 提供。 这将显示来自所有源的所有未受保护的请求。 33 | 34 | ![Network 面板,非安全资源,所有源](https://developers.google.com/web/tools/chrome-devtools/images/network-all.png) 35 | 36 | ## 检查源 37 | 38 | 使用左侧面板可以检查各个安全或非安全源。 39 | 40 | 点击安全源查看该源的连接和证书详情。 41 | 42 | ![源详情,安全](https://developers.google.com/web/tools/chrome-devtools/images/origin-detail-secure.png) 43 | 44 | 如果您点击非安全源,Security 面板会提供 Network 面板过滤视图的链接。 45 | 46 | ![源详情,非安全](https://developers.google.com/web/tools/chrome-devtools/images/origin-detail-non-secure.png) 47 | 48 | 点击链接可以查看具体是源的哪些请求通过 HTTP 提供。 49 | 50 | ![Network 面板,非安全资源,一个源](https://developers.google.com/web/tools/chrome-devtools/images/network-one.png) -------------------------------------------------------------------------------- /实战经验/新商城秒杀系统设计.md: -------------------------------------------------------------------------------- 1 | ## 新商城秒杀系统设计 2 | 3 | 4 | 5 | 上次跟大家聊到了商城秒杀系统遇到的问题。后来我的同事 tt 主持设计并实现了新的秒杀系统,用于服务接下来的秒杀活动。新的秒杀系统采用了之前说的异步提交设计,然后在系统的扩展性和抗压性上都做了比较充分的考虑和设计。在双十二的时候,整套系统轻松的应对了整点瞬时高压。这周我找 tt 约了个稿子,给大家聊聊新的秒杀系统的设计。 6 | 7 | 来,跟老王一起搬板凳听 tt 同学讲讲秒杀系统吧 ~ 8 | 9 | ==== 开始的分割线 ==== 10 | 11 | ## 秒杀系统的特点: 12 | 13 | 1 、大量请求同时发起 ( 高并发 ) ,服务器必须快速处理每一个请求,才能保证秒杀请求不超时; 14 | 15 | 2 、秒杀商品不能超卖,比如某个秒杀商品的数量是 100 个,如果不小心被秒了 1000 个商品出去,程序员的工资都不够赔啊。为了保证不超卖,必须有一个统一的地方排队减库存,比如通过通过数据库事务操作减库存; 16 | 17 | 3 、秒杀开始的一段时间,服务器请求压力突增会影响商城正常售卖处理。要解决高并发,可以增加机器进行负载分担,但是减库存是数据库单点操作,请求都会卡在数据库减库存操作上,最终导致所有请求处理变慢。 18 | 19 | ## 解决方案: 20 | 21 | 1 、解决高并发的请求接入问题: 22 | 23 | 通过 http 反向代理 ( 比如 nginx) 进行负载分担,并增加后端服务器的数量; 24 | 25 | 2 、解决数据库减库存阻塞请求的问题: 26 | 27 | 增加一个消息队列 (MQ) 服务,将秒杀请求先放到队列里,后端服务再慢慢的处理队列中的秒杀消息,并把抢购成功的请求 ( 队列最前面请求 ) 保存在数据库中备查。 MQ 就像一个巨大的蓄水池,将大量的并发请求先缓存下来,并且基本保持了请求的先后顺序。 28 | 29 | 而且 MQ 中的秒杀请求可以做优化处理,比如,当抢购商品的库存减为 0 的时候, MQ 中待处理的请求就可以简单的做失败处理,不需要再去数据库中做库存竞争了,数据库的处理压力只和抢购商品数量有关,抢购用户数量的增加并不会带来数据库压力的增加。 30 | 31 | 引入 MQ 之后用户的秒杀请求变成了异步操作,因此,需要客户端在发送秒杀请求后,再延迟发送结果查询请求,查询到秒杀成功的用户再跳转到购买链接完成购买操作,相当于秒杀的对象是一个购买机会,简化秒杀请求的处理过程。 32 | 33 | 3 、解决秒杀对商城的冲击将秒杀请求的处理服务和商城正常售卖服务进行物理隔离,增加新的三级域名隔离秒杀请求,就算秒杀系统过载,也不会影响到其他商品的正常售卖。 看一下秒杀系统的设计: 34 | 35 | ![img](http://og0sybnix.bkt.clouddn.com/VrUZNrj%20%281%29.jpg) 36 | 37 | 上图的“中间等待结果” 取值和意义如下: 38 | 39 | DIRECT_FAILED :直接失败,如:验证失败 ( 用户 token 等 ) ,未能进入 MQ 等; 40 | 41 | IN_QUEUE :已经加入消息队列,客户端需要延迟查询秒杀结果。 42 | 43 | “ 秒杀结果 ” 取值和意义如下: 44 | 45 | DIRECT_FAILED :基本验证失败; 46 | 47 | IN_QUEUE :该用户的秒杀请求仍然在队列中,还没有处理完成; 48 | 49 | BUY_FAILED :库存竞争失败,没有秒到; 50 | 51 | SUCCESS :秒杀成功,继续进行下单和付款操作。 52 | 53 | ### 设计解析: 54 | 55 | 1 、 秒杀服务器和售卖服务器部署上进行物理隔离,秒杀压力不会影响商城正常的 售卖服务; 56 | 57 | 2 、 在秒杀请求入队列之前,通过当前秒杀服务器记录的库存数据,对大量后到达 的请求直接返回秒杀失败,降低进入 MQ 的请求数量。 58 | 59 | 服务器本地记录的商品库存信息不能和数据库进行实时同步 ( 会处理影响性 能 ) ,所以不能判断当前实际库存是否大于 0 ,但是可以根据已经进入 MQ 的请求数量,判断后来的请求是否一定没有库存了,这里是一个判伪处理; 60 | 61 | 3 、 请求队列处理服务器可以通过适量的并发,在数据库中完成库存竞争并记录秒 杀成功的用户; 62 | 63 | 4 、 秒杀请求返回结果为 IN_QUEUE 的用户,延迟几秒后发起结果查询请求,这个查询已经没有并发压力了。秒杀结果的判定过程如下: 64 | 65 | 1) 数据库中有该用户的秒杀成功记录,则判定为秒杀成功。 66 | 67 | 2) 如果秒杀商品库存为 0 ,且数据库中还没有该用户的成功记录,则判定为秒杀失败。 68 | 69 | 3) 如果秒杀商品库存大于 0 ,且数据库中还没有该用户的成功记录,则返回 IN_QUEUE ,客户端稍后查询结果; 70 | 71 | 5 、 秒杀结果为成功的用户,跳转到售卖服务器,下单并支付完成购买流程。这个时候已经没有并发压力了; 72 | 73 | 6 、 售卖服务器会验证改用户是否抢购成功,防止作弊。 74 | 75 | 综上,通过 提前判伪,消息队列,延迟查询,结果验真 将并发压力拦截并稀释 掉并保证了结果的正确性。 76 | 77 | ## 秒杀系统实现过程中的其他优化措施: 78 | 79 | 1 、 在高并发处理过程中,尤其要注意锁的应用,尽量避免锁等待导致的线程切换。根据应用的场景,可以选择原子变量 ( 如计数器 ) ,读写锁,细粒度锁; 80 | 81 | 2 、 需要集中式验证的处理,比如验证当前库存是否大于零,可以通过本地缓存 的库存进行验伪; 82 | 83 | 3 、 应用本地缓存减少对外部系统 ( 数据库等 ) 的重复调用,比如 对 用户 token 合法性的验证,可以在秒杀开始之前通过 Ajax 发送预热请求,提前缓存好用 户 token 的验证结果,结合到负载分担服务器的会话保持,可以很大提高本地缓存的命中率。 84 | 85 | ==== 结束的分割线 ==== -------------------------------------------------------------------------------- /并发/Java 线程池框架核心代码分析.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/并发/Java 线程池框架核心代码分析.pdf -------------------------------------------------------------------------------- /并发/ThreadLocal/ThreadLocal 内存泄露的实例分析.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/并发/ThreadLocal/ThreadLocal 内存泄露的实例分析.pdf -------------------------------------------------------------------------------- /并发/ThreadLocal/深入分析 ThreadLocal 内存泄漏问题.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/并发/ThreadLocal/深入分析 ThreadLocal 内存泄漏问题.pdf -------------------------------------------------------------------------------- /并发/jdk8 版本并发源码解读/第七章 ReentrantLock总结.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/并发/jdk8 版本并发源码解读/第七章 ReentrantLock总结.pdf -------------------------------------------------------------------------------- /并发/jdk8 版本并发源码解读/第三章 CopyOnWriteArrayList源码解析.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/并发/jdk8 版本并发源码解读/第三章 CopyOnWriteArrayList源码解析.pdf -------------------------------------------------------------------------------- /并发/jdk8 版本并发源码解读/第二章 ConcurrentHashMap源码分析(JDK8版本).pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/并发/jdk8 版本并发源码解读/第二章 ConcurrentHashMap源码分析(JDK8版本).pdf -------------------------------------------------------------------------------- /并发/jdk8 版本并发源码解读/第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock().pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/并发/jdk8 版本并发源码解读/第五章 ReentrantLock源码解析1--获得非公平锁与公平锁lock().pdf -------------------------------------------------------------------------------- /并发/jdk8 版本并发源码解读/第六章 ReentrantLock源码解析2--释放锁unlock().pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/并发/jdk8 版本并发源码解读/第六章 ReentrantLock源码解析2--释放锁unlock().pdf -------------------------------------------------------------------------------- /并发/jdk8 版本并发源码解读/第四章 CopyOnWriteArraySet源码解析.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/并发/jdk8 版本并发源码解读/第四章 CopyOnWriteArraySet源码解析.pdf -------------------------------------------------------------------------------- /并发/访问 NULL 指针错误背后的原理.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/并发/访问 NULL 指针错误背后的原理.pdf -------------------------------------------------------------------------------- /开源框架源码分析/RocketMQ源码分析系列/RocketMQ学习(三):rocketmq-namesrv介绍.md: -------------------------------------------------------------------------------- 1 | ## RocketMQ学习(三):rocketmq-namesrv介绍 2 | 3 | 4 | 5 | *摘要:* 刚刚拉了最新的代码,版本是3.2.6,直接NamesrvStartup类的main()方法启动,不需要带启动参数,启动序列图如下: 当broker,producer,consumer都运行后,namesrv一共有8类线程: 1.ServerHouseKeepingService:守护线程,本质是ChannelEventListener,监听broker的channel变化来更新本地的RouteInfo。 6 | 7 | 刚刚拉了最新的代码,版本是3.2.6,直接NamesrvStartup类的main()方法启动,不需要带启动参数,启动序列图如下: 8 | 9 | ![namesrv_start](http://lifestack.cn/wp-content/uploads/2015/04/namesrv_start.jpg) 10 | 11 | 当broker,producer,consumer都运行后,namesrv一共有8类线程: 12 | 13 | 1.ServerHouseKeepingService:守护线程,本质是ChannelEventListener,监听broker的channel变化来更新本地的RouteInfo。 14 | 15 | 2.NSScheduledThread1:定时任务线程,定时跑2个任务,第一个是,每隔10分钟扫描出不活动的broker,然后从routeInfo中删除,第二个是,每个10分钟定时打印configTable的信息。 16 | 17 | 3.NettyBossSelector_1:Netty的boss线程(Accept线程),这里只有一根线程。 18 | 19 | 4.NettyEventExecuter:一个单独的线程,监听NettyChannel状态变化来通知ChannelEventListener做响应的动作。 20 | 21 | 5.DestroyJavaVM:java虚拟机析构钩子,一般是当虚拟机关闭时用来清理或者释放资源。 22 | 23 | 6.NettyServerSelector_x_x:Netty的Work线程(IO线程),这里可能有多根线程。 24 | 25 | 7.NettyServerWorkerThread_x:执行ChannelHandler方法的线程,ChannelHandler运行在该线程上,这里可能有多根线程。 26 | 27 | 8.RemotingExecutorThread_x:服务端逻辑线程,这里可能有多根线程。 28 | 29 | rocketmq-namesrv扮演着nameNode角色,记录运行时消息相关的meta信息以及broker和filtersrv运行时信息,可以部署集群。 -------------------------------------------------------------------------------- /开源框架源码分析/RocketMQ源码分析系列/RocketMQ学习(二):依赖关系和模块功能介绍.md: -------------------------------------------------------------------------------- 1 | ## RocketMQ学习(二):依赖关系和模块功能介绍 2 | 3 | 4 | 5 | *摘要:* 现在看的代码版本还是3.2.2 develop。先看张内部结构代码图: 从依赖层次再来看,越是被依赖的,越在底层: rocketmq包含9个子模块: rocketmq-common:通用的常量枚举、基类方法或者数据结构,按描述的目标来分包通俗易懂。 6 | 7 | 现在看的代码版本还是3.2.2 develop。先看张内部结构代码图: 8 | 9 | ![rocketmq内部依赖图](http://lifestack.cn/wp-content/uploads/2015/04/rocketmq%E5%86%85%E9%83%A8%E4%BE%9D%E8%B5%96%E5%9B%BE.jpg) 10 | 11 | 从依赖层次再来看,越是被依赖的,越在底层: 12 | 13 | ![层次结构](http://lifestack.cn/wp-content/uploads/2015/04/%E5%B1%82%E6%AC%A1%E7%BB%93%E6%9E%84.jpg) 14 | 15 | rocketmq包含9个子模块: 16 | 17 | rocketmq-common:通用的常量枚举、基类方法或者数据结构,按描述的目标来分包通俗易懂。包名有:admin,consumer,filter,hook,message等。 18 | 19 | rocketmq-remoting:用Netty4写的客户端和服务端,fastjson做的序列化,自定义二进制协议。 20 | 21 | rocketmq-srvutil:只有一个ServerUtil类,类注解是,只提供Server程序依赖,目的为了拆解客户端依赖,尽可能减少客户端的依赖。 22 | 23 | rocketmq-store:存储服务,消息存储,索引存储,commitLog存储。 24 | 25 | rocketmq-client:客户端,包含producer端和consumer端,发送消息和接收消息的过程。 26 | 27 | rocketmq-filtersrv:消息过滤器server,现在rocketmq的wiki上有示例代码及说明,https://github.com/alibaba/RocketMQ/wiki/filter_server_guide,以后会专门对每个模块做分析,到时出个完整的demo以及流程图。 28 | 29 | rocketmq-broker:对consumer和producer来说是服务端,接收producer发来的消息并存储,同时consumer来这里拉取消息。 30 | 31 | rocketmq-tools:命令行工具。 32 | 33 | rocketmq-namesrv:NameServer,类似SOA服务的注册中心,这里保存着消息的TopicName,队列等运行时的meta信息。一般系统分dataNode和nameNode,这里是nameNode。 34 | 35 | 这里可能说的比较粗糙,后面将会一一介绍。 -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/controller/JsonTest.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.controller; 2 | 3 | import com.iot.learnssm.firstssm.po.ItemsCustom; 4 | import org.springframework.stereotype.Controller; 5 | import org.springframework.web.bind.annotation.RequestBody; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | import org.springframework.web.bind.annotation.ResponseBody; 8 | 9 | /** 10 | * Created by brian on 2016/3/7. 11 | */ 12 | @Controller 13 | public class JsonTest { 14 | //请求json串(商品信息),输出json(商品信息) 15 | //@RequestBody将请求的商品信息的json串转成itemsCustom对象 16 | //@ResponseBody将itemsCustom转成json输出 17 | @RequestMapping("/requestJson") 18 | public 19 | @ResponseBody 20 | ItemsCustom requestJson(@RequestBody ItemsCustom itemsCustom) { 21 | 22 | //@ResponseBody将itemsCustom转成json输出 23 | return itemsCustom; 24 | } 25 | 26 | //请求key/value,输出json 27 | @RequestMapping("/responseJson") 28 | public 29 | @ResponseBody 30 | ItemsCustom responseJson(ItemsCustom itemsCustom) { 31 | 32 | //@ResponseBody将itemsCustom转成json输出 33 | return itemsCustom; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/controller/LoginController.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.controller; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | 6 | import javax.servlet.http.HttpSession; 7 | 8 | /** 9 | * Created by brian on 2016/3/8. 10 | */ 11 | @Controller 12 | public class LoginController { 13 | // 登陆 14 | @RequestMapping("/login") 15 | public String login(HttpSession session, String username, String password) 16 | throws Exception { 17 | 18 | // 调用service进行用户身份验证 19 | // ... 20 | 21 | // 在session中保存用户身份信息 22 | session.setAttribute("username", username); 23 | // 重定向到商品列表页面 24 | return "redirect:/items/queryItems.action"; 25 | } 26 | 27 | // 退出 28 | @RequestMapping("/logout") 29 | public String logout(HttpSession session) throws Exception { 30 | 31 | // 清除session 32 | session.invalidate(); 33 | 34 | // 重定向到商品列表页面 35 | return "redirect:/items/queryItems.action"; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/controller/MyJsonTest.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.controller; 2 | 3 | import com.iot.learnssm.firstssm.po.ItemsCustom; 4 | import com.iot.learnssm.firstssm.service.ItemsService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | 10 | import java.util.HashMap; 11 | import java.util.Map; 12 | 13 | /** 14 | * Created by Brian on 2016/3/11. 15 | */ 16 | @Controller 17 | public class MyJsonTest { 18 | @Autowired 19 | private ItemsService itemsService; 20 | 21 | @RequestMapping("/testJson") 22 | public 23 | @ResponseBody 24 | Object responseJson() throws Exception { 25 | class ResponseBody { 26 | String code = "10000"; 27 | String message = "成功"; 28 | Map result = new HashMap(); 29 | 30 | public Map getResult() { 31 | return result; 32 | } 33 | 34 | public void setResult(Map result) { 35 | this.result = result; 36 | } 37 | 38 | public String getCode() { 39 | return code; 40 | } 41 | 42 | public void setCode(String code) { 43 | this.code = code; 44 | } 45 | 46 | public String getMessage() { 47 | return message; 48 | } 49 | 50 | public void setMessage(String message) { 51 | this.message = message; 52 | } 53 | } 54 | 55 | ResponseBody responseBody = new ResponseBody(); 56 | ItemsCustom itemsCustom = itemsService.findItemsById(1); 57 | responseBody.getResult().put("itemsCustom", itemsCustom); 58 | return responseBody; 59 | 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/controller/converter/CustomDateConverter.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.controller.converter; 2 | 3 | import org.springframework.core.convert.converter.Converter; 4 | 5 | import java.text.ParseException; 6 | import java.text.SimpleDateFormat; 7 | import java.util.Date; 8 | 9 | /** 10 | * Created by brian on 2016/3/5. 11 | */ 12 | public class CustomDateConverter implements Converter { 13 | public Date convert(String s) { 14 | //实现 将日期串转成日期类型(格式是yyyy-MM-dd HH:mm:ss) 15 | 16 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 17 | 18 | try { 19 | //转成直接返回 20 | return simpleDateFormat.parse(s); 21 | } catch (ParseException e) { 22 | // TODO Auto-generated catch block 23 | e.printStackTrace(); 24 | } 25 | //如果参数绑定失败返回null 26 | return null; 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/controller/converter/validation/ValidGroup1.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.controller.converter.validation; 2 | 3 | /** 4 | * Created by brian on 2016/3/6. 5 | */ 6 | public interface ValidGroup1 { 7 | //接口中不需要定义任何方法,仅是对不同的校验规则进行分组 8 | //此分组只校验商品名称长度 9 | 10 | } 11 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/controller/converter/validation/ValidGroup2.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.controller.converter.validation; 2 | 3 | /** 4 | * Created by brian on 2016/3/6. 5 | */ 6 | public interface ValidGroup2 { 7 | //接口中不需要定义任何方法,仅是对不同的校验规则进行分组 8 | 9 | } 10 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/exception/CustomException.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.exception; 2 | 3 | /** 4 | * Created by brian on 2016/3/7. 5 | * 6 | * 系统 自定义异常类,针对预期的异常,需要在程序中抛出此类的异常 7 | */ 8 | public class CustomException extends Exception { 9 | //异常信息 10 | public String message; 11 | 12 | public CustomException(String message) { 13 | super(message); 14 | this.message = message; 15 | } 16 | 17 | public String getMessage() { 18 | return message; 19 | } 20 | 21 | public void setMessage(String message) { 22 | this.message = message; 23 | } 24 | 25 | } 26 | 27 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/exception/CustomExceptionResolver.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.exception; 2 | 3 | import org.springframework.web.servlet.HandlerExceptionResolver; 4 | import org.springframework.web.servlet.ModelAndView; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | /** 10 | * Created by brian on 2016/3/7. 11 | */ 12 | public class CustomExceptionResolver implements HandlerExceptionResolver { 13 | /** 14 | * @param request 15 | * @param response 16 | * @param handler 17 | * @param ex 系统抛出的异常 18 | * @return 19 | */ 20 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { 21 | //handler就是处理器适配器要执行Handler对象(只有method) 22 | //解析出异常类型 23 | //如果该 异常类型是系统 自定义的异常,直接取出异常信息,在错误页面展示 24 | //String message = null; 25 | //if(ex instanceof CustomException){ 26 | //message = ((CustomException)ex).getMessage(); 27 | //}else{ 28 | ////如果该 异常类型不是系统 自定义的异常,构造一个自定义的异常类型(信息为“未知错误”) 29 | //message="未知错误"; 30 | //} 31 | 32 | //上边代码变为 33 | CustomException customException; 34 | if (ex instanceof CustomException) { 35 | customException = (CustomException) ex; 36 | } else { 37 | customException = new CustomException("未知错误"); 38 | } 39 | 40 | //错误信息 41 | String message = customException.getMessage(); 42 | 43 | ModelAndView modelAndView = new ModelAndView(); 44 | 45 | //将错误信息传到页面 46 | modelAndView.addObject("message", message); 47 | 48 | //指向错误页面 49 | modelAndView.setViewName("error"); 50 | 51 | return modelAndView; 52 | 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/interceptor/HandlerInterceptor1.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.interceptor; 2 | 3 | import org.springframework.web.servlet.HandlerInterceptor; 4 | import org.springframework.web.servlet.ModelAndView; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | /** 10 | * Created by brian on 2016/3/7. 11 | */ 12 | public class HandlerInterceptor1 implements HandlerInterceptor { 13 | //进入 Handler方法之前执行 14 | //用于身份认证、身份授权 15 | //比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行 16 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 17 | 18 | System.out.println("HandlerInterceptor1...preHandle"); 19 | 20 | //return false表示拦截,不向下执行 21 | //return true表示放行 22 | return true; 23 | } 24 | 25 | //进入Handler方法之后,返回modelAndView之前执行 26 | //应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图 27 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 28 | throws Exception { 29 | System.out.println("HandlerInterceptor1...postHandle"); 30 | } 31 | 32 | //执行Handler完成执行此方法 33 | //应用场景:统一异常处理,统一日志处理 34 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 35 | System.out.println("HandlerInterceptor1...afterCompletion"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/interceptor/HandlerInterceptor2.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.interceptor; 2 | 3 | import org.springframework.web.servlet.HandlerInterceptor; 4 | import org.springframework.web.servlet.ModelAndView; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | 9 | /** 10 | * Created by brian on 2016/3/7. 11 | */ 12 | public class HandlerInterceptor2 implements HandlerInterceptor { 13 | //进入 Handler方法之前执行 14 | //用于身份认证、身份授权 15 | //比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行 16 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 17 | 18 | System.out.println("HandlerInterceptor2...preHandle"); 19 | 20 | //return false表示拦截,不向下执行 21 | //return true表示放行 22 | return true; 23 | } 24 | 25 | //进入Handler方法之后,返回modelAndView之前执行 26 | //应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图 27 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) 28 | throws Exception { 29 | System.out.println("HandlerInterceptor2...postHandle"); 30 | } 31 | 32 | //执行Handler完成执行此方法 33 | //应用场景:统一异常处理,统一日志处理 34 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { 35 | System.out.println("HandlerInterceptor2...afterCompletion"); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/interceptor/LoginInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.interceptor; 2 | 3 | import org.springframework.web.servlet.HandlerInterceptor; 4 | import org.springframework.web.servlet.ModelAndView; 5 | 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import javax.servlet.http.HttpSession; 9 | 10 | /** 11 | * Created by brian on 2016/3/8. 12 | * 登陆认证拦截器 13 | */ 14 | 15 | public class LoginInterceptor implements HandlerInterceptor { 16 | 17 | //进入 Handler方法之前执行 18 | //用于身份认证、身份授权 19 | //比如身份认证,如果认证通过表示当前用户没有登陆,需要此方法拦截不再向下执行 20 | public boolean preHandle(HttpServletRequest request, 21 | HttpServletResponse response, Object handler) throws Exception { 22 | 23 | //获取请求的url,这里是相对url,如"/ssm1/login.action" 24 | String url = request.getRequestURI(); 25 | //判断url是否是公开 地址(实际使用时将公开 地址配置配置文件中) 26 | //这里公开地址是登陆提交的地址 27 | if (url.indexOf("login.action") >= 0) { 28 | //如果进行登陆提交,放行 29 | return true; 30 | } 31 | 32 | //判断session 33 | HttpSession session = request.getSession(); 34 | //从session中取出用户身份信息 35 | String username = (String) session.getAttribute("username"); 36 | 37 | if (username != null) { 38 | //身份存在,放行 39 | return true; 40 | } 41 | 42 | //执行这里表示用户身份需要认证,跳转登陆页面 43 | request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response); 44 | 45 | //return false表示拦截,不向下执行 46 | //return true表示放行 47 | return false; 48 | } 49 | 50 | //进入Handler方法之后,返回modelAndView之前执行 51 | //应用场景从modelAndView出发:将公用的模型数据(比如菜单导航)在这里传到视图,也可以在这里统一指定视图 52 | public void postHandle(HttpServletRequest request, 53 | HttpServletResponse response, Object handler, 54 | ModelAndView modelAndView) throws Exception { 55 | 56 | System.out.println("LoginInterceptor...postHandle"); 57 | 58 | } 59 | 60 | //执行Handler完成执行此方法 61 | //应用场景:统一异常处理,统一日志处理 62 | public void afterCompletion(HttpServletRequest request, 63 | HttpServletResponse response, Object handler, Exception ex) 64 | throws Exception { 65 | 66 | System.out.println("LoginInterceptor...afterCompletion"); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/mapper/ItemsMapper.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.mapper; 2 | 3 | import com.iot.learnssm.firstssm.po.Items; 4 | import com.iot.learnssm.firstssm.po.ItemsExample; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | public interface ItemsMapper { 10 | int countByExample(ItemsExample example); 11 | 12 | int deleteByExample(ItemsExample example); 13 | 14 | int deleteByPrimaryKey(Integer id); 15 | 16 | int insert(Items record); 17 | 18 | int insertSelective(Items record); 19 | 20 | List selectByExampleWithBLOBs(ItemsExample example); 21 | 22 | List selectByExample(ItemsExample example); 23 | 24 | Items selectByPrimaryKey(Integer id); 25 | 26 | int updateByExampleSelective(@Param("record") Items record, @Param("example") ItemsExample example); 27 | 28 | int updateByExampleWithBLOBs(@Param("record") Items record, @Param("example") ItemsExample example); 29 | 30 | int updateByExample(@Param("record") Items record, @Param("example") ItemsExample example); 31 | 32 | int updateByPrimaryKeySelective(Items record); 33 | 34 | int updateByPrimaryKeyWithBLOBs(Items record); 35 | 36 | int updateByPrimaryKey(Items record); 37 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/mapper/ItemsMapperCustom.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.mapper; 2 | 3 | import com.iot.learnssm.firstssm.po.ItemsCustom; 4 | import com.iot.learnssm.firstssm.po.ItemsQueryVo; 5 | 6 | import java.util.List; 7 | 8 | public interface ItemsMapperCustom { 9 | //商品查询列表 10 | List findItemsList(ItemsQueryVo itemsQueryVo) throws Exception; 11 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/mapper/OrderdetailMapper.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.mapper; 2 | 3 | import com.iot.learnssm.firstssm.po.Orderdetail; 4 | import com.iot.learnssm.firstssm.po.OrderdetailExample; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | public interface OrderdetailMapper { 10 | int countByExample(OrderdetailExample example); 11 | 12 | int deleteByExample(OrderdetailExample example); 13 | 14 | int deleteByPrimaryKey(Integer id); 15 | 16 | int insert(Orderdetail record); 17 | 18 | int insertSelective(Orderdetail record); 19 | 20 | List selectByExample(OrderdetailExample example); 21 | 22 | Orderdetail selectByPrimaryKey(Integer id); 23 | 24 | int updateByExampleSelective(@Param("record") Orderdetail record, @Param("example") OrderdetailExample example); 25 | 26 | int updateByExample(@Param("record") Orderdetail record, @Param("example") OrderdetailExample example); 27 | 28 | int updateByPrimaryKeySelective(Orderdetail record); 29 | 30 | int updateByPrimaryKey(Orderdetail record); 31 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/mapper/OrdersMapper.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.mapper; 2 | 3 | import com.iot.learnssm.firstssm.po.Orders; 4 | import com.iot.learnssm.firstssm.po.OrdersExample; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | public interface OrdersMapper { 10 | int countByExample(OrdersExample example); 11 | 12 | int deleteByExample(OrdersExample example); 13 | 14 | int deleteByPrimaryKey(Integer id); 15 | 16 | int insert(Orders record); 17 | 18 | int insertSelective(Orders record); 19 | 20 | List selectByExample(OrdersExample example); 21 | 22 | Orders selectByPrimaryKey(Integer id); 23 | 24 | int updateByExampleSelective(@Param("record") Orders record, @Param("example") OrdersExample example); 25 | 26 | int updateByExample(@Param("record") Orders record, @Param("example") OrdersExample example); 27 | 28 | int updateByPrimaryKeySelective(Orders record); 29 | 30 | int updateByPrimaryKey(Orders record); 31 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.mapper; 2 | 3 | import com.iot.learnssm.firstssm.po.User; 4 | import com.iot.learnssm.firstssm.po.UserExample; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | public interface UserMapper { 10 | int countByExample(UserExample example); 11 | 12 | int deleteByExample(UserExample example); 13 | 14 | int deleteByPrimaryKey(Integer id); 15 | 16 | int insert(User record); 17 | 18 | int insertSelective(User record); 19 | 20 | List selectByExample(UserExample example); 21 | 22 | User selectByPrimaryKey(Integer id); 23 | 24 | int updateByExampleSelective(@Param("record") User record, @Param("example") UserExample example); 25 | 26 | int updateByExample(@Param("record") User record, @Param("example") UserExample example); 27 | 28 | int updateByPrimaryKeySelective(User record); 29 | 30 | int updateByPrimaryKey(User record); 31 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/po/Items.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.po; 2 | 3 | import com.iot.learnssm.firstssm.controller.converter.validation.ValidGroup1; 4 | 5 | import java.util.Date; 6 | import javax.validation.constraints.NotNull; 7 | import javax.validation.constraints.Size; 8 | 9 | public class Items { 10 | private Integer id; 11 | //校验名称在1到30字符中间 12 | //message是提示校验出错显示的信息 13 | //groups:此校验属于哪个分组,groups可以定义多个分组 14 | @Size(min = 1, max = 30, message = "{items.name.length.error}", groups = {ValidGroup1.class}) 15 | private String name; 16 | 17 | private Float price; 18 | 19 | private String pic; 20 | 21 | //非空校验 22 | @NotNull(message = "{items.createtime.isNUll}") 23 | private Date createtime; 24 | 25 | private String detail; 26 | 27 | public Integer getId() { 28 | return id; 29 | } 30 | 31 | public void setId(Integer id) { 32 | this.id = id; 33 | } 34 | 35 | public String getName() { 36 | return name; 37 | } 38 | 39 | public void setName(String name) { 40 | this.name = name == null ? null : name.trim(); 41 | } 42 | 43 | public Float getPrice() { 44 | return price; 45 | } 46 | 47 | public void setPrice(Float price) { 48 | this.price = price; 49 | } 50 | 51 | public String getPic() { 52 | return pic; 53 | } 54 | 55 | public void setPic(String pic) { 56 | this.pic = pic == null ? null : pic.trim(); 57 | } 58 | 59 | public Date getCreatetime() { 60 | return createtime; 61 | } 62 | 63 | public void setCreatetime(Date createtime) { 64 | this.createtime = createtime; 65 | } 66 | 67 | public String getDetail() { 68 | return detail; 69 | } 70 | 71 | public void setDetail(String detail) { 72 | this.detail = detail == null ? null : detail.trim(); 73 | } 74 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/po/ItemsCustom.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.po; 2 | 3 | /** 4 | * Created by Brian on 2016/3/2. 5 | * 商品信息的扩展类 6 | */ 7 | public class ItemsCustom extends Items { 8 | //添加商品信息的扩展属性 9 | } 10 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/po/ItemsQueryVo.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.po; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by Brian on 2016/3/2. 7 | */ 8 | public class ItemsQueryVo { 9 | 10 | //商品信息 11 | private Items items; 12 | 13 | //为了系统 可扩展性,对原始生成的po进行扩展 14 | private ItemsCustom itemsCustom; 15 | 16 | //批量商品信息 17 | private List itemsList; 18 | 19 | public Items getItems() { 20 | return items; 21 | } 22 | 23 | public void setItems(Items items) { 24 | this.items = items; 25 | } 26 | 27 | public ItemsCustom getItemsCustom() { 28 | return itemsCustom; 29 | } 30 | 31 | public void setItemsCustom(ItemsCustom itemsCustom) { 32 | this.itemsCustom = itemsCustom; 33 | } 34 | 35 | public List getItemsList() { 36 | return itemsList; 37 | } 38 | 39 | public void setItemsList(List itemsList) { 40 | this.itemsList = itemsList; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/po/Orderdetail.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.po; 2 | 3 | public class Orderdetail { 4 | private Integer id; 5 | 6 | private Integer ordersId; 7 | 8 | private Integer itemsId; 9 | 10 | private Integer itemsNum; 11 | 12 | public Integer getId() { 13 | return id; 14 | } 15 | 16 | public void setId(Integer id) { 17 | this.id = id; 18 | } 19 | 20 | public Integer getOrdersId() { 21 | return ordersId; 22 | } 23 | 24 | public void setOrdersId(Integer ordersId) { 25 | this.ordersId = ordersId; 26 | } 27 | 28 | public Integer getItemsId() { 29 | return itemsId; 30 | } 31 | 32 | public void setItemsId(Integer itemsId) { 33 | this.itemsId = itemsId; 34 | } 35 | 36 | public Integer getItemsNum() { 37 | return itemsNum; 38 | } 39 | 40 | public void setItemsNum(Integer itemsNum) { 41 | this.itemsNum = itemsNum; 42 | } 43 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/po/Orders.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.po; 2 | 3 | import java.util.Date; 4 | 5 | public class Orders { 6 | private Integer id; 7 | 8 | private Integer userId; 9 | 10 | private String number; 11 | 12 | private Date createtime; 13 | 14 | private String note; 15 | 16 | public Integer getId() { 17 | return id; 18 | } 19 | 20 | public void setId(Integer id) { 21 | this.id = id; 22 | } 23 | 24 | public Integer getUserId() { 25 | return userId; 26 | } 27 | 28 | public void setUserId(Integer userId) { 29 | this.userId = userId; 30 | } 31 | 32 | public String getNumber() { 33 | return number; 34 | } 35 | 36 | public void setNumber(String number) { 37 | this.number = number == null ? null : number.trim(); 38 | } 39 | 40 | public Date getCreatetime() { 41 | return createtime; 42 | } 43 | 44 | public void setCreatetime(Date createtime) { 45 | this.createtime = createtime; 46 | } 47 | 48 | public String getNote() { 49 | return note; 50 | } 51 | 52 | public void setNote(String note) { 53 | this.note = note == null ? null : note.trim(); 54 | } 55 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/po/User.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.po; 2 | 3 | import java.util.Date; 4 | 5 | public class User { 6 | private Integer id; 7 | 8 | private String username; 9 | 10 | private Date birthday; 11 | 12 | private String sex; 13 | 14 | private String address; 15 | 16 | public Integer getId() { 17 | return id; 18 | } 19 | 20 | public void setId(Integer id) { 21 | this.id = id; 22 | } 23 | 24 | public String getUsername() { 25 | return username; 26 | } 27 | 28 | public void setUsername(String username) { 29 | this.username = username == null ? null : username.trim(); 30 | } 31 | 32 | public Date getBirthday() { 33 | return birthday; 34 | } 35 | 36 | public void setBirthday(Date birthday) { 37 | this.birthday = birthday; 38 | } 39 | 40 | public String getSex() { 41 | return sex; 42 | } 43 | 44 | public void setSex(String sex) { 45 | this.sex = sex == null ? null : sex.trim(); 46 | } 47 | 48 | public String getAddress() { 49 | return address; 50 | } 51 | 52 | public void setAddress(String address) { 53 | this.address = address == null ? null : address.trim(); 54 | } 55 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/service/ItemsService.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.service; 2 | 3 | import com.iot.learnssm.firstssm.po.ItemsCustom; 4 | import com.iot.learnssm.firstssm.po.ItemsQueryVo; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Created by Brian on 2016/3/3. 10 | */ 11 | //@Service 12 | public interface ItemsService { 13 | //商品查询列表 14 | List findItemsList(ItemsQueryVo itemsQueryVo) throws Exception; 15 | 16 | //根据id查询商品信息 17 | 18 | /** 19 | *

Title: findItemsById

20 | *

Description:

21 | * 22 | * @param id 查询商品的id 23 | * @return 24 | * @throws Exception 25 | */ 26 | ItemsCustom findItemsById(Integer id) throws Exception; 27 | 28 | //修改商品信息 29 | 30 | /** 31 | *

Title: updateItems

32 | *

Description:

33 | * 34 | * @param id 修改商品的id 35 | * @param itemsCustom 修改的商品信息 36 | * @throws Exception 37 | */ 38 | void updateItems(Integer id, ItemsCustom itemsCustom) throws Exception; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/java/com/iot/learnssm/firstssm/service/impl/ItemsServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.iot.learnssm.firstssm.service.impl; 2 | 3 | import com.iot.learnssm.firstssm.exception.CustomException; 4 | import com.iot.learnssm.firstssm.mapper.ItemsMapper; 5 | import com.iot.learnssm.firstssm.mapper.ItemsMapperCustom; 6 | import com.iot.learnssm.firstssm.po.Items; 7 | import com.iot.learnssm.firstssm.po.ItemsCustom; 8 | import com.iot.learnssm.firstssm.po.ItemsQueryVo; 9 | import com.iot.learnssm.firstssm.service.ItemsService; 10 | import org.springframework.beans.BeanUtils; 11 | import org.springframework.beans.factory.annotation.Autowired; 12 | 13 | import java.util.List; 14 | 15 | /** 16 | * Created by Brian on 2016/3/3. 17 | */ 18 | public class ItemsServiceImpl implements ItemsService { 19 | 20 | @Autowired 21 | private ItemsMapperCustom itemsMapperCustom; 22 | 23 | @Autowired 24 | private ItemsMapper itemsMapper; 25 | 26 | public List findItemsList(ItemsQueryVo itemsQueryVo) throws Exception { 27 | return itemsMapperCustom.findItemsList(itemsQueryVo); 28 | } 29 | 30 | public ItemsCustom findItemsById(Integer id) throws Exception { 31 | Items items = itemsMapper.selectByPrimaryKey(id); 32 | if (items == null) { 33 | throw new CustomException("修改的商品信息不存在!"); 34 | } 35 | //中间对商品信息进行业务处理 36 | //.... 37 | //返回ItemsCustom 38 | ItemsCustom itemsCustom = null; 39 | //将items的属性值拷贝到itemsCustom 40 | if (items != null) { 41 | itemsCustom = new ItemsCustom(); 42 | BeanUtils.copyProperties(items, itemsCustom); 43 | } 44 | 45 | return itemsCustom; 46 | } 47 | 48 | public void updateItems(Integer id, ItemsCustom itemsCustom) throws Exception { 49 | //添加业务校验,通常在service接口对关键参数进行校验 50 | //校验 id是否为空,如果为空抛出异常 51 | 52 | //更新商品信息使用updateByPrimaryKeyWithBLOBs根据id更新items表中所有字段,包括 大文本类型字段 53 | //updateByPrimaryKeyWithBLOBs要求必须转入id 54 | itemsCustom.setId(id); 55 | itemsMapper.updateByPrimaryKeyWithBLOBs(itemsCustom); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/resources/CustomValidationMessages.properties: -------------------------------------------------------------------------------- 1 | #\u6DFB\u52A0\u6821\u9A8C\u7684\u9519\u8BEF\u63D0\u793A\u4FE1\u606F 2 | items.name.length.error=\u8BF7\u8F93\u51651\u523030\u4E2A\u5B57\u7B26\u7684\u5546\u54C1\u540D\u79F0 3 | items.createtime.isNUll=\u8BF7\u8F93\u5165\u5546\u54C1\u7684\u751F\u4EA7\u65E5\u671F 4 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/resources/com/iot/learnssm/firstssm/mapper/ItemsMapperCustom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | items.name LIKE '%${itemsCustom.name}%' 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 28 | 29 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/resources/db.properties: -------------------------------------------------------------------------------- 1 | jdbc.driver=com.mysql.jdbc.Driver 2 | jdbc.url=jdbc:mysql://localhost:3306/mybatis001?characterEncoding=utf-8 3 | jdbc.username=root 4 | jdbc.password=123 5 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/resources/log4j.properties: -------------------------------------------------------------------------------- 1 | # Global logging configuration 2 | log4j.rootLogger=DEBUG, stdout 3 | # Console output... 4 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 5 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n 7 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/resources/mybatis/sqlMapConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | 23 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/resources/spring/applicationContext-dao.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/resources/spring/applicationContext-service.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/resources/spring/applicationContext-transaction.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/webapp/WEB-INF/jsp/error.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: Brian 4 | Date: 2016/3/4 5 | Time: 10:51 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | 错误提示 12 | 13 | 14 | ${message} 15 | 16 | 17 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/webapp/WEB-INF/jsp/items/editItems.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8" %> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 4 | <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> 5 | 6 | 7 | 8 | 9 | 修改商品信息 10 | 11 | 12 | 13 | 14 | 15 | 16 | ${ error.defaultMessage}
17 |
18 |
19 |
20 | 21 | 修改商品信息: 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | 45 | 46 | 47 | 48 | 51 | 52 | 53 | 55 | 56 |
商品名称
商品价格
商品生产日期"/> 34 |
商品图片 39 | 40 | 41 |
42 |
43 | 44 |
商品简介 49 | 50 |
54 |
57 | 58 |
59 | 60 | 61 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/webapp/WEB-INF/jsp/items/editItemsQuery.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8" %> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 4 | <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> 5 | 6 | 7 | 8 | 9 | 查询商品列表 10 | 22 | 23 | 24 |
25 | 查询条件: 26 | 27 | 28 | 29 | 33 | 34 |
商品名称: 30 | 31 | 32 |
35 | 商品列表: 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 51 | 52 | 53 | 54 | 55 | 56 |
商品名称商品价格生产日期商品描述操作
"/>
57 |
58 | 59 | 60 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/webapp/WEB-INF/jsp/login.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: brian 4 | Date: 2016/3/8 5 | Time: 0:13 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | 系统登陆 12 | 13 | 14 |
15 | 用户账号:
16 | 用户密码 :
17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/webapp/WEB-INF/jsp/success.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: Brian 4 | Date: 2016/3/4 5 | Time: 10:51 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | 成功提示 12 | 13 | 14 | 操作成功! 15 | 16 | 17 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/learnssm-firstssm/src/main/webapp/jsonTest.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: brian 4 | Date: 2016/3/7 5 | Time: 20:49 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | 12 | json交互测试 13 | 14 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-generator/lib/log4j-1.2.16.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-generator/lib/log4j-1.2.16.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-generator/lib/mybatis-3.2.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-generator/lib/mybatis-3.2.3.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-generator/lib/mybatis-generator-core-1.3.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-generator/lib/mybatis-generator-core-1.3.2.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-generator/lib/mysql-connector-java-5.1.28-bin.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-generator/lib/mysql-connector-java-5.1.28-bin.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-generator/lib/ojdbc14.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-generator/lib/ojdbc14.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-generator/src/GeneratorSqlmap.java: -------------------------------------------------------------------------------- 1 | import org.mybatis.generator.api.MyBatisGenerator; 2 | import org.mybatis.generator.config.Configuration; 3 | import org.mybatis.generator.config.xml.ConfigurationParser; 4 | import org.mybatis.generator.internal.DefaultShellCallback; 5 | 6 | import java.io.File; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class GeneratorSqlmap { 11 | 12 | public void generator() throws Exception { 13 | 14 | List warnings = new ArrayList(); 15 | boolean overwrite = true; 16 | //指定逆向工程配置文件 17 | File configFile = new File("generatorConfig-base.xml"); 18 | ConfigurationParser cp = new ConfigurationParser(warnings); 19 | Configuration config = cp.parseConfiguration(configFile); 20 | DefaultShellCallback callback = new DefaultShellCallback(overwrite); 21 | MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, 22 | callback, warnings); 23 | myBatisGenerator.generate(null); 24 | 25 | } 26 | 27 | public static void main(String[] args) throws Exception { 28 | try { 29 | GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap(); 30 | generatorSqlmap.generator(); 31 | } catch (Exception e) { 32 | e.printStackTrace(); 33 | } 34 | 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-generator/src/log4j.properties: -------------------------------------------------------------------------------- 1 | log4j.rootLogger=DEBUG, Console 2 | #Console 3 | log4j.appender.Console=org.apache.log4j.ConsoleAppender 4 | log4j.appender.Console.layout=org.apache.log4j.PatternLayout 5 | log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n 6 | log4j.logger.java.sql.ResultSet=INFO 7 | log4j.logger.org.apache=INFO 8 | log4j.logger.java.sql.Connection=DEBUG 9 | log4j.logger.java.sql.Statement=DEBUG 10 | log4j.logger.java.sql.PreparedStatement=DEBUG -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/config/db.properties: -------------------------------------------------------------------------------- 1 | jdbc.driver=com.mysql.jdbc.Driver 2 | jdbc.url=jdbc:mysql://localhost:3306/mybatis001?characterEncoding=utf-8 3 | jdbc.username=root 4 | jdbc.password=123 5 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/config/log4j.properties: -------------------------------------------------------------------------------- 1 | # Global logging configuration 2 | log4j.rootLogger=DEBUG, stdout 3 | # Console output... 4 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 5 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n 7 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/config/mybatis/SqlMapConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/config/spring/applicationContext.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 12 | 13 | 14 | 15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 42 | 43 | 48 | 49 | 53 | 54 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/config/sqlmap/User.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 10 | 11 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/aopalliance-1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/aopalliance-1.0.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/asm-3.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/asm-3.3.1.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/aspectjweaver-1.6.11.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/aspectjweaver-1.6.11.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/cglib-2.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/cglib-2.2.2.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/commons-dbcp-1.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/commons-dbcp-1.2.2.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/commons-logging-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/commons-logging-1.1.1.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/commons-pool-1.3.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/commons-pool-1.3.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/javassist-3.17.1-GA.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/javassist-3.17.1-GA.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/jstl-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/jstl-1.2.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/junit-4.9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/junit-4.9.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/log4j-1.2.17.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/log4j-1.2.17.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/log4j-api-2.0-rc1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/log4j-api-2.0-rc1.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/log4j-core-2.0-rc1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/log4j-core-2.0-rc1.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/mybatis-3.2.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/mybatis-3.2.7.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/mybatis-spring-1.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/mybatis-spring-1.2.2.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/mysql-connector-java-5.1.7-bin.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/mysql-connector-java-5.1.7-bin.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/slf4j-api-1.7.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/slf4j-api-1.7.5.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/slf4j-log4j12-1.7.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/slf4j-log4j12-1.7.5.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-aop-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-aop-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-aspects-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-aspects-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-beans-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-beans-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-context-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-context-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-context-support-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-context-support-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-core-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-core-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-expression-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-expression-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-jdbc-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-jdbc-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-orm-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-orm-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-test-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-test-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-tx-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-tx-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-web-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-web-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-webmvc-3.2.0.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis-spring/lib/spring-webmvc-3.2.0.RELEASE.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/src/com/iot/ssm/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.dao; 2 | 3 | import com.iot.ssm.po.User; 4 | 5 | /** 6 | * Created by Brian on 2016/2/24. 7 | */ 8 | public interface UserDao { 9 | //根据id查询用户信息 10 | public User findUserById(int id) throws Exception; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/src/com/iot/ssm/dao/UserDaoImpl.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.dao; 2 | 3 | import com.iot.ssm.po.User; 4 | import org.apache.ibatis.session.SqlSession; 5 | import org.mybatis.spring.support.SqlSessionDaoSupport; 6 | 7 | /** 8 | * Created by Brian on 2016/2/24. 9 | */ 10 | public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao { 11 | 12 | @Override 13 | public User findUserById(int id) throws Exception { 14 | //继承SqlSessionDaoSupport,通过this.getSqlSession()得到sqlSessoin 15 | SqlSession sqlSession = this.getSqlSession(); 16 | User user = sqlSession.selectOne("test.findUserById", id); 17 | 18 | return user; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/src/com/iot/ssm/mapper/ItemsMapper.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.mapper; 2 | 3 | import com.iot.ssm.po.Items; 4 | import com.iot.ssm.po.ItemsExample; 5 | import org.apache.ibatis.annotations.Param; 6 | 7 | import java.util.List; 8 | 9 | public interface ItemsMapper { 10 | int countByExample(ItemsExample example); 11 | 12 | int deleteByExample(ItemsExample example); 13 | 14 | int deleteByPrimaryKey(Integer id); 15 | 16 | int insert(Items record); 17 | 18 | int insertSelective(Items record); 19 | 20 | List selectByExampleWithBLOBs(ItemsExample example); 21 | 22 | List selectByExample(ItemsExample example); 23 | 24 | Items selectByPrimaryKey(Integer id); 25 | 26 | int updateByExampleSelective(@Param("record") Items record, @Param("example") ItemsExample example); 27 | 28 | int updateByExampleWithBLOBs(@Param("record") Items record, @Param("example") ItemsExample example); 29 | 30 | int updateByExample(@Param("record") Items record, @Param("example") ItemsExample example); 31 | 32 | int updateByPrimaryKeySelective(Items record); 33 | 34 | int updateByPrimaryKeyWithBLOBs(Items record); 35 | 36 | int updateByPrimaryKey(Items record); 37 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/src/com/iot/ssm/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.mapper; 2 | 3 | import com.iot.ssm.po.User; 4 | 5 | /** 6 | * Created by Brian on 2016/2/24. 7 | */ 8 | public interface UserMapper { 9 | //根据id查询用户信息 10 | User findUserById(int id) throws Exception; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/src/com/iot/ssm/mapper/UserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/src/com/iot/ssm/po/Items.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.po; 2 | 3 | import java.util.Date; 4 | 5 | public class Items { 6 | private Integer id; 7 | 8 | private String name; 9 | 10 | private Float price; 11 | 12 | private String pic; 13 | 14 | private Date createtime; 15 | 16 | private String detail; 17 | 18 | public Integer getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Integer id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(String name) { 31 | this.name = name == null ? null : name.trim(); 32 | } 33 | 34 | public Float getPrice() { 35 | return price; 36 | } 37 | 38 | public void setPrice(Float price) { 39 | this.price = price; 40 | } 41 | 42 | public String getPic() { 43 | return pic; 44 | } 45 | 46 | public void setPic(String pic) { 47 | this.pic = pic == null ? null : pic.trim(); 48 | } 49 | 50 | public Date getCreatetime() { 51 | return createtime; 52 | } 53 | 54 | public void setCreatetime(Date createtime) { 55 | this.createtime = createtime; 56 | } 57 | 58 | public String getDetail() { 59 | return detail; 60 | } 61 | 62 | public void setDetail(String detail) { 63 | this.detail = detail == null ? null : detail.trim(); 64 | } 65 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/src/com/iot/ssm/po/User.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.po; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * Created by Administrator on 2016/2/21. 8 | */ 9 | public class User implements Serializable { 10 | //属性名要和数据库表的字段对应 11 | private int id; 12 | private String username;// 用户姓名 13 | private String sex;// 性别 14 | private Date birthday;// 生日 15 | private String address;// 地址 16 | 17 | //用户创建的订单列表 18 | //private List ordersList; 19 | 20 | public int getId() { 21 | return id; 22 | } 23 | 24 | public void setId(int id) { 25 | this.id = id; 26 | } 27 | 28 | public String getUsername() { 29 | return username; 30 | } 31 | 32 | public void setUsername(String username) { 33 | this.username = username; 34 | } 35 | 36 | public String getSex() { 37 | return sex; 38 | } 39 | 40 | public void setSex(String sex) { 41 | this.sex = sex; 42 | } 43 | 44 | public Date getBirthday() { 45 | return birthday; 46 | } 47 | 48 | public void setBirthday(Date birthday) { 49 | this.birthday = birthday; 50 | } 51 | 52 | public String getAddress() { 53 | return address; 54 | } 55 | 56 | public void setAddress(String address) { 57 | this.address = address; 58 | } 59 | 60 | //public List getOrdersList() { 61 | // return ordersList; 62 | //} 63 | // 64 | //public void setOrdersList(List ordersList) { 65 | // this.ordersList = ordersList; 66 | //} 67 | 68 | @Override 69 | public String toString() { 70 | return "User [id=" + id + ", username=" + username + ", sex=" + sex 71 | + ", birthday=" + birthday + ", address=" + address + "]"; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/test/com/iot/ssm/dao/UserDaoImplTest.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.dao; 2 | 3 | import com.iot.ssm.po.User; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | import org.springframework.context.ApplicationContext; 7 | import org.springframework.context.support.ClassPathXmlApplicationContext; 8 | 9 | public class UserDaoImplTest { 10 | 11 | private ApplicationContext applicationContext; 12 | 13 | //在setUp这个方法得到spring容器 14 | @Before 15 | public void setUp() throws Exception { 16 | applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml"); 17 | } 18 | 19 | @Test 20 | public void testFindUserById() throws Exception { 21 | // 创建UserDao的对象 22 | UserDao userDao = (UserDao) applicationContext.getBean("userDao"); 23 | 24 | // 调用UserDao的方法 25 | User user = userDao.findUserById(1); 26 | 27 | System.out.println(user); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/test/com/iot/ssm/mapper/ItemsMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.mapper; 2 | 3 | import com.iot.ssm.po.Items; 4 | import com.iot.ssm.po.ItemsExample; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | import org.springframework.context.ApplicationContext; 8 | import org.springframework.context.support.ClassPathXmlApplicationContext; 9 | 10 | import java.util.Date; 11 | import java.util.List; 12 | 13 | public class ItemsMapperTest { 14 | 15 | private ApplicationContext applicationContext; 16 | 17 | private ItemsMapper itemsMapper; 18 | 19 | //在setUp这个方法得到spring容器 20 | @Before 21 | public void setUp() throws Exception { 22 | applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml"); 23 | itemsMapper = (ItemsMapper) applicationContext.getBean("itemsMapper"); 24 | } 25 | 26 | //根据主键删除 27 | @Test 28 | public void testDeleteByPrimaryKey() { 29 | 30 | } 31 | 32 | //插入 33 | @Test 34 | public void testInsert() { 35 | //构造 items对象 36 | Items items = new Items(); 37 | items.setName("手机"); 38 | items.setPrice(999f); 39 | items.setCreatetime(new Date()); 40 | itemsMapper.insert(items); 41 | } 42 | 43 | //自定义条件查询 44 | @Test 45 | public void testSelectByExample() { 46 | ItemsExample itemsExample = new ItemsExample(); 47 | //通过criteria构造查询条件 48 | ItemsExample.Criteria criteria = itemsExample.createCriteria(); 49 | criteria.andNameEqualTo("笔记本"); 50 | //可能返回多条记录 51 | List list = itemsMapper.selectByExample(itemsExample); 52 | 53 | System.out.println(list); 54 | 55 | } 56 | 57 | //根据主键查询 58 | @Test 59 | public void testSelectByPrimaryKey() { 60 | Items items = itemsMapper.selectByPrimaryKey(1); 61 | System.out.println(items); 62 | } 63 | 64 | //更新数据 65 | @Test 66 | public void testUpdateByPrimaryKey() { 67 | 68 | //对所有字段进行更新,需要先查询出来再更新 69 | Items items = itemsMapper.selectByPrimaryKey(1); 70 | 71 | items.setName("手机"); 72 | 73 | itemsMapper.updateByPrimaryKey(items); 74 | //如果传入字段不空为才更新,在批量更新中使用此方法,不需要先查询再更新 75 | //itemsMapper.updateByPrimaryKeySelective(record); 76 | 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis-spring/test/com/iot/ssm/mapper/UserMapperTest.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.mapper; 2 | 3 | import com.iot.ssm.po.User; 4 | import org.junit.Before; 5 | import org.junit.Test; 6 | import org.springframework.context.ApplicationContext; 7 | import org.springframework.context.support.ClassPathXmlApplicationContext; 8 | 9 | public class UserMapperTest { 10 | 11 | private ApplicationContext applicationContext; 12 | 13 | //在setUp这个方法得到spring容器 14 | @Before 15 | public void setUp() throws Exception { 16 | applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml"); 17 | } 18 | 19 | @Test 20 | public void testFindUserById() throws Exception { 21 | 22 | UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper"); 23 | 24 | //调用userMapper的方法 25 | 26 | User user = userMapper.findUserById(1); 27 | 28 | System.out.println(user); 29 | 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/config/db.properties: -------------------------------------------------------------------------------- 1 | jdbc.driver=com.mysql.jdbc.Driver 2 | jdbc.url=jdbc:mysql://localhost:3306/mybatis001?characterEncoding=utf-8 3 | jdbc.username=root 4 | jdbc.password=123 5 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/config/ehcache.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/config/log4j.properties: -------------------------------------------------------------------------------- 1 | # Global logging configuration 2 | log4j.rootLogger=DEBUG, stdout 3 | # Console output... 4 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 5 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 6 | log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n 7 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/asm-3.3.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/asm-3.3.1.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/cglib-2.2.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/cglib-2.2.2.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/commons-logging-1.1.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/commons-logging-1.1.1.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/ehcache-core-2.6.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/ehcache-core-2.6.5.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/javassist-3.17.1-GA.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/javassist-3.17.1-GA.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/junit-4.9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/junit-4.9.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/log4j-1.2.17.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/log4j-1.2.17.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/log4j-api-2.0-rc1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/log4j-api-2.0-rc1.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/log4j-core-2.0-rc1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/log4j-core-2.0-rc1.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/mybatis-3.2.7.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/mybatis-3.2.7.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/mybatis-ehcache-1.0.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/mybatis-ehcache-1.0.2.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/mysql-connector-java-5.1.7-bin.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/mysql-connector-java-5.1.7-bin.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/slf4j-api-1.7.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/slf4j-api-1.7.5.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/lib/slf4j-log4j12-1.7.5.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/mybatis/lib/slf4j-log4j12-1.7.5.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.dao; 2 | 3 | import com.iot.mybatis.po.User; 4 | 5 | import java.util.List; 6 | 7 | /** 8 | * Created by Brian on 2016/2/24. 9 | */ 10 | public interface UserDao { 11 | //根据id查询用户信息 12 | public User findUserById(int id) throws Exception; 13 | 14 | //根据用户名列查询用户列表 15 | public List findUserByName(String name) throws Exception; 16 | 17 | //添加用户信息 18 | public void insertUser(User user) throws Exception; 19 | 20 | //删除用户信息 21 | public void deleteUser(int id) throws Exception; 22 | } 23 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/dao/UserDaoImpl.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.dao; 2 | 3 | import com.iot.mybatis.po.User; 4 | import org.apache.ibatis.session.SqlSession; 5 | import org.apache.ibatis.session.SqlSessionFactory; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by Brian on 2016/2/24. 11 | */ 12 | public class UserDaoImpl implements UserDao { 13 | // 需要向dao实现类中注入SqlSessionFactory 14 | // 这里通过构造方法注入 15 | private SqlSessionFactory sqlSessionFactory; 16 | 17 | public UserDaoImpl(SqlSessionFactory sqlSessionFactory) { 18 | this.sqlSessionFactory = sqlSessionFactory; 19 | } 20 | 21 | @Override 22 | public User findUserById(int id) throws Exception { 23 | SqlSession sqlSession = sqlSessionFactory.openSession(); 24 | User user = sqlSession.selectOne("test.findUserById", id); 25 | //释放资源 26 | sqlSession.close(); 27 | return user; 28 | } 29 | 30 | @Override 31 | public List findUserByName(String name) throws Exception { 32 | SqlSession sqlSession = sqlSessionFactory.openSession(); 33 | 34 | List list = sqlSession.selectList("test.findUserByName", name); 35 | 36 | // 释放资源 37 | sqlSession.close(); 38 | 39 | return list; 40 | } 41 | 42 | @Override 43 | public void insertUser(User user) throws Exception { 44 | SqlSession sqlSession = sqlSessionFactory.openSession(); 45 | //执行插入操作 46 | sqlSession.insert("test.insertUser", user); 47 | 48 | // 提交事务 49 | sqlSession.commit(); 50 | 51 | // 释放资源 52 | sqlSession.close(); 53 | } 54 | 55 | @Override 56 | public void deleteUser(int id) throws Exception { 57 | SqlSession sqlSession = sqlSessionFactory.openSession(); 58 | 59 | //执行插入操作 60 | sqlSession.delete("test.deleteUser", id); 61 | 62 | // 提交事务 63 | sqlSession.commit(); 64 | 65 | // 释放资源 66 | sqlSession.close(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/mapper/OrdersMapperCustom.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.mapper; 2 | 3 | import com.iot.mybatis.po.Orders; 4 | import com.iot.mybatis.po.OrdersCustom; 5 | import com.iot.mybatis.po.User; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by Brian on 2016/2/25. 11 | */ 12 | public interface OrdersMapperCustom { 13 | //查询订单关联查询用户信息 14 | public List findOrdersUser() throws Exception; 15 | 16 | //查询订单关联查询用户使用resultMap 17 | public List findOrdersUserResultMap() throws Exception; 18 | 19 | //查询订单(关联用户)及订单明细 20 | public List findOrdersAndOrderDetailResultMap() throws Exception; 21 | 22 | //查询用户购买商品信息 23 | public List findUserAndItemsResultMap() throws Exception; 24 | 25 | //查询订单关联查询用户,用户信息是延迟加载 26 | public List findOrdersUserLazyLoading() throws Exception; 27 | 28 | } 29 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.mapper; 2 | 3 | import com.iot.mybatis.po.User; 4 | import com.iot.mybatis.po.UserCustom; 5 | import com.iot.mybatis.po.UserQueryVo; 6 | 7 | import java.util.List; 8 | 9 | /** 10 | * Created by Brian on 2016/2/24. 11 | */ 12 | public interface UserMapper { 13 | //根据id查询用户信息 14 | public User findUserById(int id) throws Exception; 15 | 16 | //根据用户名列查询用户列表 17 | public List findUserByName(String name) throws Exception; 18 | 19 | //添加用户信息 20 | public void insertUser(User user) throws Exception; 21 | 22 | //删除用户信息 23 | public void deleteUser(int id) throws Exception; 24 | 25 | //更新用户 26 | public void updateUser(User user) throws Exception; 27 | 28 | //用户信息综合查询 29 | public List findUserList(UserQueryVo userQueryVo) throws Exception; 30 | 31 | //用户信息综合查询总数 32 | public int findUserCount(UserQueryVo userQueryVo) throws Exception; 33 | 34 | //根据id查询用户信息,使用resultMap输出 35 | public User findUserByIdResultMap(int id) throws Exception; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/po/Items.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.po; 2 | 3 | import java.util.Date; 4 | 5 | public class Items { 6 | private Integer id; 7 | 8 | private String name; 9 | 10 | private Float price; 11 | 12 | private String pic; 13 | 14 | private Date createtime; 15 | 16 | private String detail; 17 | 18 | public Integer getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Integer id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(String name) { 31 | this.name = name == null ? null : name.trim(); 32 | } 33 | 34 | public Float getPrice() { 35 | return price; 36 | } 37 | 38 | public void setPrice(Float price) { 39 | this.price = price; 40 | } 41 | 42 | public String getPic() { 43 | return pic; 44 | } 45 | 46 | public void setPic(String pic) { 47 | this.pic = pic == null ? null : pic.trim(); 48 | } 49 | 50 | public Date getCreatetime() { 51 | return createtime; 52 | } 53 | 54 | public void setCreatetime(Date createtime) { 55 | this.createtime = createtime; 56 | } 57 | 58 | public String getDetail() { 59 | return detail; 60 | } 61 | 62 | public void setDetail(String detail) { 63 | this.detail = detail == null ? null : detail.trim(); 64 | } 65 | 66 | @Override 67 | public String toString() { 68 | return "Items [id=" + id + ", name=" + name + ", price=" + price 69 | + ", pic=" + pic + ", createtime=" + createtime + ", detail=" 70 | + detail + "]"; 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/po/Orderdetail.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.po; 2 | 3 | public class Orderdetail { 4 | private Integer id; 5 | 6 | private Integer ordersId; 7 | 8 | private Integer itemsId; 9 | 10 | private Integer itemsNum; 11 | 12 | //明细对应的商品信息 13 | private Items items; 14 | 15 | public Integer getId() { 16 | return id; 17 | } 18 | 19 | public void setId(Integer id) { 20 | this.id = id; 21 | } 22 | 23 | public Integer getOrdersId() { 24 | return ordersId; 25 | } 26 | 27 | public void setOrdersId(Integer ordersId) { 28 | this.ordersId = ordersId; 29 | } 30 | 31 | public Integer getItemsId() { 32 | return itemsId; 33 | } 34 | 35 | public void setItemsId(Integer itemsId) { 36 | this.itemsId = itemsId; 37 | } 38 | 39 | public Integer getItemsNum() { 40 | return itemsNum; 41 | } 42 | 43 | public void setItemsNum(Integer itemsNum) { 44 | this.itemsNum = itemsNum; 45 | } 46 | 47 | public Items getItems() { 48 | return items; 49 | } 50 | 51 | public void setItems(Items items) { 52 | this.items = items; 53 | } 54 | 55 | @Override 56 | public String toString() { 57 | return "Orderdetail [id=" + id + ", ordersId=" + ordersId 58 | + ", itemsId=" + itemsId + ", itemsNum=" + itemsNum + "]"; 59 | } 60 | 61 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/po/Orders.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.po; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | public class Orders { 7 | private Integer id; 8 | 9 | private Integer userId; 10 | 11 | private String number; 12 | 13 | private Date createtime; 14 | 15 | private String note; 16 | 17 | //用户信息 18 | private User user; 19 | 20 | //订单明细 21 | private List orderdetails; 22 | 23 | public Integer getId() { 24 | return id; 25 | } 26 | 27 | public void setId(Integer id) { 28 | this.id = id; 29 | } 30 | 31 | public Integer getUserId() { 32 | return userId; 33 | } 34 | 35 | public void setUserId(Integer userId) { 36 | this.userId = userId; 37 | } 38 | 39 | public String getNumber() { 40 | return number; 41 | } 42 | 43 | public void setNumber(String number) { 44 | this.number = number == null ? null : number.trim(); 45 | } 46 | 47 | public Date getCreatetime() { 48 | return createtime; 49 | } 50 | 51 | public void setCreatetime(Date createtime) { 52 | this.createtime = createtime; 53 | } 54 | 55 | public String getNote() { 56 | return note; 57 | } 58 | 59 | public void setNote(String note) { 60 | this.note = note == null ? null : note.trim(); 61 | } 62 | 63 | public User getUser() { 64 | return user; 65 | } 66 | 67 | public void setUser(User user) { 68 | this.user = user; 69 | } 70 | 71 | public List getOrderdetails() { 72 | return orderdetails; 73 | } 74 | 75 | public void setOrderdetails(List orderdetails) { 76 | this.orderdetails = orderdetails; 77 | } 78 | 79 | //public void print(){ 80 | // System.out.println("----test-print-----"+user+" user==null: "+(user==null)); 81 | //} 82 | 83 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/po/OrdersCustom.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.po; 2 | 3 | /** 4 | *

Title: OrdersCustom

5 | *

Description: 订单的扩展类

6 | */ 7 | //通过此类映射订单和用户查询的结果,让此类继承包括 字段较多的pojo类 8 | public class OrdersCustom extends Orders { 9 | 10 | //添加用户属性 11 | /*USER.username, 12 | USER.sex, 13 | USER.address */ 14 | 15 | private String username; 16 | private String sex; 17 | private String address; 18 | 19 | public String getUsername() { 20 | return username; 21 | } 22 | 23 | public void setUsername(String username) { 24 | this.username = username; 25 | } 26 | 27 | public String getSex() { 28 | return sex; 29 | } 30 | 31 | public void setSex(String sex) { 32 | this.sex = sex; 33 | } 34 | 35 | public String getAddress() { 36 | return address; 37 | } 38 | 39 | public void setAddress(String address) { 40 | this.address = address; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/po/User.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.po; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | /** 8 | * Created by Administrator on 2016/2/21. 9 | */ 10 | public class User implements Serializable { 11 | //属性名要和数据库表的字段对应 12 | private int id; 13 | private String username;// 用户姓名 14 | private String sex;// 性别 15 | private Date birthday;// 生日 16 | private String address;// 地址 17 | 18 | //用户创建的订单列表 19 | private List ordersList; 20 | 21 | public int getId() { 22 | return id; 23 | } 24 | 25 | public void setId(int id) { 26 | this.id = id; 27 | } 28 | 29 | public String getUsername() { 30 | return username; 31 | } 32 | 33 | public void setUsername(String username) { 34 | this.username = username; 35 | } 36 | 37 | public String getSex() { 38 | return sex; 39 | } 40 | 41 | public void setSex(String sex) { 42 | this.sex = sex; 43 | } 44 | 45 | public Date getBirthday() { 46 | return birthday; 47 | } 48 | 49 | public void setBirthday(Date birthday) { 50 | this.birthday = birthday; 51 | } 52 | 53 | public String getAddress() { 54 | return address; 55 | } 56 | 57 | public void setAddress(String address) { 58 | this.address = address; 59 | } 60 | 61 | public List getOrdersList() { 62 | return ordersList; 63 | } 64 | 65 | public void setOrdersList(List ordersList) { 66 | this.ordersList = ordersList; 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | return "User [id=" + id + ", username=" + username + ", sex=" + sex 72 | + ", birthday=" + birthday + ", address=" + address + "]"; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/po/UserCustom.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.po; 2 | 3 | /** 4 | * Created by Brian on 2016/2/24. 5 | */ 6 | public class UserCustom extends User { 7 | } 8 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/src/com/iot/mybatis/po/UserQueryVo.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.po; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * Created by Brian on 2016/2/24. 7 | */ 8 | public class UserQueryVo { 9 | 10 | //在这里包装所需要的查询条件 11 | //传入多个id 12 | private List ids; 13 | 14 | //用户查询条件 15 | private UserCustom userCustom; 16 | 17 | public UserCustom getUserCustom() { 18 | return userCustom; 19 | } 20 | 21 | public void setUserCustom(UserCustom userCustom) { 22 | this.userCustom = userCustom; 23 | } 24 | 25 | public List getIds() { 26 | return ids; 27 | } 28 | 29 | public void setIds(List ids) { 30 | this.ids = ids; 31 | } 32 | 33 | //可以包装其它的查询条件,订单、商品 34 | //.... 35 | 36 | } 37 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/mybatis/test/com/iot/mybatis/dao/UserDaoImplTest.java: -------------------------------------------------------------------------------- 1 | package com.iot.mybatis.dao; 2 | 3 | import com.iot.mybatis.po.User; 4 | import org.apache.ibatis.io.Resources; 5 | import org.apache.ibatis.session.SqlSessionFactory; 6 | import org.apache.ibatis.session.SqlSessionFactoryBuilder; 7 | import org.junit.Before; 8 | import org.junit.Test; 9 | 10 | import java.io.InputStream; 11 | 12 | public class UserDaoImplTest { 13 | 14 | private SqlSessionFactory sqlSessionFactory; 15 | 16 | // 此方法是在执行testFindUserById之前执行 17 | @Before 18 | public void setUp() throws Exception { 19 | // 创建sqlSessionFactory 20 | 21 | // mybatis配置文件 22 | String resource = "SqlMapConfig.xml"; 23 | // 得到配置文件流 24 | InputStream inputStream = Resources.getResourceAsStream(resource); 25 | 26 | // 创建会话工厂,传入mybatis的配置文件信息 27 | sqlSessionFactory = new SqlSessionFactoryBuilder() 28 | .build(inputStream); 29 | } 30 | 31 | @Test 32 | public void testFindUserById() throws Exception { 33 | // 创建UserDao的对象 34 | UserDao userDao = new UserDaoImpl(sqlSessionFactory); 35 | 36 | // 调用UserDao的方法 37 | User user = userDao.findUserById(1); 38 | 39 | System.out.println(user); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springmvc-brian 8 | springmvc-1st 9 | 1.0-SNAPSHOT 10 | war 11 | 12 | 13 | 14 | org.springframework 15 | spring-webmvc 16 | 4.2.4.RELEASE 17 | 18 | 19 | 20 | 21 | springmvc-1st-1.0-SNAPSHOT 22 | 23 | 24 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/java/com/iot/ssm/controller/ItemsController.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.controller; 2 | 3 | import com.iot.ssm.po.Items; 4 | import org.springframework.web.servlet.ModelAndView; 5 | import org.springframework.web.servlet.mvc.Controller; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | 12 | /** 13 | * Created by brian on 2016/2/19. 14 | */ 15 | public class ItemsController implements Controller { 16 | 17 | public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { 18 | //调用service查找数据库,查询商品列表,这里使用静态数据模拟 19 | List itemsList = new ArrayList(); 20 | 21 | //向list中填充静态数据 22 | Items items_1 = new Items(); 23 | items_1.setName("联想笔记本"); 24 | items_1.setPrice(6000f); 25 | items_1.setDetail("ThinkPad T430 联想笔记本电脑!"); 26 | 27 | Items items_2 = new Items(); 28 | items_2.setName("苹果手机"); 29 | items_2.setPrice(5000f); 30 | items_2.setDetail("iphone6苹果手机!"); 31 | 32 | itemsList.add(items_1); 33 | itemsList.add(items_2); 34 | 35 | //返回ModelAndView 36 | ModelAndView modelAndView = new ModelAndView(); 37 | //相当于request的setAttribute方法,在jsp页面中通过itemsList取数据 38 | modelAndView.addObject("itemsList", itemsList); 39 | 40 | //指定视图 41 | modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp"); 42 | 43 | return modelAndView; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/java/com/iot/ssm/controller/ItemsController2.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.controller; 2 | 3 | import com.iot.ssm.po.Items; 4 | import org.springframework.web.HttpRequestHandler; 5 | 6 | import java.io.IOException; 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import javax.servlet.ServletException; 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | 13 | /** 14 | * Created by brian on 2016/2/19. 15 | */ 16 | public class ItemsController2 implements HttpRequestHandler { 17 | public void handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) 18 | throws ServletException, IOException { 19 | //调用service查找数据库,查询商品列表,这里使用静态数据模拟 20 | List itemsList = new ArrayList(); 21 | 22 | //向list中填充静态数据 23 | Items items_1 = new Items(); 24 | items_1.setName("联想笔记本"); 25 | items_1.setPrice(6000f); 26 | items_1.setDetail("ThinkPad T430 联想笔记本电脑!"); 27 | 28 | Items items_2 = new Items(); 29 | items_2.setName("苹果手机"); 30 | items_2.setPrice(5000f); 31 | items_2.setDetail("iphone6苹果手机!"); 32 | 33 | itemsList.add(items_1); 34 | itemsList.add(items_2); 35 | 36 | //设置模型数据 37 | httpServletRequest.setAttribute("itemsList", itemsList); 38 | 39 | //设置转发的视图 40 | httpServletRequest.getRequestDispatcher("/WEB-INF/jsp/items/itemsList.jsp").forward(httpServletRequest, httpServletResponse); 41 | 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/java/com/iot/ssm/po/Items.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.po; 2 | 3 | import java.util.Date; 4 | 5 | public class Items { 6 | private Integer id; 7 | 8 | private String name; 9 | 10 | private Float price; 11 | 12 | private String pic; 13 | 14 | private Date createtime; 15 | 16 | private String detail; 17 | 18 | public Integer getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Integer id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(String name) { 31 | this.name = name == null ? null : name.trim(); 32 | } 33 | 34 | public Float getPrice() { 35 | return price; 36 | } 37 | 38 | public void setPrice(Float price) { 39 | this.price = price; 40 | } 41 | 42 | public String getPic() { 43 | return pic; 44 | } 45 | 46 | public void setPic(String pic) { 47 | this.pic = pic == null ? null : pic.trim(); 48 | } 49 | 50 | public Date getCreatetime() { 51 | return createtime; 52 | } 53 | 54 | public void setCreatetime(Date createtime) { 55 | this.createtime = createtime; 56 | } 57 | 58 | public String getDetail() { 59 | return detail; 60 | } 61 | 62 | public void setDetail(String detail) { 63 | this.detail = detail == null ? null : detail.trim(); 64 | } 65 | 66 | @Override 67 | public String toString() { 68 | return "Items [id=" + id + ", name=" + name + ", price=" + price 69 | + ", pic=" + pic + ", createtime=" + createtime + ", detail=" 70 | + detail + "]"; 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/java/com/iot/ssm/po/Orderdetail.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.po; 2 | 3 | public class Orderdetail { 4 | private Integer id; 5 | 6 | private Integer ordersId; 7 | 8 | private Integer itemsId; 9 | 10 | private Integer itemsNum; 11 | 12 | public Integer getId() { 13 | return id; 14 | } 15 | 16 | public void setId(Integer id) { 17 | this.id = id; 18 | } 19 | 20 | public Integer getOrdersId() { 21 | return ordersId; 22 | } 23 | 24 | public void setOrdersId(Integer ordersId) { 25 | this.ordersId = ordersId; 26 | } 27 | 28 | public Integer getItemsId() { 29 | return itemsId; 30 | } 31 | 32 | public void setItemsId(Integer itemsId) { 33 | this.itemsId = itemsId; 34 | } 35 | 36 | public Integer getItemsNum() { 37 | return itemsNum; 38 | } 39 | 40 | public void setItemsNum(Integer itemsNum) { 41 | this.itemsNum = itemsNum; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "Orderdetail [id=" + id + ", ordersId=" + ordersId 47 | + ", itemsId=" + itemsId + ", itemsNum=" + itemsNum + "]"; 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/java/com/iot/ssm/po/Orders.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.po; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | public class Orders { 7 | private Integer id; 8 | 9 | private Integer userId; 10 | 11 | private String number; 12 | 13 | private Date createtime; 14 | 15 | private String note; 16 | 17 | //用户信息 18 | private User user; 19 | 20 | //订单明细 21 | private List orderdetails; 22 | 23 | public Integer getId() { 24 | return id; 25 | } 26 | 27 | public void setId(Integer id) { 28 | this.id = id; 29 | } 30 | 31 | public Integer getUserId() { 32 | return userId; 33 | } 34 | 35 | public void setUserId(Integer userId) { 36 | this.userId = userId; 37 | } 38 | 39 | public String getNumber() { 40 | return number; 41 | } 42 | 43 | public void setNumber(String number) { 44 | this.number = number == null ? null : number.trim(); 45 | } 46 | 47 | public Date getCreatetime() { 48 | return createtime; 49 | } 50 | 51 | public void setCreatetime(Date createtime) { 52 | this.createtime = createtime; 53 | } 54 | 55 | public String getNote() { 56 | return note; 57 | } 58 | 59 | public void setNote(String note) { 60 | this.note = note == null ? null : note.trim(); 61 | } 62 | 63 | public User getUser() { 64 | return user; 65 | } 66 | 67 | public void setUser(User user) { 68 | this.user = user; 69 | } 70 | 71 | public List getOrderdetails() { 72 | return orderdetails; 73 | } 74 | 75 | public void setOrderdetails(List orderdetails) { 76 | this.orderdetails = orderdetails; 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | return "Orders [id=" + id + ", userId=" + userId + ", number=" + number 82 | + ", createtime=" + createtime + ", note=" + note + ", user=" 83 | + user + ", orderdetails=" + orderdetails + "]"; 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/java/com/iot/ssm/po/User.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.po; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | *

Title: User

8 | *

Description:用户信息

9 | *

Company: www.itcast.com

10 | * 11 | * @version 1.0 12 | * @author 传智.燕青 13 | * @date 2015-2-2下午1:03:07 14 | */ 15 | public class User implements Serializable { 16 | private int id; 17 | private String username;// 用户姓名 18 | private String sex;// 性别 19 | private Date birthday;// 生日 20 | private String address;// 地址 21 | 22 | public int getId() { 23 | return id; 24 | } 25 | 26 | public void setId(int id) { 27 | this.id = id; 28 | } 29 | 30 | public String getUsername() { 31 | return username; 32 | } 33 | 34 | public void setUsername(String username) { 35 | this.username = username; 36 | } 37 | 38 | public String getSex() { 39 | return sex; 40 | } 41 | 42 | public void setSex(String sex) { 43 | this.sex = sex; 44 | } 45 | 46 | public Date getBirthday() { 47 | return birthday; 48 | } 49 | 50 | public void setBirthday(Date birthday) { 51 | this.birthday = birthday; 52 | } 53 | 54 | public String getAddress() { 55 | return address; 56 | } 57 | 58 | public void setAddress(String address) { 59 | this.address = address; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | return "User [id=" + id + ", username=" + username + ", sex=" + sex 65 | + ", birthday=" + birthday + ", address=" + address + "]"; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/resources/springmvc.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | itemsController 21 | itemsController 22 | itemsController2 23 | 24 | 25 | 26 | 27 | 30 | 31 | 32 | 33 | 34 | 35 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/webapp/WEB-INF/jsp/items/itemsList.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8" %> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 4 | <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> 5 | 6 | 7 | 8 | 9 | 查询商品列表 10 | 11 | 12 |
13 | 查询条件: 14 | 15 | 16 | 17 | 18 |
19 | 商品列表: 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
商品名称商品价格生产日期商品描述操作
${item.name }${item.price }${item.detail }修改
41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/webapp/WEB-INF/lib/jstl.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/springmvcfirst/src/main/webapp/WEB-INF/lib/jstl.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/webapp/WEB-INF/lib/standard.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/springmvcfirst/src/main/webapp/WEB-INF/lib/standard.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcfirst/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | springmvc 10 | org.springframework.web.servlet.DispatcherServlet 11 | 14 | 15 | contextConfigLocation 16 | classpath:springmvc.xml 17 | 18 | 19 | 20 | 21 | springmvc 22 | 29 | *.action 30 | 31 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | springmvc-brian 8 | springmvc-2nd 9 | 1.0-SNAPSHOT 10 | war 11 | 12 | 13 | 14 | org.springframework 15 | spring-webmvc 16 | 4.2.4.RELEASE 17 | 18 | 19 | 20 | 21 | 22 | springmvc-2nd-1.0-SNAPSHOT 23 | 24 | 25 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/src/main/java/com/iot/ssm/controller/ItemsController.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.controller; 2 | 3 | import com.iot.ssm.po.Items; 4 | import org.springframework.web.servlet.ModelAndView; 5 | import org.springframework.web.servlet.mvc.Controller; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | import javax.servlet.http.HttpServletRequest; 10 | import javax.servlet.http.HttpServletResponse; 11 | 12 | /** 13 | * Created by brian on 2016/2/19. 14 | */ 15 | public class ItemsController implements Controller { 16 | 17 | public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception { 18 | //调用service查找数据库,查询商品列表,这里使用静态数据模拟 19 | List itemsList = new ArrayList(); 20 | 21 | //向list中填充静态数据 22 | Items items_1 = new Items(); 23 | items_1.setName("联想笔记本"); 24 | items_1.setPrice(6000f); 25 | items_1.setDetail("ThinkPad T430 c1 联想笔记本电脑!"); 26 | 27 | Items items_2 = new Items(); 28 | items_2.setName("苹果手机"); 29 | items_2.setPrice(5000f); 30 | items_2.setDetail("iphone6苹果手机!"); 31 | 32 | itemsList.add(items_1); 33 | itemsList.add(items_2); 34 | 35 | //返回ModelAndView 36 | ModelAndView modelAndView = new ModelAndView(); 37 | //相当于request的setAttribute方法,在jsp页面中通过itemsList取数据 38 | modelAndView.addObject("itemsList", itemsList); 39 | 40 | //指定视图 41 | modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp"); 42 | 43 | return modelAndView; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/src/main/java/com/iot/ssm/po/Items.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.po; 2 | 3 | import java.util.Date; 4 | 5 | public class Items { 6 | private Integer id; 7 | 8 | private String name; 9 | 10 | private Float price; 11 | 12 | private String pic; 13 | 14 | private Date createtime; 15 | 16 | private String detail; 17 | 18 | public Integer getId() { 19 | return id; 20 | } 21 | 22 | public void setId(Integer id) { 23 | this.id = id; 24 | } 25 | 26 | public String getName() { 27 | return name; 28 | } 29 | 30 | public void setName(String name) { 31 | this.name = name == null ? null : name.trim(); 32 | } 33 | 34 | public Float getPrice() { 35 | return price; 36 | } 37 | 38 | public void setPrice(Float price) { 39 | this.price = price; 40 | } 41 | 42 | public String getPic() { 43 | return pic; 44 | } 45 | 46 | public void setPic(String pic) { 47 | this.pic = pic == null ? null : pic.trim(); 48 | } 49 | 50 | public Date getCreatetime() { 51 | return createtime; 52 | } 53 | 54 | public void setCreatetime(Date createtime) { 55 | this.createtime = createtime; 56 | } 57 | 58 | public String getDetail() { 59 | return detail; 60 | } 61 | 62 | public void setDetail(String detail) { 63 | this.detail = detail == null ? null : detail.trim(); 64 | } 65 | 66 | @Override 67 | public String toString() { 68 | return "Items [id=" + id + ", name=" + name + ", price=" + price 69 | + ", pic=" + pic + ", createtime=" + createtime + ", detail=" 70 | + detail + "]"; 71 | } 72 | 73 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/src/main/java/com/iot/ssm/po/Orderdetail.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.po; 2 | 3 | public class Orderdetail { 4 | private Integer id; 5 | 6 | private Integer ordersId; 7 | 8 | private Integer itemsId; 9 | 10 | private Integer itemsNum; 11 | 12 | public Integer getId() { 13 | return id; 14 | } 15 | 16 | public void setId(Integer id) { 17 | this.id = id; 18 | } 19 | 20 | public Integer getOrdersId() { 21 | return ordersId; 22 | } 23 | 24 | public void setOrdersId(Integer ordersId) { 25 | this.ordersId = ordersId; 26 | } 27 | 28 | public Integer getItemsId() { 29 | return itemsId; 30 | } 31 | 32 | public void setItemsId(Integer itemsId) { 33 | this.itemsId = itemsId; 34 | } 35 | 36 | public Integer getItemsNum() { 37 | return itemsNum; 38 | } 39 | 40 | public void setItemsNum(Integer itemsNum) { 41 | this.itemsNum = itemsNum; 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "Orderdetail [id=" + id + ", ordersId=" + ordersId 47 | + ", itemsId=" + itemsId + ", itemsNum=" + itemsNum + "]"; 48 | } 49 | 50 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/src/main/java/com/iot/ssm/po/Orders.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.po; 2 | 3 | import java.util.Date; 4 | import java.util.List; 5 | 6 | public class Orders { 7 | private Integer id; 8 | 9 | private Integer userId; 10 | 11 | private String number; 12 | 13 | private Date createtime; 14 | 15 | private String note; 16 | 17 | //用户信息 18 | private User user; 19 | 20 | //订单明细 21 | private List orderdetails; 22 | 23 | public Integer getId() { 24 | return id; 25 | } 26 | 27 | public void setId(Integer id) { 28 | this.id = id; 29 | } 30 | 31 | public Integer getUserId() { 32 | return userId; 33 | } 34 | 35 | public void setUserId(Integer userId) { 36 | this.userId = userId; 37 | } 38 | 39 | public String getNumber() { 40 | return number; 41 | } 42 | 43 | public void setNumber(String number) { 44 | this.number = number == null ? null : number.trim(); 45 | } 46 | 47 | public Date getCreatetime() { 48 | return createtime; 49 | } 50 | 51 | public void setCreatetime(Date createtime) { 52 | this.createtime = createtime; 53 | } 54 | 55 | public String getNote() { 56 | return note; 57 | } 58 | 59 | public void setNote(String note) { 60 | this.note = note == null ? null : note.trim(); 61 | } 62 | 63 | public User getUser() { 64 | return user; 65 | } 66 | 67 | public void setUser(User user) { 68 | this.user = user; 69 | } 70 | 71 | public List getOrderdetails() { 72 | return orderdetails; 73 | } 74 | 75 | public void setOrderdetails(List orderdetails) { 76 | this.orderdetails = orderdetails; 77 | } 78 | 79 | @Override 80 | public String toString() { 81 | return "Orders [id=" + id + ", userId=" + userId + ", number=" + number 82 | + ", createtime=" + createtime + ", note=" + note + ", user=" 83 | + user + ", orderdetails=" + orderdetails + "]"; 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/src/main/java/com/iot/ssm/po/User.java: -------------------------------------------------------------------------------- 1 | package com.iot.ssm.po; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | *

Title: User

8 | *

Description:用户信息

9 | *

Company: www.itcast.com

10 | * 11 | * @version 1.0 12 | * @author 传智.燕青 13 | * @date 2015-2-2下午1:03:07 14 | */ 15 | public class User implements Serializable { 16 | private int id; 17 | private String username;// 用户姓名 18 | private String sex;// 性别 19 | private Date birthday;// 生日 20 | private String address;// 地址 21 | 22 | public int getId() { 23 | return id; 24 | } 25 | 26 | public void setId(int id) { 27 | this.id = id; 28 | } 29 | 30 | public String getUsername() { 31 | return username; 32 | } 33 | 34 | public void setUsername(String username) { 35 | this.username = username; 36 | } 37 | 38 | public String getSex() { 39 | return sex; 40 | } 41 | 42 | public void setSex(String sex) { 43 | this.sex = sex; 44 | } 45 | 46 | public Date getBirthday() { 47 | return birthday; 48 | } 49 | 50 | public void setBirthday(Date birthday) { 51 | this.birthday = birthday; 52 | } 53 | 54 | public String getAddress() { 55 | return address; 56 | } 57 | 58 | public void setAddress(String address) { 59 | this.address = address; 60 | } 61 | 62 | @Override 63 | public String toString() { 64 | return "User [id=" + id + ", username=" + username + ", sex=" + sex 65 | + ", birthday=" + birthday + ", address=" + address + "]"; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/src/main/resources/springmvc.xml: -------------------------------------------------------------------------------- 1 | 8 | 9 | 12 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | 31 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/src/main/webapp/WEB-INF/jsp/items/itemsList.jsp: -------------------------------------------------------------------------------- 1 | <%@ page language="java" contentType="text/html; charset=UTF-8" 2 | pageEncoding="UTF-8" %> 3 | <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 4 | <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> 5 | 6 | 7 | 8 | 9 | 查询商品列表 10 | 11 | 12 |
13 | 查询条件: 14 | 15 | 16 | 17 | 18 |
19 | 商品列表: 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 |
商品名称商品价格生产日期商品描述操作
${item.name }${item.price }${item.detail }修改
41 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/src/main/webapp/WEB-INF/lib/jstl.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/springmvcsecond/src/main/webapp/WEB-INF/lib/jstl.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/src/main/webapp/WEB-INF/lib/standard.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/源码/ssm学习笔记sourcecode/springmvcsecond/src/main/webapp/WEB-INF/lib/standard.jar -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/springmvcsecond/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | springmvc 10 | org.springframework.web.servlet.DispatcherServlet 11 | 14 | 15 | contextConfigLocation 16 | classpath:springmvc.xml 17 | 18 | 19 | 20 | 21 | springmvc 22 | 29 | *.action 30 | 31 | -------------------------------------------------------------------------------- /源码/ssm学习笔记sourcecode/sql/data.sql: -------------------------------------------------------------------------------- 1 | /* 2 | SQLyog v10.2 3 | MySQL - 5.1.72-community : Database - mybatis 4 | ********************************************************************* 5 | */ 6 | 7 | 8 | /*!40101 SET NAMES utf8 */; 9 | 10 | /*!40101 SET SQL_MODE=''*/; 11 | 12 | /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; 13 | /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; 14 | /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; 15 | /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; 16 | /*Data for the table `items` */ 17 | 18 | insert into `items`(`id`,`name`,`price`,`detail`,`pic`,`createtime`) values (1,'台式机',3000.0,'该电脑质量非常好!!!!',NULL,'2015-02-03 13:22:53'),(2,'笔记本',6000.0,'笔记本性能好,质量好!!!!!',NULL,'2015-02-09 13:22:57'),(3,'背包',200.0,'名牌背包,容量大质量好!!!!',NULL,'2015-02-06 13:23:02'); 19 | 20 | /*Data for the table `orderdetail` */ 21 | 22 | insert into `orderdetail`(`id`,`orders_id`,`items_id`,`items_num`) values (1,3,1,1),(2,3,2,3),(3,4,3,4),(4,4,2,3); 23 | 24 | /*Data for the table `orders` */ 25 | 26 | insert into `orders`(`id`,`user_id`,`number`,`createtime`,`note`) values (3,1,'1000010','2015-02-04 13:22:35',NULL),(4,1,'1000011','2015-02-03 13:22:41',NULL),(5,10,'1000012','2015-02-12 16:13:23',NULL); 27 | 28 | /*Data for the table `user` */ 29 | 30 | insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'王五',NULL,'2',NULL),(10,'张三','2014-07-10','1','北京市'),(16,'张小明',NULL,'1','河南郑州'),(22,'陈小明',NULL,'1','河南郑州'),(24,'张三丰',NULL,'1','河南郑州'),(25,'陈小明',NULL,'1','河南郑州'),(26,'王五',NULL,NULL,NULL); 31 | 32 | /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; 33 | /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; 34 | /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; 35 | /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; -------------------------------------------------------------------------------- /经验总结/static class 静态类详解.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/经验总结/static class 静态类详解.pdf -------------------------------------------------------------------------------- /面试/database/MySQL_PASS.md: -------------------------------------------------------------------------------- 1 | ## MySQL修改root密码 2 | 3 | ### 方法一:用set password命令 4 | 5 | 首先,登陆mysql 6 | 7 | mysql -u root -p 8 | 9 | 然后执行set password命令 10 | 11 | set password for root@localhost = password('654321'); 12 | 13 | 上面例子,将root密码更改为654321 14 | 15 | ### 方法二:使用mysqladmin 16 | 17 | 格式为:mysqladmin -u用户名 -p旧密码 password 新密码 18 | 19 | mysqladmin -uroot -p123456 password "654321" 20 | 21 | 上面例子,将root密码由123456更改为654321 22 | 23 | ### 方法三:更改mysql的user表 24 | 25 | 首先,登陆mysql 26 | 27 | ``` 28 | mysql -uroot -p 29 | 然后操作mysql库的user表,进行update 30 | mysql> use mysql; 31 | mysql> update user set password=password('654321') where user='root' and host='localhost'; 32 | mysql> flush privileges; 33 | ``` 34 | 35 | ### 方法四:忘记密码的情况下 36 | 37 | 首先停止mysql服务 38 | 39 | 1、service mysqld stop 40 | 41 | 以跳过授权的方式启动mysql 42 | 43 | 2、mysqld_safe --skip-grant-tables & 44 | 45 | 3、mysql -u root 46 | 47 | 操作mysql库的user表,进行update 48 | 49 | ``` 50 | mysql> use mysql; 51 | mysql> update user set password=password('654321') where user='root' and host='localhost'; 52 | mysql> flush privileges; 53 | mysql> quit 54 | 重启mysql服务 55 | ``` 56 | 57 | 重启mysql服务 58 | service mysqld restart 59 | 60 | ## 开启远程mysql连接 61 | 62 | 步骤: 63 | 1、登入mysql 64 | 65 | 2、use mysql命令 66 | 67 | 3、GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; 68 | 69 | 4、flush privileges 70 | 71 | 5、查看select host,user from user -------------------------------------------------------------------------------- /面试/database/MySQL常见问题总结.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/muyinchen/woker/9dcd6f5bea49e9ed0f4b660c16092725b0982868/面试/database/MySQL常见问题总结.pdf --------------------------------------------------------------------------------