您的位置:首页 > 运维架构 > 网站架构

自己写架构笔记(2)----jdbc编码技巧与架构设计

2018-01-23 22:15 351 查看

1、学习JDBC在开发中常用的一些小技巧

常用数据类型

描述文本用的字符串类型(varchar)

金额核算的数值类型(int)

日期处理的日期类型(date)

数值类型与字符串类型的应用规律:

对于可能参与计算的列用数值类型,否则用字符串

3. 数据库编码体系

1、英文单词命名:比如员工信息表中的name

缺点:列名长度不等 多义词及近义词问题

2、汉语简拼(全拼)

缺陷: 列名长度不等, 重码太高(相重的机率大)

3、层级编码

其实层级编码在我们的生活中很常见,例如学生在学校的学号,居民的身份证号,其实都是按照层级去编码的,学号中的层级(可能前3位代表这个学院,中间纪委代表专业,后面是自己的学号)

使用层级编码有什么好处?在实际的需要中,我们需要大量的表,每张表里需要大量的列,这个时候如果我们使用最之前的英文编码,就会难以维护数据库,在遇到新的数据添加的时候,也是很难去找到相应的列。这个时候我们就可以使用层级编码,使用一些数字代码去表示每个列,每张表,只要我们自己记录好对应的真正的数据是什么,就可以加大开发的效率。

了解了什么是层级编码,我们在数据库编码的时候,其实我们也可以用层级编码,还是用之前的员工信息来说,我们有一个员工管理系统:其中有部门、岗位、员工、工资核算等。其中每个分支又有不同的几个部分,我们就可以如下图所示进行层级编码:例如,部门使用A1来代表,那么在这个部门下的部门编号这个属性,我们就可以用A1010,再有部门的规模属性,我们又可以用A1020,以此类推,我们可以使用这种“代码”来代表大量的属性,提高开发速率。



之前的写的员工登记界面,我们就可以这样去思考,将员工管理作为一个大的方面A1010,然后再将各个功能如下去层级编码:

a1010 — 数据查询

a1011 — 数据添加

a1012 — 单一实例查询

a1013 — 数据修改

a1014 — 单一实例删除

a1015 — 批量删除

每一个代表对应的一个servlet。

2、架构设计

架构设计的第一原则

约定大于配置,大于技术实现;

事先的规划大于事中的实施,大于事后问责

这句话是一个老师总结的,他告诉我的意思就是,一个良好的软件系统,首要的第一原则是有一个良好的架构,也就是必须先做好规划,做好自己的程序的各个层次,类似于MVC,你也可以按照自己的思想去写架构。

下面这张图是老师给我们说的他的架构设计的思想:



最外面的是显示层,显示层中的各种控件调用的是控制层,也就是servlet,我们并不在servlet中写业务逻辑,再单独写一个业务逻辑层。

3、员工信息录入数据库的例子

效果图

先看一下效果图:输入相应的信息,点击保存,页面显示是否成功,然后查看数据库中是否成功存入信息。



工程架构

该工程的结果图如下所示:



services包中存放的是业务逻辑,也就是一些具体的方法,例如这个项目中的A1010Services类,这里面存放了一个添加员工信息入数据库的方法

在services中的各种业务逻辑对应的java文件中,每个java中的方法都对应一个servlet,使用servlet来调用方法,例如,这个A1010Services.java中的add方法就对应着web中impl中的A1011Servlet,这个层级编码就是A1010中的多个方法分别对应着A1011Servlet,A1011Servlet,A1011Servlet等servlet。

support中BaseServlet是用来获取所有的页面的控件,并将其封装到dto对象中,然后利用dto对象来获得页面控件的值。

system中放一些工具,db中存放与数据库相关的方法,CodeFilter用来处理中文乱码问题。在获得数据的连接这个层面,我们如果直接把连接写到原代码中,额如果之后因为业务要求,需要换数据库,那么我们还要改源代码,改源代码是最危险的事情,所以我们要把能不放在源代码中的东西,就不放在源代码中,这里我们把连接的东西(url,uesename,password)放在.properties配置文件中,然后利用专有的工具去读,具体如下所示:

下面来看一下代码:

