基础开发培训

开发语言介绍

前台 Bootstrap

由 Twitter 开源的一个 CSS/HTML 框架, Bootstrap 是基于 HTML5 和 CSS3 开发的,它在 jQuery 的基础上进行了更为个性化和人性化的完善。 Bootstrap 自带丰富的 Web 组件,如:下拉菜单、按钮组、按钮下拉菜单、导航、导航条、路径导航、分页、排版、缩略图、警告对话框、进度条、媒体对象等。
参见: http://v3.bootcss.com/components/

后台 Java 代码

采用 JDK1.7 及其以上版本,下载地址: http://www.oracle.com/technetwork/java/javase/archive-139210.html

开发工具介绍

开发工具

使用 Eclipse 进行开发。下载地址: https://www.eclipse.org/downloads/eclipse-packages/

中间件

使用 Tomcat 作为开发 web 服务器进行开发,使用最新的 7 及其以上版本。下载地址: https://tomcat.apache.org/download-80.cgi

数据库

MySQL 和 Oracle 都有兼容。

SVN 使用介绍

版本控制工具,代码统一放在公司 SVN 服务器上。

常用的一些操作:

  • 检出( checkout )
  • 更新(update)
  • 提交( commit)
  • 同步(sync)

数据库介绍

为了使代码要同时兼容 OracleMySQL 两种数据库,所以在拼写 SQL 的时候尽量避免大量使用数据库自身特有的函数。为此需要了解哪些函数是 Oracle 的,哪些函数是 MySQL 的,如若避免不了使用这些函数,请在 SQL 的 XML 文件中使用<mysql><oracle>标签进行明确标出。这样在工程启动的时候,mybatis 会根据配置文件中指定的方言,解析为指定的 SQL 语句,装入到内存。

为什么使用 mybatis

Hibernate 与 Mybatis 都是较为流行的 ORM 框架,且开发社区也相对活跃。 Hibernate 的真正掌握要比 Mybatis 来得难些。Mybatis 框架相对简单很容易上手,Hibernate 入门和优化的门槛较高。Hibernate 适用于中小企业需求变化不多的项目, mybatis 专注 sql 本身,程序员自己写 sql 语句,sql 的修改与优化比较方便,适用于需求变化较多的项目。

开发框架简介

开发组件简介

后台目录结构

1
2
3
4
5
|--Java Resource
|--api:存放所有的接口类
|--business:存放所有的Service业务逻辑
|--controller:存放所有的Action类
|--resources:存放所有的资源文件

前台目录结构

1
2
3
4
5
6
7
8
9
10
11
resource:存放所有前台静态文件
|--css:存放所有样式文件
|--image:存放所有的图片文件
|--js:存放所有的JS文件
|--less:存放所有的less文件
|--plugin:存放所有的插件
uploadfiles:文件上传附件的目录
WEB-INF:存放页面和配置文件
|--conf:存放系统配置文件
|--lib:存放依赖的jar
|--view:存放业务模块对应的JSP文件

配置文件介绍

修改指定的配置文件,启动工程。修改如下几个重要的配置文件:

1
2
3
4
5
6
resource(资源目录)
|-- applicationContext.xml(修改数据库的链接方式)
|-- casFilterConfig.xml(指定使用的认证)
|-- config.xml(修改具体的配置参数)
|-- mybatis-config.xml(修改分页使用的方言)
|-- redis-context.xml(修改使用的缓存服务器信息)

简单的增删改查

通过代码生成器可以快速的生成简单的代码样例,根据自己的业务逻辑需求在此基础上进行修改即可。点击 【创建】 按钮之前需要填写部分内容,填写说明如下:

  • 应用:代码中划分为多个应用,此处填写应用对应的英文简称。
  • 模块:填写在应用下对应的模块英文简称。
  • 表名:填写模块对应的数据库中的业务表,填写后会生成简单的 SQL 语句。
  • 生成前/后台代码复选框:选中指定的复选框生成对应的代码。

