1

点赞

1

回复

416

浏览

MyBatis入门实例:整合Spring MVC与MyBatis开发问答网站

开发目标 今天我们使用MyBatis和Spring MVC开发一个简单的问答网站,你可以使用Markdown来发布问题和答案。完整的教程请参考 《基于MyBatis和Spring MVC搭建问答网站》 https://course.tianmaying.com/spring mvc mybatis qa 。 这篇文章可以教会你以下知识: MyBatis配置和使用最简单的姿势 MyBatis+Spring MVC实现一个简单的Web页面 MyBatis的核心类是干嘛用的( SqlSessionFactoryBuilder 、 SqlSessionFactory 和 SqlSession ) MyBatis Spring如何使用,帮你做了哪些工作? MyBatis Spring Boot Starter如何支持MyBatis,让你使用MyBatis的门槛降到最低 相信看完本身是你开始使用MyBatis的一个非常棒的开始! 最终的效果图如下: Web端的开发我们使用Spring MVC,对Spring MVC还不太熟悉的同学,可以看看天码营的 Spring MVC实战练习 https://course.tianmaying.com/spring mvc 。当然,Spring MVC的部分不是这个练习的重点,也基本不影响大家的理解和练习。 这样一个系统麻雀虽小,五张俱全,会涉及MyBatis的很多核心知识。MyBatis确实是一个非常简单易学的ORM框架,很适合作为你学习的第一款Java ORM框架。 ORM是什么? ORM是Object Relation Mapping的缩写,顾名思义,即对象关系映射。 ORM是一种以面向对象的方式来进行数据库操作的技术。Web开发中常用的语言,都会有对应的ORM框架。而MyBatis就是Java开发中一种常用ORM框架。 简单地理解,通过Java进行数据库访问的正常流程可以分为以下几步: 1. 准备好SQL语句 2. 调用JDBC的API传入SQL语句,设置参数 3. 解析JDBC返回的结果 这个过程实际上非常麻烦,比如: 在Java代码中拼接SQL非常麻烦,而且易于出错 JDBC的代码调用有很多重复性的代码 从JDBC返回的结果转换成领域模型的Java对象很繁琐 而使用ORM框架,则可以让我们用面向对象的方式来操作数据库,比如通过一个简单的函数调用就完成上面整个流程,直接返回映射为Java对象的结果。这个流程中很大一部分工作其实交给ORM自动化地帮我们执行了。 MYBATIS简介 MyBatis的入门知识最好的材料是其 官方网站 http://www.mybatis.org/mybatis 3/ ,而且其绝大部分内容都有中文版本。 官方网站上如下介绍MyBatis: MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或标注,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。 简单地理解,你可以认为MyBatis将SQL语句,以及SQL返回结果到Java对象的映射,都放到了一个易于配置的XML文件里了,你的Java代码就会变得异常简单。当然,除了XML,MyBatis同时也支持基于标注的方式,但是功能上会有一些限制。总体来说,我们推荐使用XML方式,一些简单的SQL使用标注会更方便一些。 开发环境 工欲善其事,必先利其器 首先让我们搭建好本地的开发环境,这里不会事无巨细地描述环境中每一种工具的安装步骤和用法,你可以从参考材料以及Google中获取有用的信息。 JAVA 我们推荐安装 JavaSE Development Kit 8 http://www.oracle.com/technetwork/java/javase/downloads/jdk8 downloads 2133151.html 。 参考 Java开发环境安装与配置 https://course.tianmaying.com/java basic/lesson/java environment IDE IDE我们推荐使用 Eclipse http://www.eclipse.org/home/index.php 或 IntelliJ IDEA https://www.jetbrains.com/idea/ (当然还有很多别的选择),它们对Maven项目的支持非常完善,自动提示、补全功能异常强大,对于开发效率的提升非常明显。 参考 Eclipse安装和使用 https://course.tianmaying.com/java basic/lesson/eclipse 0 MAVEN Maven是Java世界中最流行的项目构建工具,理论上来说在安装了IDE后,IDE内部会自带一个Maven的安装版本,如果想在命令行工具中使用Maven命令,可以单独进行安装。 参考: Maven基本概念 http://www.tianmaying.com/tutorial/maven basic 如何通过Maven构建项目 http://www.tianmaying.com/tutorial/maven demo 通过Maven进行项目构建与管理 http://www.tianmaying.com/tutorial/maven project management 如果想深入了解,推荐 Maven实战 https://book.douban.com/subject/5345682/ 。 H2 我们使用内嵌的数据库H2,如果希望转换成其他数据库,比如MySQL,只需修改数据库连接串即可。当然别忘了要在依赖中增加相应的数据库访问驱动包。H2数据库不需要你任何额外的安装工作。 创建项目 接下来我们开始创建第一个MyBatis项目吧。新建一个Maven项目,项目结构如下: ....

