当前位置:   article > 正文

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

jdbc 编码

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

常用数据类型
  1. 描述文本用的字符串类型(varchar)
  2. 金额核算的数值类型(int)
  3. 日期处理的日期类型(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>
  • 1
  • 2
  • 3
  • 4
  • 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
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

跳转到的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);
}

}
  • 1
  • 2
  • 3
  • 4
  • 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
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

再看一下这个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
        {
            //System.out.println(key+"="+val);
            dto.put(key, val);
        }   
    }
    return dto;
}



}
  • 1
  • 2
  • 3
  • 4
  • 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
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

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;
}
}
  • 1
  • 2
  • 3
  • 4
  • 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
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65

数据库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();
    }
}

}
  • 1
  • 2
  • 3
  • 4
  • 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
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

中文乱码处理的过滤器:

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
}

}
  • 1
  • 2
  • 3
  • 4
  • 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

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

DRIVER=com.mysql.jdbc.Driver
URL=jdbc:mysql://localhost/ehr?characterEncoding=GBK
USERNAME=root
PASSWORD=
  • 1
  • 2
  • 3
  • 4

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);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/1004821
推荐阅读
相关标签
  

闽ICP备14008679号