代码结构及其分布

代码生成器究竟做了什么?

  1. 生成 javascript 文件,会产生一个 WebContent/resource/js/应用/业务模块/模块名.js 文件。此文件中按照规则自动帮你生成了命名空间和一些 JS 样例代码。

  2. 生成一个 JSP 文件,会创建一个 WebContent/WEB-INF/view/应用/业务模块/模块名.jsp 文件。此文件中会自动引入 jstl、htmlcompressor 标签、common.jsp 和自身所依赖的 javascript 文件。jstl 是 JSP 的一个标准的标签库,启动能包括迭代和条件判断、数据管理格式化、XML 操作以及数据库访问。 Htmlcompressor 作用是将页面元素进行压缩,进来减少网络的 IO 传输。common.jsp 声明了一些公用的变量。

  3. 生成一个 Action 类, 创建一个 controller/com/应用/业务模块/action/业务模块 Action.java 的文件。该类中会自动继承 SecurityBaseAction 这个抽象类,为此其自身也就具有了 SecurityBaseAction 中的所有方法的功能。在继承该类的同时需要通过泛型传递两个参数,第一个参数指定自身所依赖的 Service,第二个参数指定查询结果的返回类型(默认是 Map,如果有特殊需要可以使用自定义实体)。

  4. 生成一个 Service 接口,创建一个 api/com/应用/业务模块/service/业务模块 Service.java 的文件,该 Service 继承 SecurityBaseService 接口。

  5. 生成 Service 的实现类,创建一个 business/com/应用/业务模块/service/业务模块名 ServiceImpl.java 的文件。该文件继承 BaseServiceImpl 基类并实现了自己的 Service 接口。继承基类的时候需要通过泛型传递两个参数,第一个为改 Service 中所依赖的 Mapper 接口类,第二个为查询的时候返回的类型(默认是 Map,如有特殊需求可以自己定义实体)。实现自己的 Service 接口的时候同样需要通过泛型传查询时返回的数据类型。

  6. 生成一个 Mapper 的接口,创建一个 business/com/应用/业务模块/mapper/业务模块名 Mapper.java 的文件。

  7. 生成一个 XML 文件,创建一个 business/com/应用/业务模块/mapper/业务模块名 Mapper.xml 的文件。在该文件中会根据前台输入的数据表自动生成 CRUD 的 SQL 语句。

几个基础的公共类

开发时为了尽快排除和定位问题,为了使开发人员尽快上手,介绍如下几个基类:

  • Cas20ProxyReceivingTicketValidationFilter:路径 tp-common-1.0.jar/com/tp/cas/ 登录成功之后 cas 回调该类中的 onSuccessfulValidation 方法,该方法会初始化当前登录人员的所有相关信息。

  • CommonAction: 路径 tp-common-1.0.jar/com/tp/base/action/ 存放了一些公共的方法,如:首页、404、500、403、注销、上传、下载、截图、获取 token。

  • SecurityBaseAction:路径 controller/com/tp/base/action/ 基础的 Action,所有业务模块的 Action 均继承了这个抽象类,该类中实现了公共的分页查询(page)、查询全部(list)、获取指定对象(get)、保存或修改(saveOrUpdate)、添加(add)、批量添加(addBatch)、修改(update)、批量修改(updateBatch)、删除(delete)、判断对象是否存在(exist)、记录的状态切换(toggle)、获取当前用户(getCurrentUser)等。

  • BaseServiceImpl:路径 tp-common-1.0.jar/com/tp/base/service/ 基础的 Service 实现类,所有业务模块的 Server 均继承该类,此类中实现了基础的 CRUD。

  • AuthenticationInterceptor:路径 tp-common-1.0.jar/com/tp/interceptor/ 判断当前用户是否有权限访问系统资源的一个拦截器(springmvc interceptor)。

  • LoggerInterceptor:路径 tp-common-1.0.jar/com/tp/interceptor/ 用于记录用户操作日志的拦截器(springmvc interceptor)。

  • ParameterInterceptor:路径 tp-common-1.0.jar/com/tp/interceptor/ 前台传递参数到后台执行 SQL 语句的拦截器(mybatis interceptor)。

  • SqlTimeInterceptor:路径 tp-common-1.0.jar/com/tp/interceptor/ 记录 SQL 日志信息的拦截器(mybatis interceptor)。

  • common.js:路径 resource/plugin/ 封装了很多公用的 JS 方法,封装的原因好比系统中的提示框,现在用的 layer,如果有一天不再用这个 layer 了,直接修改 common.js 里面的公共方法,则所有业务模块的提示框就全变了,而不用到每个业务模块中到处进行修改。便于统一管理和维护。