spring-mvcmybatisspring

1

点赞

0

回复

544

浏览

Spring AOP中定义切点(PointCut)和通知(Advice)

本文讨论一下Spring AOP编程中的两个关键问题,定义切点和定义通知,理解这两个问题能应付大部分AOP场景。 如果你还不熟悉AOP,请先看 AOP基本原理 https://www.tianmaying.com/tutorial/spring aop ,本文的例子也沿用了 AOP基本原理 https://www.tianmaying.com/tutorial/spring aop 中的例子。 切点表达式 切点的功能是指出切面的通知应该从哪里织入应用的执行流。切面只能织入公共方法。 在Spring AOP中,使用AspectJ的切点表达式语言定义切点其中 excecution() 是最重要的描述符,其它描述符用于辅助 excecution() 。 excecution() 的语法如下 execution(modifiers pattern? ret type pattern declaring type pattern? name pattern(param pattern)throws pattern?)...

aopspring

1

点赞

0

回复

457

浏览

Spring MVC@RequestMapping 方法所支持的参数类型和返回类型详解

使用 @RequestMapping 标注的处理方法可以拥有非常灵活的方法签名,它支持的方法参数及返回值类型种类极其丰富。大多数参数都可以任意的次序出现,除了唯一的一个例外: BindingResult 参数。 支持的方法参数类型 @RequestMapping 方法方法所支持的常见参数类型: 请求或响应对象(Servlet API)。可以是任何具体的请求或响应类型的对象,比如, ServletRequest 或 HttpServletRequest 对象。 HttpSession 类型的会话对象(Servlet API)。使用该类型的参数将要求这样一个session的存在,因此这样的参数永不为 null 。 当前请求的地区信息 java.util.Locale ,由已配置的最相关的地区解析器解析得到。在MVC的环境下,就是应用中配置的 LocaleResolver 或 LocaleContextResolver 与当前请求绑定的时区信息 java.util.TimeZone (java 6以上的版本)/ java.time.ZoneId (java 8),由 LocaleContextResolver 解析得到 org.springframework.http.HttpMethod 。可以拿到HTTP请求方法 包装了当前被认证用户信息的 java.security.Principal 带 @PathVariable 标注的方法参数,其存放了URI模板变量中的值。 带 @RequestParam 标注的方法参数,其存放了Servlet请求中所指定的参数。参数的值会被转换成方法参数所声明的类型。 带 @RequestHeader 标注的方法参数,其存放了Servlet请求中所指定的HTTP请求头的值。参数的值会被转换成方法参数所声明的类型。 带 @RequestBody 标注的参数,提供了对HTTP请求体的存取。参数的值通过 HttpMessageConverter 被转换成方法参数所声明的类型。 带 @RequestPart 标注的参数,提供了对一个"multipart/form data请求块(request part)内容的存取。 HttpEntity 类型的参数,其提供了对HTTP请求头和请求内容的存取。请求流是通过 HttpMessageConverter 被转换成entity对象的。 java.util.Map / org.springframework.io.Model / org.springframework.ui.ModelMap 类型的参数,用以增强默认暴露给视图层的模型(model)的功能 org.springframework.web.servlet.mvc.support.RedirectAttributes 类型的参数,用以指定重定向下要使用到的属性集以及添加flash属性(暂存在服务端的属性,它们会在下次重定向请求的范围中有效)。 命令或表单对象,它们用于将请求参数直接绑定到bean字段(可能是通过setter方法)。你可以通过 @InitBinder 标注和/或 HanderAdapter 的配置来定制这个过程的类型转换。 RequestMappingHandlerAdapter 类 webBindingInitializer 属性的文档。这样的命令对象,以及其上的验证结果,默认会被添加到模型model中,键名默认是该命令对象类的类名——比如, some.package.OrderAddress 类型的命令对象就使用属性名 orderAddress 类获取。 ModelAttribute 标注可以应用在方法参数上,用以指定该模型所用的属性名 org.springframework.validation.Errors / org.springframework.validation.BindingResult 验证结果对象,用于存储前面的命令或表单对象的验证结果(紧接其前的第一个方法参数)。 org.springframework.web.bind.support.SessionStatus 对象,用以标记当前的表单处理已结束。这将触发一些清理操作: @SessionAttributes 在类级别标注的属性将被移除 org.springframework.web.util.UriComponentsBuilder 构造器对象,用于构造当前请求URL相关的信息,比如主机名、端口号、资源类型(scheme)、上下文路径、servlet映射中的相对部分(literal part)等 BINDINGRESULT的特殊性 在参数列表中, Errors 或 BindingResult 参数必须紧跟在其所绑定的验证对象后面。这是因为,在参数列表中允许有多于一个的模型对象,Spring会为它们创建不同的 BindingResult 实例。因此,下面这样的代码是不能工作的: BindingResult与@ModelAttribute错误的参数次序 @RequestMapping(method = RequestMethod.POST)...