<%@ page language="java" pageEncoding="GBK"%>
<%@ taglib uri="http://org.wangxg/jsp/extl" prefix="e"%>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
${msg }
<br>
<br>
<form action="/ehr/a1011.html" method="post">
<table border="1" align="center" width="55%">
<caption>
员工建档
<hr width="160">
</caption>
<tr>
<td>姓名</td>
<td>
<e:text name="aab102" autofocus="true"/>
</td>
<td>身份证</td>
<td>
<e:text name="aab103"/>
</td>
</tr>
<tr>
<td>生日</td>
<td>
<e:date name="aab104"/>
</td>
<td>性别</td>
<td>
<e:radio name="aab105" value="男:1,女:2" defval="1"/>
</td>
</tr>
<tr>
<td>联系方式</td>
<td>
<e:text name="aab106"/>
</td>
<td>民族</td>
<td>
<e:select name="aab107" value="汉族:01,满族:02,蒙族:03,藏族:04,维族:05"/>
</td>
</tr>
<tr>
<td>邮件</td>
<td>
<e:email name="aab108"/>
</td>
<td>工资</td>
<td>
<e:number step="0.01" name="aab109"/>
</td>
</tr>
<tr>
<td>爱好</td>
<td colspan="3">
<e:groupbox name="aab110" value="Java:1,C:2,C++:3,C++--:4,C#:5,Python:6,GO:7"/>
</td>
</tr>
<tr>
<td>备注</td>
<td colspan="3">
<e:textarea rows="5" cols="45" name="aab111"/>
</td>
</tr>
<tr>
<td colspan="4" align="center">
<input type="submit" name="next" value="添加">
<input type="submit" name="next" value="返回">
</td>
</tr>
</table>
</form>
</body>
</html>


跳转到的Servlet:

package com.neusoft.web.impl;

import java.io.IOException;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.neusoft.web.support.BaseServlet;
import com.neusoft.services.A1010Services;

@WebServlet("/a1011.html")
public class A1011Servlet extends BaseServlet
{
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
try
{
//创建DTO
Map<String,Object> dto=this.createDto(request);
//实例化业务逻辑类
A1010Services services=new A1010Services(dto);
//调用业务逻辑方法
String msg=services.addAb01()?"添加成功!":"添加失败!";

//将数据保存到request中,通过request将数据带入页面
request.setAttribute("msg", msg);
}
catch(Exception ex)
{
request.setAttribute("msg", "提示:网络故障!");
ex.printStackTrace();
}

//从Servlet调回到JSP的语句
request.getRequestDispatcher("/A1011.jsp").forward(request, response);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
this.doGet(request, response);
}

}


再看一下这个servlet中用到的BaseServlet:

package com.neusoft.web.support;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;

public abstract class BaseServlet extends HttpServlet
{

/**
* 创建DTO,封装页面数据
* @param request
* @return
*/
protected  Map<String,Object> createDto(HttpServletRequest request)
{
//页面数据获取---对页面控件,案名取值
Map<String,String[]> tem=request.getParameterMap();

//定义页面数据的封装对象
Map<String,Object> dto=new HashMap<>();

//1.获取tem中所有的key形成集合
Set<String> keySet=tem.keySet();
//2.通过循环读取keySet中的每个key
for(String key:keySet)
{
//System.out.println(key);
//3.通过key获取对应的value数组
String val[]=tem.get(key);
//4.判断数组长度是否为1,如果是1,表示遇到的是非checkbox控件
if(val.length==1)
{
//System.out.println(key+"="+val[0]);
dto.put(key, val[0]);
}
else
{

ccde
//System.out.println(key+"="+val);
dto.put(key, val);
}
}
return dto;
}

}


servlet对应的services方法:

package com.neusoft.services;

import java.util.*;

import com.neusoft.system.db.DBUtils;

import java.sql.*;

