Java Web项目开发从0开始的要点!
前言
本文章详细的列出了开发一个传统JavaWeb项目需要注意的要点,从环境准备开始到三层架构搭建,需要注意的地方全部罗列出来。
第一部分:环境准备
1. Maven命令创建web骨架
mvn archetype:create -DgroupId=net.rocketa -DartifactId=mywebapp -DarchetypeArtifactId=maven-archetype-webapp
注意web servlet版本(web.xml,3.1),Junit版本指定为4.X(这样Spring好通过注解的方式来运行单元测试)
2. 注意在IDEA中需要设置好MAVEN工程的Sources/Tests/Resources/Test Resources属性。
3. 日志依赖
slf4j:规范和接口
具体的日志实现有:
log4j、logback、common-logging
因此我们一般是使用slf4j接口+一种具体的日志实现+slf4j和这个具体日志实现的依赖整合
4. 数据库依赖
有2个依赖,需要注意,一个是驱动,一个是数据库连接池(C3P0,DBCP...)。
驱动JAR包是运行期需要包含,编译期不需要的。
5. 持久层框架依赖
说白了,DAO层的框架依赖:MyBatis or Hibernate or ....
比如除MyBatis本身的依赖需要引入之外,还需要引入MyBatis和Spring的整合依赖。
6. Web层依赖
比如,JSP中使用到的一些JSTL、标签、Ajax访问JSON等,还有需要注意的是,在编译期需要引入servlet-api。
7. Spring核心依赖
spring-core、spring-beans、spring-context
8. Spring和DB之间的整合依赖
Spring是需要介入DB的管理的,比如它的声明式事务。
spring-jdbc、spring-tx
9. Spring对Web的一些整合依赖
spring-web、spring-webmvc
10. Spring对Junit的支持依赖
spring-test
NOSQL对事务的支持不是很好,它主要追求的是性能、高可用、分布式。
MySQL等关系型数据库对事务的支持是很成熟的,也是很可靠的落地方案。
第二部分:DAO层
NOSQL对事务的支持不是很好,它主要追求的是性能、高可用、分布式。
MySQL等关系型数据库对事务的支持是很成熟的,也是很可靠的落地方案。
1. 表
可以在项目中建立一个SQL文件,便于SQL的管理。
注意,表的存储引擎(事务的支持:innodb)、自动增长的特性、编码、主键和索引。
一个良好的习惯是:为所有的表都添加一个创建时间字段,用于记录,方便排查。
应该为表名、列名添加注释,方便其他工程师查阅。
应该注意SQL技巧,比如插入存在唯一约束的表中,如果出现冲突不想报错的话,可以:insert ignore into ….(可以通过返回的影响行数来进行判断)
2. Dao层实体
一些业务对象的建立,setter/getter/toString等就不说了,需要特别注意的是,除了表的字段之外,还需要什么属性?这里涉及到一个一对一、一对多,多对多的概念!
3. Dao层接口和mapper sql
MyBatis的特点:从SQL(参数+sql)映射到Entity/List(定制SQL、自由传递参数、结果集自动赋值)
使用MyBatis的方式:SQL写在XML中,或者注解提供SQL。更加推荐的是XML,因为更加灵活,XML提供的动态拼接功能也是比注解简单的多。
一个全局的mybatis配置文件+具体的SQL文件+DAO接口:让我们只需要设计接口,关注业务逻辑,解放出来。
在全局mybatis配置文件中重点注意:是否开启驼峰转换,获取数据库自增主键,列别名替换列名等。
注意DAO接口和具体的SQL文件之间的对应关系。
具体SQL写法中,比如#{},等需要引起注意。
输入参数类型parameterType,如果是多个基本类型,那么不用给出来。
即便返回的是List对象,我们的resultType依然指定的是集合中的对象类型。
在Mybatis的SQL文件中是可以通过OGNL表达式来对对象中的一些对象类型的属性进行赋值的!
表名.xxx 或者 表名.xxx as yyy 对于Mybatis而言,会忽略表名.前缀,也会忽略as。
另外,注意在Dao接口中,如果方法有多个基本类型参数,别忘了通过@Param来进行运行期参数标记!
总结:Dao层的工作逐渐演变成接口设计和SQL编写了,这种代码和SQL的分离方式,便于我们进行review,而Dao的拼接将在Service层完成。
4. 一些优化配置
比如,对带包路径的类型进行简化,通过配置扫描包。
比如,批量扫描SQL文件,通过自动扫描配置文件。
5. mybatis和spring需要整合
spring需要接管数据库
JDBC的一些连接信息,数据库连接池的一些配置信息,就是配置DataSource的过程。
spring和mybatis整合的核心
SqlSessionFactory是MyBatis的配置核心,把DataSource注入,并指明MyBatis的全局配置文件位置,typeAliasesPackage扫描,mapper文件位置扫描等。
spring通过动态代理帮助生成Dao的代理实现类(MapperScannerConfigurer)
注入SqlSessionFactory(通过sqlSessionFactoryBeanName),指明Dao接口的包路径basePackage
总之,配置的一项原则是:约定优于配置!!!
第三部分:进行Spring Junit单元测试
当我们进行了一些配置,写了一些SQL,Dao接口后,应该要进行Spring Junit单元测试,可以通过IDEA快速的生成测试用例(很好用的一个功能,因为IDEA可以帮助我们快速在test下建立与dao/service接口的同级目录下生成用例)
在用例中,我们只需要在类上打上注解:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring配置文件"})
加载Spring容器后,我们就可以在用例中注入对象,开始测试了!!!
第四部分:Service层
Service层需要关注几个要点:
业务对象的封装、web和service之间进行数据传递的DTO、异常的处理(业务异常)
注意Spring事务回退的默认机制是:运行时异常。
因此,我们在service层默认定义的业务异常一般extends RuntimeException。
一般而言,通过:
try{
}catch(业务异常1 e1){
}catch(业务异常2 e2){
}catch(Exception e){
throw new 业务异常(...);
}
要知道,service层可能会发生业务异常,也可能发生一些其他异常,为了Spring都可以感知到,这里会把Exception异常转化成运行时异常
第五部分:Controller层
1. Restful
一种优雅的URI表述方式;资源的状态;状态的转移
Restful示例:
GET /product/list 查询操作
GET /product/{productId}/detail
GET /product/time/now
POST /product/{productId}/execution 添加、修改操作【非幂等性】
POST /product/{productId}/{userId}/order
DELETE /product/{productId}/delete 删除操作
PUT 修改操作【幂等性】
URL设计:
/模块/资源/{标示}/集合1/...
2.Controller中请求方法的细节处理
考虑几个方面:请求参数绑定、请求方式限制、转发与重定向、数据模型赋值、JSON数据返回、Cookie访问
@RequestMapping(value="/{productId:\d+}/detail",method=RequestMethod.GET,produces={"application/json;charset=UTF-8"})
@ResponseBody
public String detail(
@PathVariable("productId") Long productId,@CookieValue(value="userId",required=false) Long userId,Model model){
# return "rediect:/xxx/yyy"
# return "forward:/xxx/yyy"
# return "view"
}
3.整合配置Spring MVC
在web.xml中配置DispatcherServlet拦截请求,并指出Spring相关的配置文件。
开启Spring MVC的注解模式:
静态资源请求采用默认的servlet配置
配置JSP、ViewResolver的prefix「如/WEB-INF/jsp」suffix「如.jsp」
扫描web相关的Controller:
OK,先整理到这里。
原文发布时间为:2018-11-25
本文来自云栖社区合作伙伴“互联网架构师”,了解相关信息可以关注“互联网架构师”。
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
刚写完排序算法,就被开除了…
据说是一个月薪 9K 的 Java 程序员,因老板让他写一个排序算法,然后他就写了一段屌炸天的休眠排序算法,接着他就被老板开除了…… 排序算法代码大概是这样的: 这段代码有什么问题? 这个程序员更屌啊,数字排序,用一行简单的 Arrays.sort 就搞定的东西,他竟用到了这么多概念。 1、循环 2、线程休眠 3、多线程 下面贴上完整的代码: /** *微信公众号:Java技术栈 */publicclassArraySortimplementsRunnable{ privateintnumber; publicArraySort(intnumber){ this.number=number; } publicstaticvoidmain(String[]args){ int[]numbers=newint[]{102,338,62,9132,580,666}; for(intnumber:numbers){ newThread(newArraySort(number)).start(); } } @Override publicvoidrun(){ try{ Thread.sleep(...
- 下一篇
为什么你会觉得微服务架构很别扭
很多系统迁移到微服务架构之后,并没有明显感觉到微服务架构带来的优势,反而觉得带来了更高的复杂度,王启军在《持续演进的Cloud Native》书中总结了七种微服务架构没能发挥出固有优势的原因,看看自己“中枪”了没! 1、用传统方式构建微服务 微服务架构和传统的架构方式思路完全不一样。例如传统方式实现高可用,更相信流程,更相信KPI对人的影响,因此流程需要让更多的人去测试,制定更严格的发布流程。 而微服务架构强调的是自动化发布、灰度发布、Design For Failure、自动化测试、故障隔离、自愈。很多失败的案例以传统的方式去构建微服务架构,一切都没有转变,只是把服务拆开,根本无法享受微服务架构带来的便利,反而因此遇到了更多麻烦。最明显的是对开发人员的影响,他们质疑微服务架构是否适合自己的业务场景,而一个充满质疑的团队是不可能具备强大战斗力的。 2、组织结构不变 如果要充分发挥微服务架构的优势,组织结构必须发生转变,构建和微服务配套的小团队,并且让他们拥有绝对的自主权。实际上,相当一部分实施微服务架构的团队都没有做到这一点,因为组织结构总是涉及利益。比较典型的问题是,小团队不需要团队...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- MySQL8.0.19开启GTID主从同步CentOS8
- Mario游戏-低调大师作品
- CentOS关闭SELinux安全模块
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Red5直播服务器,属于Java语言的直播服务器
- CentOS8编译安装MySQL8.0.19
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池