spring-mvcspring

1

点赞

0

回复

516

浏览

Spring MVC @ModelAttribute详解

方法使用@MODELATTRIBUTE标注 @ModelAttribute 标注可被应用在方法或方法参数上。 标注在方法上的 @ModelAttribute 说明方法是用于添加一个或多个属性到model上。这样的方法能接受与 @RequestMapping 标注相同的参数类型,只不过不能直接被映射到具体的请求上。 在同一个控制器中,标注了 @ModelAttribute 的方法实际上会在 @RequestMapping 方法之前被调用。 以下是示例: // Add one attribute...

spring-mvcspring

0

点赞

0

回复

1002

浏览

Spring MVC中映射请求路径:@RequestMapping标注详解

@REQUESTMAPPING的基本用法 可以使用 @RequestMapping 标注来将请求URL,如 /appointments 等,映射到整个类上或某个特定的处理器方法上。一般来说,类级别的标注负责将一个特定(或符合某种模式)的请求路径映射到一个控制器上,同时通过方法级别的标注来细化映射,即根据特定的HTTP请求方法(“GET”和“POST”方法等)、HTTP请求中是否携带特定参数等条件,将请求映射到匹配的方法上。 @Controller...

spring-mvcspring

0

点赞

0

回复

786

浏览

Spring MVC DispatcherServlet详解

SPRING MVC的特点 Spring MVC框架是围绕 DispatcherServlet 来设计的,这个 Servlet 会把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染和文件上传等功能。 处理器是应用中注解了 @Controller 和 @RequestMapping 的类和方法,Spring为处理器方法提供了非常多样灵活的配置。 Spring 3.0以后提供了 @Controller 注解机制、 @PathVariable 注解以及一些其他的特性,你可以使用它们来进行RESTful web站点和应用的开发。 Spring MVC具有以下特性: 清晰的职责分离。每个角色——控制器,验证器,命令对象,表单对象,模型对象, DispatcherServlet ,处理器映射,视图解析器,等等许多——的工作,都可以由相应的对象来完成。 强大、直观的框架和应用bean的配置。这种配置能力包括能够从不同的上下文中进行简单的引用,比如在web控制器中引用业务对象、验证器等。 强大的适配能力、非侵入性和灵活性。Spring MVC支持你定义任意的控制器方法签名,在特定的场景下你还可以添加适合的注解(比如 @RequestParam 、 @RequestHeader 、 @PathVariable 等) 可复用的业务代码,使你远离重复代码。你可以使用已有的业务对象作为命令对象或表单对象,而不需让它们去继承一个框架提供的基类。 可定制的数据绑定和验证。类型不匹配仅被认为是应用级别的验证错误,错误值、本地化日期、数字绑定等会被保存。你不需要再在表单对象使用全String字段,然后再手动将它们转换成业务对象。 可定制的处理器映射和视图解析。处理器映射和视图解析策略从简单的基于URL配置,到精细专用的解析策略,Spring全都支持。在这一点上,Spring比一些依赖于特定技术的web框架要更加灵活。 灵活的模型传递。Spring使用一个名称/值对的Map来做模型,这使得模型很容易集成、传递给任何类型的视图技术。 可定制的本地化信息、时区和主题解析。支持用/不用Spring标签库的JSP技术,支持JSTL,支持无需额外配置的Velocity模板,等等。; 一个简单但功能强大的JSP标签库,通常称为Spring标签库,它提供了诸如数据绑定、主题支持等一些特性的支持。这些定制的标签为标记(markup)你的代码提供了最大程度的灵活性。 一个Spring 2.0开始引入的JSP表单标签库。它让你在JSP页面中编写表单简单许多。 新增生命周期仅绑定到当前HTTP请求或HTTP会话的Bean类型。 DISPATCHERSERVLET的工作流程 Spring MVC框架是请求驱动的:所有设计都围绕着一个中央 Servlet 来展开,它负责把所有请求分发到控制器;同时提供其他Web应用开发所需要的功能。 DispatcherServlet 与Spring IoC容器做到了无缝集成,这意味着,Spring提供的任何特性在Spring MVC中你都可以使用。 下图展示了Spring Web MVC的 DispatcherServlet 处理请求的工作流, DispatcherServlet 应用的其实就是一个“前端控制器”的设计模式: 基于 Spring Boot http://www.tianmaying.com/tutorial/spring boot overview ,可以直接使用Spring MVC,除非有非常个性化的要求,相关配置不需要手动配置。 DISPATCHERSERVLET的配置 DispatcherServlet 其实就是个 Servlet (它继承自 HttpServlet 基类),同样也需要在你Web应用的 web.xml 配置文件下声明。你需要在 web.xml 文件中把你希望 DispatcherServlet 处理的请求映射到对应的URL上去。这就是标准的Java EE Servlet配置;下面的代码就展示了对 DispatcherServlet 和路径映射的声明: ...