前台公共方法简介

  1. 获取 URL 上面的参数:$.getParameter(“参数名”);
  2. 日志格式化:$.formatDate(“yyyy-MM-dd hh:mm:ss” , new Date());
  3. 加载右侧页面:Util.load(加载的 URL 地址 , 加载前回调 , 加载后回调);
  4. 分页获取列表:Util. getPageObjListByForm(参数);
  5. 发送异步请求:Util. ajax(参数);
  6. 渲染模板:Util. renderTemplet(参数);
  7. 获取 token:Util. getToken(参数);
  8. 删除记录:Util. deleteRecord(参数);
  9. 渲染列表:Util. dataTables(参数);
  10. 页面表单弹窗:Util. formModal(参数);
  11. 字典转换:Util. convertSysDic(字典表名,key);
  12. 设置浏览器的 hash 值:Util. setHash(hash 值);
  13. 替换指定的 hash 值:Util. replaceHash(key , value);
  14. 获取 hash 值:Util. getHash(hash , key , 默认值);
  15. 判断对象是否为空:Util. isNotEmpty(值);
  16. 截取字符串:Util. subStr(字符串,长度);
  17. 联想:Util. autocomplete();
  18. 设置 cookie:Util. setCookie(键,值,过期时间);
  19. 获取 cookie:Util. getCookie(键);
  20. 裁剪图片:Util.crop(回调,模块名字,操作类型,图片路径,宽度,高度,X 轴,Y 轴);
  21. 系统提示,操作成功:Msg.success(提示信息);
  22. 系统提示,操作失败:Msg.error(提示信息);
  23. 系统提示,警告:Msg.warning(提示信息,回调函数);
  24. 系统提示,信息:Msg.info(提示信息);
  25. 系统提示,确认:Msg.confirm(提示信息,回调函数);
  26. 加载条:Msg.load();
  27. 关闭系统提示:Msg.close(提示对象);
  28. 页面弹出层:Msg.open(配置参数);

页面中的公共依赖组件

  1. 日期 my97,具体功能参见:http://www.my97.net/
  2. 树组件 zTree,具体功能参见:http://www.treejs.cn/
  3. 系统弹出框 layer,具体功能参见:http://layer.layui.com/
  4. 上传组件 webuploader,具体功能参见:http://fex.baidu.com/webuploader/
  5. 页面图表 echart,具体功能参见:http://echarts.baidu.com/
  6. 模板渲染 artTemplate,具体功能参见:https://github.com/aui/artTemplate
  7. 表格插件 datatables,具体功能参见:http://datatables.club/
  8. 前台校验 jQuery Validation,具体功能参见:http://jqueryvalidation.org/
  9. 网站使用的响应式布局框架 bootstrap,具体说明参见:http://www.bootcss.com/

开发习惯养成