public class A1010Services
{
private Map<String,Object> dto=null;

public A1010Services(Map<String,Object> dto)
{
this.dto=dto;
}

public boolean delete()throws Exception
{
Connection conn=DBUtils.getConnection();
return false;
}

public boolean addAb01()throws Exception
{
Connection conn=DBUtils.getConnection();
//System.out.println(conn);
//5.定义SQL
StringBuilder sql=new StringBuilder()
.append("insert into ab01(aab102,aab103,aab104,aab105,aab106,")
.append("                 aab107,aab108,aab109,aab110,aab111)")
.append("      values(?,?,?,?,?,")
.append("             ?,?,?,?,?)")
;
/**
* 6.编译SQL--通过连接对象编译SQL语句,生成预编译语句对象
* 编译完毕后,pstm就代表程序需要执行的SQL,以后对pstm进行的操作,就相当于对SQL进行的操作
*/
PreparedStatement pstm=conn.prepareStatement(sql.toString());
System.out.println(pstm);
//7.参数赋值:为语句对象相应位置的参数,替换具体值
pstm.setObject(1, this.dto.get("aab102"));
pstm.setObject(2, this.dto.get("aab103"));
pstm.setObject(3, this.dto.get("aab104"));
pstm.setObject(4, this.dto.get("aab105"));
pstm.setObject(5, this.dto.get("aab106"));
pstm.setObject(6, this.dto.get("aab107"));
pstm.setObject(7, this.dto.get("aab108"));
pstm.setObject(8, this.dto.get("aab109"));
pstm.setObject(9, "1");
pstm.setObject(10, this.dto.get("aab111"));
System.out.println(pstm);
//8.执行SQL
/**
* res代表SQL语句执行后,影响的行数
* 如果执行成功,返回值是影响的行数,对于insert,值一般是1,如果失败返回0
*/
int res=pstm.executeUpdate();
//9.处理结果
return res>0;
}
}


数据库DBUtils文件:

package com.neusoft.system.db;

import java.sql.*;
//资源文件解析器
import java.util.ResourceBundle;

public class DBUtils
{
//1.定义驱动串---整个驱动jar包中,核心类的路径
private static String driver=null;
//2.定义链接串---数据库所在的位置及名称
private static String url=null;
private static String userName=null;
private static String password=null;

/**
* 静态块
* 在类被第一次加载入内存时候,执行,以后不再执行
*/
static
{
System.out.println("run static .......");
try
{
//获取资源文件解析器实例
ResourceBundle bundle=ResourceBundle.getBundle("DBOPtions");
//从资源文件获取数据
driver=bundle.getString("DRIVER");
url=bundle.getString("URL");
userName=bundle.getString("USERNAME");
password=bundle.getString("PASSWORD");

//3.加载驱动
Class.forName(driver);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}

/**
* 当一个类中所有的成员(属性和方法)都是static,那么此时构造器应该私有
*/
private DBUtils() {}

public static Connection getConnection()throws Exception
{
//4.创建链接
Connection conn=DriverManager.getConnection(url, userName, password);
return conn;
}

public static void main(String[] args)
{
try
{
for(int i=0;i<10;i++)
{
System.out.println(DBUtils.getConnection());
}
}
catch(Exception ex)
{
ex.printStackTrace();
}
}

}


中文乱码处理的过滤器:

package com.neusoft.system.tools;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServlet;

/**
* Servlet Filter implementation class CodeFilter
*/
@WebFilter("/*")
public class CodeFilter extends HttpServlet implements Filter
{
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{

//将服务器编码格式转换成GBK
request.setCharacterEncoding("GBK");

//让请求到达目标Servlet
chain.doFilter(request, response);
}

/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}

}


和数据库有关的配置文件:

DRIVER=com.mysql.jdbc.Driver
URL=jdbc:mysql://localhost/ehr?characterEncoding=GBK
USERNAME=root
PASSWORD=


4、中文乱码



http协议中的两种提交的方法,编码格式如上图所示,其中POST方法,数据体的编码格式是页面指定的编码格式,本来在jsp指定的GBK编码,在提交给服务器之后,又以ISO-8859-1编码,所以会产生中文乱码,这里我们只要指定request的编码为GBK,就不会产生中文乱码,采用过滤器来对每个页面进行过滤,将每个请求的编码指定为GBK:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
{

//将服务器编码格式转换成GBK
request.setCharacterEncoding("GBK");

//让请求到达目标Servlet
chain.doFilter(request, response);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