springspring-mvc

1

点赞

0

回复

1155

浏览

Spring处理自动装配歧义

自动装配中冲突 自动装配(autowiring)要求bean的匹配具备唯一性,否则就会产生歧义,从而抛出异常。 例如,如果我们给 QunarBookingService 和 CtripBookingService 都标注上 @Component ,则应用上下文中会有两个 BookingService 实例。 QunarBookingService.java @Component...

springjava

2

点赞

0

回复

1281

浏览

Spring MVC中创建URL路由

设计网站的URL 现代的Web站点都会设计一套拥有明确意义,方便用户记忆的URL,不论是域名还是路径,以天码营为例: http://tianmaying.com/courses http://tianmaying.com/courses 表示网站下所有的课程列表 http://tianmaying.com/course/web development http://tianmaying.com/course/web development 表示当前我们正在学习的这门课程 在HTML和CSS的学习中,我们创建了个人博客网站的基本页面,如果需要将他们放在Internet中让其他人可以访问,就必须为它们设计一套URL,现在假设我们的网站通过 http://localhost:8080/ http://localhost:8080/ 可以访问: http://localhost:8080/ http://localhost:8080/ 是网站首页,同时也应该对应当前的文章列表 http://localhost:8080/posts/create http://localhost:8080/posts/create ,创建新文章页面 http://localhost:8080/posts/{id}/ http://localhost:8080/posts/){id}/ ,显示某一篇文章页面 http://localhost:8080/posts/){id}/edit http://localhost:8080/posts/){id}/edit ,编辑某一篇文章页面 定义URL处理方法 在Spring WebMVC框架中,使用 @RequestMapping 注解可以将URL与处理方法绑定起来,例如: @Controller...

springjavaspring-mvc

1

点赞

0

回复

2274

浏览

Spring中如何混用XML与Java装配方式

多种装配方式的混用 除了自动配置,Spring使用显式的Java配置或者XML配置也可以完成任何装配。通常情况下可能在一个Spring项目中同时使用自动配置和显式配置。 对于自动配置,它自动从整个容器上下文中查找合适的bean,这个bean是通过 @Component 之类的标准,可能来自Java配置或者XML配置。 我们先来了解一下Java配置吧。 JAVA配置 创建配置类 使用Java配置,通过创建一个专门用于Spring配置的类,然后通过 @Configuration 标注该类。这个类一般不包含业务代码,类似于一个配置文件。 package com.tianmaying.config;...

javaspring

0

点赞

0

回复

2511

浏览

Spring的自动装配方法

SPRING的装配方式 我们已经了解了依赖注入的基本原理,初识了 @Component 和 @AutoWired 标注的用法。为一个应用中的Beans的配置依赖注入关系的过程称之为装配(Wiring)。 Spring提供三种装配方式: 基于标注的自动装配 基于XML配置的显式装配 基于Java配置的显式装配 之前的示例就是使用自动装配。通过给Java类增加相应的标注,就能够启用Spring隐式的Bean发现机制,并自动完成装配过程。我们在开发中应该尽可能使用自动装配,足以应付开发中的绝大多数情况。 Spring通过两个特性实现自动装配: 构件扫描:自动扫描和创建Spring应用上下文中的Beans @Autowired 标注:自动建立Spring Beans之间的依赖关系 在某些情况下,基于XML配置和基于Java配置的显式装配会有用武之地,比如实例化一个第三方库中的Bean。这种情况下,Java配置和XML配置我们优先使用Java配置,因为这是一种类型安全的方式,能够在编译时就尽早发现错误。 我们先来了解自动装配吧! 启用自动扫描 如何启动自动扫描机制呢? 在Spring Boot应用中,加入 @SpringBootApplication 标注就能启动自动扫描。 package com.tianmaying;...

javaspring

3

点赞

2

回复

3709

浏览

通过Spring Boot三分钟创建Spring Web项目