前台编码注意事项

  1. 尽量减少 HTTP 请求个数:合并图片,CSS,JS,避免没有必要的数据请求;
  2. 避免空的 src 和 href:留意具有这两个属性的标签如 link,script,img,iframe 等;
  3. 使用 gzip 压缩内容:压缩所有可能的文件类型以来减少文件体积;
  4. 把 CSS 放到顶部,把 JS 放到底部:确保用户至少能早一点看到界面,让网站看起来至少反应快一点,所以应该把必须的 js 和 css 放顶部,把不那么重要的 css 和 js 放底部;
  5. 自己写的 JS 里面注意使用命名空间,在使用 hashchange 的时候注意不要产生多余的事件处理。在 JSP 中自定义页面 Id 的时候要尽量不要和其他页面中的 Id 重复。

后台编码注意事项

  1. 系统级别的配置请使用系统常量进行声明(见: SystemConstant );
  2. 如果想加日志的输出请使用 slf4j 按日志级别进行输出;
  3. 在自定义的 Action 当中无需自己重复注入自身所依赖的 Service,直接使用即可;
  4. 同理在自定义的 Service 之中无需自己重复注入自身所依赖的 Mapper,直接使用即可;
  5. 如果需要事务包裹,请在自己的 Service 方法上使用 @Transactional 注解;
  6. 为减少不必要的麻烦,请不要在 XML 文件的 SQL 语句中带有中文;
  7. 为了防止 SQL 注入,前台传递到 SQL 中的参数均进行了 SQL 关键字的特殊处理,如需忽略系统的转换,请在指定的 SQL 语句中使用“/ignoreParameter/”进行说明。为此出现的 SQL 攻击,请自行解决。

SQL 语句注意事项

  1. 获取唯一 一行时使用 limit 1:

    1
    select user_id , user_name from sys_uicm_user where id_number =09901

    1
    select user_id , user_name from sys_uicm_user where id_number =09901’ limit 1;

    当你已经知道获取的记录只有一行时,请将 limit 1 添加到 where 语句后面。这样数据库引擎在找到第一个符合条件的记录后就停止扫描了,而不是遍历整个表或索引。

  2. 避免使用 select *:
    从表中读取的数据越多,查询速度越慢。增加了磁盘操作所需的时间,数据库与 web 服务器分开时,增加了网络传输的 IO,同理 web 服务器和客户端也存在网络的传输。也增加了服务器将查询出来的对象进行 json 序列化所需的时间。

  3. 数据库中的字段类型与所占空间大小适当(如:使用 INT 来存储 IP 地址):
    一般存储一个 IP 字段至少是 varchar(15),如果用 INT 只需要 4 个字节的空间,而且字段长度固定。

  4. 大表分页:
    当起始页较小时,查询没有性能问题。随着起始记录的增加,时间也随着增大。

    1
    2
    3
    4
    select * from  user  limit 10, 20   0.016 秒
    select * from  user  limit 10000, 20   0.094 秒
    select * from  user  limit 400000, 20   3.229 秒
    SELECT * FROM  user  a JOIN (select id from  user  limit  400000, 20) b ON a.id = b.id 0.2 秒

SQL 语句调优基本原则

  1. 避免全表扫描;
  2. 建立索引(合理使用索引,索引一定不是越多越好);
  3. 尽量避免大事务操作(事务时间尽可能短),提高系统并发能力;
  4. 尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理;
  5. 语句中字段比较的时候,请使用同类型比较;
  6. 尽量避免在 where 子句中对字段进行表达式操作和函数操作;
  7. 应尽量避免在 where 子句中使用 or 来连接条件,可以考虑使用 union 代替;
  8. 使用 union all 替代 union ,因为 union 有去重开销;
  9. 应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描;
  10. in 和 not in 也要慎用,对于连续的数值,能用 between 就不要用 in,exists 代替 in;
  11. 不用 select * , 消耗 cpu,io,内存,带宽;
  12. 尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销;
  13. 尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为变长字段存储空间小,对于查询来说,在一个相对较小的字段内搜索效率显然要高些;
作者

buubiu

发布于

2020-07-14

更新于

2024-01-25

许可协议