SPRING BOOT简介 接下来我们所有的Spring代码实例将会基于 Spring Boot http://projects.spring.io/spring boot/ ,因此我们先来了解一下Spring Boot这个大杀器。 Spring早期使用XML配置的方式来配置Spring Beans之间的关系,比如AOP和依赖注入的配置。随着功能以及业务逻辑的日益复杂,应用便会伴随大量的XML配置文件以及复杂的Bean依赖关系。随着Spring 3.0的发布,Spring团队逐渐开始摆脱XML配置文件,并且在开发过程中大量使用“约定优先配置”(convention over configuration)的思想来摆脱Spring框架中各类纷繁复杂的配置。Spring就是在这样一种背景下被抽象出来的一个在Spring之上的开发框架。 Spring Boot的设计目的是用来简化新Spring应用的创建以及开发过程。从它的名字可以看出,其作用在于创建和启动新的基于 Spring 框架的项目,它能够帮助开发人员很容易的创建出基于Spring的独立运行和产品级别的应用。它包含的特性如下: 应用独立运行,对于Web应用直接嵌入应用服务器(Tomcat or Jetty) 根据项目的依赖(Maven or Gradle中定义的依赖)自动配置Spring框架的特性 提供生产环境中的监控功能——性能、应用状态信息等 不会生成繁琐的Java代码以及XML配置文件 Spring Boot并不是用来替代Spring的解决方案,而是和Spring框架紧密结合用于提升Spring开发者体验的工具。Spring Boot应用通常只需要非常少量的配置代码,而且有内嵌的Web服务器,让开发者能够更加专注于业务逻辑。在后面的开发过程中,我们能够逐渐感受到Spring Boot这些优秀特性给我们带来的好处。 第一个SPRING BOOT项目 接下来我们通过创建一个简单的Spring Boot项目来建立对初步的印象。一开始可能会遇到一些不太理解的地方,没关系,我们会在学习过程中我们会逐一搞定。 我们通过Maven来创建项目,【File】 【New】 【Others...】; 弹出的对话框中包含了一系列的项目类型,我们选择 Maven Project ;一个技巧是可以在 type filter text 中输入 Maven 进行搜索过滤,这样很快可以找到 Maven Project 。 选中后出现了新的对话框,勾选 Create a simple project (skip archetype selection) ,点击 Next 后,按照下图输入内容: 输入完成后点击 Finish ,第一个项目就创建成功了。 项目创建成功后,在Eclipse IDE左边的 Project Explorer 中会出现我们刚刚创建的项目,其中有一个 pom.xml 文件,我们先对它进行修改,增加一个依赖,内容变为: project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema instance"...

springbootspring

1

点赞

1

回复

1061

浏览

Java企业应用开发框架Spring框架简介

SPRING是什么? Spring是一个开源的轻量级的Java企业应用开发框架,其初衷是为了替代当时非常笨重的Java EE(当时还称为J2EE)组件技术EJB(Enterprice Java Beans),让Java EE开发更加简单灵活。 Spring起源于Rod Jahnson 2002年出版的著作《Expert One on One J2EE Design and Development》,书中分析了Java EE的开发效率和实际性能等方面的问题,从实践和架构的角度探讨了简化开发的原则和方法。以此为基础,他实现了一个名为 interface21 的轻量级开发框架,成为Spring框架的前身。2004年,Spring正式发布1.0版本,同年Rod Jahnson推出了另一部影响深远的经典著作《Expert one on one J2EE Development without EJB》,Spring开始逐步在Java领域流行。现在Spring框架的版本已经演化到了4.x,它已经成为Java开发框架的一种事实标准,对Java EE规范本身也产生了重要影响。比如EJB规范就在发展中逐渐引入了众多Spring框架的优秀特征。 Spring最重要的两个核心功能是依赖注入(DI,Dependency Injection)和面向切面编程(AOP,Aspect Oriented Programming)。其中DI用于管理Java对象之间的依赖关系,AOP用于解耦业务代码和公共服务代码(如日志,安全,事务等)。DI和AOP能够让代码更加简单,具有良好的松耦合特性和可测试性,极大地简化开发。理解这两者是使用Spring框架的基础。 Spring框架本身具有模块化的分层架构,开发者可以根据需要使用其中的各个模块。Spring框架对Java企业应用开发中的各类通用问题都进行了良好的抽象,因此也能够把应用各个层次所涉及的特定开发框架(如MVC框架、ORM框架)方便得组合到一起。Spring是一个极其优秀的一站式的Full Stack集成框架。 SPRING的基本思想 Spring的目标是简化Java应用开发,那么它是通过什么方式来实现这一目标的呢?前面我们说过DI和AOP是Spring的核心功能,更准确地说,Spring通过为DI和AOP这两种编程技术提供支持,来让应用更方便的进行开发。此外,Spring提倡基于POJO(Plain Old Java Object)的编程模型,提供了针对企业开发且屏蔽重复代码的工具类。在开始正式进入代码编写之前,我们先了解Spring简化开发的几个基本思想。 DI 面向对象的程序通过一组对象之间相互通信来实现特定功能,这里的通信具体来说就是一个对象对另一个对象的方法调用或者属性访问。比如有一个 BlogRespositry 类负责将博客内容存储到数据库,一个 BlogController 负责解析前端的Web请求。 BlogController 接受到新建博客的请求之后,需要调用 BlogRespositry 的方法来保存博客内容。这里 BlogRespositry 就是 BlogController 的一个依赖,具体体现在 BlogController 会包含一个 BlogRespositry 类型的成员变量。 class BlogController {...

springjava

0

点赞

1

回复

830

浏览

敏捷课程总结报告 - 辣个表情

项目立意 有个段子大家可能听说过,“不要问我的理想工作是什么,我的理想是不用工作”。虽然很消极,但是反映出了现在社会绝大多数人的思想。这也是正常的,对于大部分人来说,生活的主旨是让自己能活下去,然后是过得舒服过得愉快,最后才是为他人创造些什么。 所以现在真正赚钱的所谓IP,面对的主要人群都是这样的、绝大多数的人,手游、电影、电视,都是这样。大时代是如此,特别的,在这个大时代中,有一小支文化也同样在发展壮大,就是所谓的“宅”文化。 大家可能会觉得宅文化是一个小圈子,但是实际上它覆盖的范围是相当大,从早点的ACG,也就是动画漫画游戏,拓展到了今天的ACGN,新加了小说,所以从广义上来说,我们都是宅文化的一员。 于此同时,“宅”的定义也在逐渐拓展,更多的被用来表示对某一个事物的喜好者组成的群体,这是由于互联网时代的特征造成的,放在过去你喜欢一个什么东西,你就参加社团,现在呢,只需要老老实实待在家里,通过网络就可以获取你想要的一切。 “宅”文化不像体育运动那样是一个互相的过程,主要是制作者向消费者单方面的灌输内容,那么对于消费者来说,这样的内容灌输是不够的。动画更新了、小说连载了、电影上映了,看完了,不过瘾,下一集还要等或者就干脆没有了,怎么办?看完之后,感动了、不满了、困惑了,怎么办?所以我们会看到,电影播完之后各种地方开始吐槽,动漫更新后视频上各种弹幕飞过,QQ群,论坛更是不用多说,在这个过程里,作品得到了充分的诠释,观众得到了满足,社交平台得到了流量,可谓是皆大欢喜。 而在交流的过程中,有相当一部分,当然是偏灌水的那一部分,是由表情完成的。这其中有两个原因:首先,单纯的文字是平淡而单调的,“干嘛”两个字根据不同的语音语调可以演绎出许多种不同的意思,更不用说那个我们大家都懂的字了其次,如果你只是想要表达你现在的想法,文字反倒麻烦了,一个简单的表情就能够精确、方便、快捷的表达你内心的想法 说了这么多?那么需求到底是什么呢?我们的根本需求来源于这样的一个因素:表情(通常是QQ表情)只能够存在本地!这就造成了巨大的问题——对于自己收藏的表情的管理是困难的所以对于这样的需求,我们的目标只有一个:表情云 项目目标 基本目标 搭建一个在线的表情库,支持用户上传表情,下载表情。方便用户在多台设备,不同系统环境下的表情使用。 上传&下载 多种上传方式 批量下载功能 展示 用户自定义标签 筛选 收藏 用户可以通过标签来收藏表情,便于之后的查找和使用 最近使用,方便快速的复用表情 历程回顾 项目从国庆之后开始搭建,期间一直零零散散的网上堆砌功能,大家也分头去做各自的事情,每当实现了一个相对完整的功能,就会往主分支上合并,并且立即上线。 技术方案 数据库 最开始的数据库设计包含有两个表: Expr : id , creator , extension , md5 Tag : id , content , expr_id , owner 其中省略了用户系统User和标签内容TagContent: User :在设计中才用了使用Url来包含用户ID做法,通过Url进行用户验证。一方面后台实现起来较为方便,一方面为了与客户端进行逻辑上的统一。 TagContent :以 Tag 模型中 content 域来直接进行表示但是这样的设计也产生一定的问题,在前端不能很好的进行路由,同时在统计Tag时比较麻烦。 WEB+API服务器 发现/收藏 直接将用户所有的表情以列表的形式显示,在前端才用了 React.js 进行模版渲染。 表情上传 1. 拖拽上传在使用QQ、YY等聊天工具时,可以对图片进行直接的拖拽。当将聊天框内的图片直接拖拽至记事本时,会直接转化图片缓存的地址。利用这个性质,在JavaScript设置抓取事件:当图片拖拽至对应抓取框时,通过JavaScript中 file 类获取当前图片的数据流以及本地地址。根据 file 类所存储的数据将图片对应显示于浏览器。确认上传时,将图片的地址进行传递实现了上传功能。 2. 复制上传在Windows系统中通过 Ctrl+V 进行图片复制时,剪贴板中是以数据流的格式存储的图片,特别是通过截图软件(如QQ的 Ctrl+Alt+A )截取的图片并没有直接对应的静态文件。因此在处理复制上传时需要解决的问题是数据流如何转化为文件。通过调研一些成熟的富文本编辑器,阅读其源代码,发现了可行的解决方案:利用计算机的Blob(binary large object)容器。提供了访问粘贴板中Blob二进制数据的接口 clipboardData.items ,并提供了将其转换为文件的方法 getAsFile ,通过这两个函数实现了二进制流数据的转化。 3. 打包上传利用AjaxFileUpload.js库进行文件上传,将上传的压缩包文件进行解包,分解为多个图片。目前支持Zip/Rar文件的打包上传,这两种格式压缩文件比较常见,并且有着明确的编码方式说明文件。在查找算法的过程中,发现Java自身就有这两种文件压缩解压的库,以及对应的maven包: ...

.netspringc++设计模式java

1

点赞

0

回复

1345

浏览

浅析Spring框架中的设计结构

1、什么是SPRING框架 Spring 是一个开源框架,是为了解决企业应用程序开发复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许您选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。 Spring 框架是一个分层架构,由 7 个模块组成,如下图所示。 2、SPRING中的设计模式 Spring 是面向 Bean 的编程(BOP,Bean Oriented Programming),因此Bean对Spring非常的重要。 Spring 的Core模块就用于创建、配置和管理bean的方式,并为构建在Core之上提供服务。因此,本文将简单对Bean的管理过程中用到的 设计模式 http://tianmaying.com/tag/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F 进行介绍 (1)工厂模式 Bean 的创建采用了的工厂模式,他的顶级接口是 BeanFactory。 BeanFactory 有三个子接口:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactor。这三个接口 主要是为了区分在 Spring 内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制 。上述三种工厂类的功能大部分是通过 DefaultListableBeanFactory和 AbstractBeanFactory 实现的。 BeanFactory提供了工厂模式最基础的接口,包括4个获取实例的方法、4个判断的方法以及1个获取类型和别名的方法。 package org.springframework.beans.factory;...

spring设计模式

0

点赞

0

回复

5227

浏览

Spring Data JPA: 为单个Repository添加自定义方法

我们在 Spring Data JPA: 为所有Repository添加自定义方法 http://tianmaying.com/tutorial/spring jpa custom all 中学习了通过JpaRepositoryFactory来为所有Repository添加一个公共的方法以及实现。但在很多情况下,我们需要为某个单独的Repository添加一个自定义的方法,并使其拥有一个自定义的实现。我们现在就来学习一下如何为某个单独的Repository添加自定义方法 ...

javaspringjpa

新建主题 记录代码

学员动态

  • k**y在课程作业中回复了老师:老师,正确的是pos...
  • z**x在课程中提出了问题:老师我还想问下冒泡排...
  • w**3回复了k**y在课程中的问题:不懂的直接在代码答疑...
  • w**3回复了z**x在课程中的问题:你对修饰符理解是对的...
  • u**i向课程作业中提交了代码
  • k**y在课程作业中回复了老师:老师。请问这个这样写...
  • c**h向课程作业中提交了代码
  • 三年向课程作业中提交了代码
  • d**g向课程作业中提交了代码
  • s**1在课程作业中回复了老师:感谢,检测过了,还得...
  • w**3回复了s**1在课程中的问题:好的,稍等。 老师,...
  • z**5在课程中提出了问题:不知道为什么出现了这...
  • 刘澳学向课程作业中提交了代码
  • w**3回复了z**x在课程中的问题:两个其实是不一样的变...
  • 三年在课程作业中回复了老师:完善Question...
  • z**5在课程中提出了问题
  • 天码君评论了s**1在课程中的作业:登录成功的逻辑和Lo...
  • s**1在课程中提出了问题:老师,麻烦帮我解锁一...
  • k**y在课程作业中回复了老师:老师,想问下这一行代...
  • k**y在课程作业中回复了老师:老师 请问这里是应该...
  • w**3回复了z**x在课程中的问题:length是获取数...
  • w**3评论了c**h在课程中的作业:返回值是string...
  • z**5在课程中提出了问题
  • m**2在课程中提出了问题:为什么这个定义的属性...
  • 三年在课程作业中回复了老师:完善Question...
  • c**h在课程作业中回复了老师:老师,您好! 我试了...
  • u**i向课程作业中提交了代码
  • 1**8向课程作业中提交了代码
  • w**3回复了z**x在课程中的问题:API(Applic...
  • w**3回复了B**e在课程中的问题:成员变量顾名思义就是...
  • z**x在课程中提出了问题:老师能给我讲解下绿框...
  • 天码君回复了1**7在课程中的问题:欢迎来到天码营学习,...
  • w**3评论了s**1在课程中的作业:在这里String ...
  • 天码君评论了三年在课程中的作业:这里collect的...
  • c**1向课程作业中提交了代码
  • m**2在课程中提出了问题:啊 明白了! 谢谢呢...
  • w**3评论了c**h在课程中的作业:public sta...
  • 刘澳学向课程作业中提交了代码
  • w**3回复了z**x在课程中的问题:碰到这样的方法,你可...
  • k**y在课程作业中回复了老师:int id;这样就...
  • z**x在课程中提出了问题:我是看《java从入...
  • 天码君评论了三年在课程中的作业:你这里条件设置了ta...
  • w**3评论了k**y在课程中的作业:system.out...
  • c**h向课程作业中提交了代码
  • c**h向课程作业中提交了代码
  • w**3评论了s**1在课程中的作业:public voi...
  • 刘澳学向课程作业中提交了代码
  • c**n向课程作业中提交了代码
  • 1**6向课程作业中提交了代码
  • 天码君回复了d**g在课程中的问题:欢迎来到天码营学习,...
  • z**x在课程中提出了问题:好的老师,它为什么排...
  • 天码君评论了s**1在课程中的作业:LoginFilte...
  • w**3回复了z**x在课程中的问题:请问你是在哪里看到这...
  • s**1在课程作业中回复了老师:这块没明白,这个us...
  • m**2向课程作业中提交了代码
  • w**3回复了m**2在课程中的问题:Post 都没有定义...
  • x**4向课程作业中提交了代码
  • w**3评论了k**y在课程中的作业:main方法是一个程...
  • 刘澳学向课程作业中提交了代码
  • 天码君回复了s**1在课程中的问题:欢迎来到天码营学习,...
  • w**3评论了s**1在课程中的作业:next不需要定义在...
  • u**i向课程作业中提交了代码
  • 1**6向课程作业中提交了代码
  • k**y在课程中提出了问题:老师。实战任务怎么没...
  • c**h向课程作业中提交了代码
  • z**x在课程中提出了问题:还有老师,为什么它0...
  • w**3评论了k**y在课程中的作业:...
  • s**1在课程作业中回复了老师:老师麻烦帮我看下我这...
  • d**g在课程中提出了问题:老师,您好, 我对这...
  • z**x在课程中提出了问题:API是什么啊? 碰...
  • c**h向课程作业中提交了代码
  • z**x在课程中提出了问题:好的,理解了 两个其...
  • c**h在课程作业中回复了老师:错误: 缺少返回语句...
  • B**e在课程中提出了问题:成员变量是不是就相当...
  • w**3回复了z**5在课程中的问题:你是创建了什么别的文...
  • c**h向课程作业中提交了代码
  • u**i向课程作业中提交了代码
  • z**x在课程中提出了问题:老师我想问两个问题,...
  • 天码君评论了三年在课程中的作业:and和or的优先级...
  • 刘澳学向课程作业中提交了代码
  • s**1在课程作业中回复了老师:按照答案改完还是检测...
  • 天码君回复了s**1在课程中的问题:欢迎来到天码营学习,...
  • 刘澳学向课程作业中提交了代码
  • s**1在课程作业中回复了老师:老师麻烦帮我看看,本...
  • c**h向课程作业中提交了代码
  • c**h向课程作业中提交了代码
  • d**g评论了:四个整形变量...
  • w**3回复了m**2在课程中的问题:public cla...
  • 天码君回复了s**1在课程中的问题:欢迎来到天码营学习,...
  • 1**9完成了课程的作业
  • 天码君回复了s**1在课程中的问题:欢迎来到天码营学习,...
  • c**h在课程作业中回复了老师:十分感谢老师指点...
  • w**3评论了k**y在课程中的作业:调用属性的时候不需要...
  • c**1向课程作业中提交了代码
  • c**h向课程作业中提交了代码
  • 天码君回复了s**1在课程中的问题:欢迎来到天码营学习,...
  • w**3回复了z**x在课程中的问题:怎么说呢,数组本身也...
  • s**1在课程作业中回复了老师:老师,麻烦再帮我看下...
  • 三年向课程作业中提交了代码
  • z**x添加了笔记:提高 关于类和Jav...
反馈意见