首页 > 其他 > 详细

架构探险笔记2

时间:2018-08-24 10:06:44      阅读:138      评论:0      收藏:0      [点我收藏+]

系统设计

一个web项目,先从原始需求开始分析,找出需求中涉及到的Use Case(案例),然后涉及表结构,画原型图,定义URL规范。

1.设计用例

找出功能点,可以用一张UML的”用例图“来描绘以上用例,这样效果会更好,UML流程图可以用visio画图。

2.设计表结构

根据需求,找到核心的业务实体,创建对应的表。

建议:

表明与字段名均为小写,若多个单词可用“下划线”分割;

每张表都要有一个唯一ID主键字段

数据类型尽可能统一,不要出现太多数据类型

个人一般比较喜欢用powerdesigner,设计好表后可以直接生成sql语句。

3.设计界面原型

可以使用Balsqmiq Mockups软件,这是一款比较Q的软件,可以快速地画出界面原型,感受一下画风。

技术分享图片

(这个画风让我想起了饥荒这款游戏。。。。。)

 4.设计URL

设计出url与页面跳转及接口的对应关系

举个栗子

URL  描述
GET:/customer 进入列表查询界面
GET:/customer_create 进入新增界面
POST:/customer_create 新增
DELETE:/customer_delete/{id}  删除

创建数据库

创建数据库编码方式统一为UTF-8,以免编码不一致导致中文乱码。

建立连接后,New Database输入Database Name和Character set,点击确定。

技术分享图片技术分享图片

这里使用的工具为Navicat。

准备开发环境

新建一个maven项目,具体步骤参照上一篇笔记。 

这里不用框架,用servlet+jsp写一个mvc架构的项目。

编写模型层

 技术分享图片

数据库中添加表

CREATE TABLE `customer`(
    `id` BIGINT(20) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(255) DEFAULT NULL,
    `contact` VARCHAR(255) DEFAULT NULL,
    `telephone` VARCHAR(255) DEFAULT NULL,
    `email` VARCHAR(255) DEFAULT NULL,
    `remark` text,
     PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

编写控制器层

一个servlet只有一个请求路径,但可以处理多种不同的请求,请求类型有GET、POST、PUT、DELETE

这里因为是servlet3.0所以不用在web.xml中配置servlet及映射mapping,只需要用@WebServlet注解即可

技术分享图片

编写服务层

package com.smart4j.chapter2.service;/**
 * Created by Administrator on 2018/8/13.
 */

import com.smart4j.chapter2.model.Customer;

import java.util.List;
import java.util.Map;

/**
 * @program: chapter2->CustomerService
 * @description: 客户服务层
 * @author: qiuyu
 * @create: 2018-08-13 20:15
 **/
public class CustomerService {
    
    /** 
    * @Description: 获取客户列表
    * @Param: [] 
    * @return: java.util.List<com.smart4j.chapter2.model.Customer> 
    * @Author: qiuyu
    * @Date: 2018/8/13 
    */ 
    public List<Customer> getCustomerList(String keyWord){
        //TODO
        return  null;
    }

    /** 
    * @Description: 根据id获取客户
    * @Param: [id] 
    * @return: com.smart4j.chapter2.model.Customer 
    * @Author: qiuyu
    * @Date: 2018/8/13 
    */ 
    public Customer getCustomer(long id){
        //todo
        return null;
    }
    /**
    * @Description:  创建客户
    * @Param: [fieldMap]
    * @return: boolean
    * @Author: qiuyu
    * @Date: 2018/8/13
    */
    public boolean createCustomer(Map<String,Object> fieldMap){
        //todo
        return false;
    }

    /** 
    * @Description: 更新客户
    * @Param: [] 
    * @return: boolean 
    * @Author: qiuyu
    * @Date: 2018/8/13 
    */ 
    public boolean updateCustomer(long id,Map<String,Object> fieldMap){
        //todo
        return false;
    }

    /** 
    * @Description: 删除客户
    * @Param: [] 
    * @return: boolean 
    * @Author: qiuyu
    * @Date: 2018/8/13 
    */ 
    public boolean deleteCustomer(long id){
        //todo
        return false;
    }
    
}

编写单元测试

首先要在pom.xml中添加依赖

        <!--JUnit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

编写单元测试

/**
 * Created by Administrator on 2018/8/13.
 */

import com.smart4j.chapter2.model.Customer;
import com.smart4j.chapter2.service.CustomerService;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: chapter2->CustomerServiceText
 * @description: 客户测试类
 * @author: qiuyu
 * @create: 2018-08-13 20:24
 **/
public class CustomerServiceText {
    private final CustomerService customerService;

    public CustomerServiceText() {
        customerService = new CustomerService();
    }

    @Before
   public void init(){
        //初始化数据库
   }

   @Test
   public void getCustomerListText(){
       List<Customer> customerList =customerService.getCustomerList("");
       Assert.assertEquals(2,customerList.size());
   }
   @Test
   public void getCustomerTest(){
       long id =1;
       Customer customer = customerService.getCustomer(id);
       Assert.assertNotNull(customer);
   }
   @Test
   public void createCustomerTest(){
       Map<String,Object> fieldMap = new HashMap<String, Object>();
       fieldMap.put("name","小猪佩琪");
       fieldMap.put("contact","John");
       fieldMap.put("telephone","18151449650");
       boolean result = customerService.createCustomer(fieldMap);
       Assert.assertTrue(result);
   }

   @Test
   public void updateCustomerTest(){
       long id =1;
       Map<String,Object> fieldMap = new HashMap<String,Object>();
       fieldMap.put("contact","Aeolian");
       boolean result = customerService.updateCustomer(id,fieldMap);
       Assert.assertTrue(result);
   }

   @Test
   public void deleteCustomer(){
       long id =1;
       boolean result = customerService.deleteCustomer(id);
       Assert.assertTrue(result);
   }
}

视图层

使用JSP充当视图层,在WEB-INF/view目录下存放所有的JSP文件。推荐将JSP放入到WEB-INF内部,因为用户无法通过浏览器地址栏直接请求放在WEB-INF内部的JSP文件,必须通过Servlet进行转发或者重定向。

技术分享图片

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>客户管理-创建客户</title>
</head>
<body>

<h1>创建客户界面</h1>
<%--TODO--%>
</body>
</html>

日志 

在pom.xml中添加日志依赖

        <!--slf4j-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.77</version>
        </dependency>

在main/resource目录下新建一个名为log4j.properties的文件

log4j.rootLogger=ERROR,console,file

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%m%n

log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File=${user.home}/logs/book.log
log4j.appender.file.DatePattern=‘_‘yyyyMMdd
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{HH:mm:ss,SSS} %p %c (%L) -%m %n

log4j.logger.org.smart4j=DEBUG

将日志级别设置为DEBUG,并提供了两种日志appender,分别是console与file。最后一句制定只有org.smart4j包下的类才能输出DEBUG级别的日志。

测试,这里user.home为C:\Users\Administrator

public class PropsUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(PropsUtil.class);

    public static void main(String[] args) throws IOException {
        /*测试日志*/
        LOGGER.error("text");
    }
}

技术分享图片

数据库

添加mysql依赖以及两个apache常用依赖

        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.33</version>
            <scope>runtime</scope>
        </dependency>
        <!--Apache Commons Lang-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <!--Apache Commons Collections-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-collections4</artifactId>
            <version>4.0</version>
        </dependency>

配置confg.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://******:3306/demo2?characterEncoding=utf-8
jdbc.username=root
jdbc.password=***密码****
jdbc.wait_timeout=600

编写常用工具类properties文件读写、类型转换、字符串工具类、集合工具类

详细链接Java开发常用Util工具类-StringUtil、CastUtil、CollectionUtil、PropsUtil

数据库操作类

数据库操作类DBHelper.java,用于初始化数据库,打开连接,关闭连接。 

package com.smart4j.chapter.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @program: DBHelper
 * @description: 数据库操作类
 **/
public class DBHelper {
    private static final Logger LOGGER = LoggerFactory.getLogger(DBHelper.class);

    private static final String DRIVER;
    private static final String URL;
    private static final String USERNAME;
    private static final String PASSWORD;

    /**
     * 静态代码块在类加载时运行
     */
    static{
        Properties conf = PropsUtil.loadProps("config.properties");
        DRIVER = conf.getProperty("jdbc.driver");
        URL = conf.getProperty("jdbc.url");
        USERNAME = conf.getProperty("jdbc.username");
        PASSWORD = conf.getProperty("jdbc.password");

        try {
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            //e.printStackTrace();
            LOGGER.error("can not load jdbc driver",e);
        }
    }

    /**
     * 获取数据库连接
     * @return
     */
    public static Connection getConnection(){
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(URL,USERNAME,PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();  //在catlina.out中打印
            LOGGER.error("get connection failure",e);
        }
        return conn;
    }

    /**
     * 关闭数据库连接
     * @param conn
     */
    public static void closeConnection(Connection conn){
        if (conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
                LOGGER.error("close connection failure",e);
            }
        }
    }
}

 使用Apache Common项目中的DbUtils类库,pom.xml中插入依赖

        <!-- Apache commons DbUtils -->
        <dependency>
            <groupId>commons-dbutils</groupId>
            <artifactId>commons-dbutils</artifactId>
            <version>1.6</version>
        </dependency>

然后在DBHelper类中增添以下方法。

    private static final QueryRunner QUERY_RUNNER = new QueryRunner();

    /**
     * 查询实体列表
     * @param entityClass
     * @param sql
     * @param params
     * @param <T>
     * @return
     */
    public static <T> List<T> queryEntityList(Class<T> entityClass,String sql,Object... params){
        List<T> entityList;
        Connection conn = getConnection();
        try {
            entityList = QUERY_RUNNER.query(conn,sql,new BeanListHandler<T>(entityClass),params);
        } catch (SQLException e) {
            //e.printStackTrace();
            LOGGER.error("query entity list failure",e);
            throw new RuntimeException(e);
        } finally {
            closeConnection(conn);
        }
        return entityList;
    }

    /**
     * 查询实体
     * @param entityClass
     * @param sql
     * @param params
     * @param <T>
     * @return
     */
    public static <T> T queryEntity(Class<T> entityClass,String sql,Object... params){
        T entity;
        Connection conn = getConnection();
        try {
            entity=QUERY_RUNNER.query(conn,sql,new BeanHandler<T>(entityClass),params);
        } catch (SQLException e) {
            //e.printStackTrace();
            LOGGER.error("query entity failure",e);
            throw new RuntimeException(e);
        } finally {
            closeConnection(conn);
        }
        return entity;
    }

    /**
     * 多表查询,其中的Map表示列明与列值的映射关系
     * @param sql
     * @param params
     * @return
     */
    public static List<Map<String,Object>> executeQuery(String sql,Object... params){
        List<Map<String,Object>> result;
        Connection conn = getConnection();
        try {
            result = QUERY_RUNNER.query(conn,sql,new MapListHandler(),params);
        } catch (SQLException e) {
            //e.printStackTrace();
            LOGGER.error("execute query failure",e);
            throw new RuntimeException(e);
        }
        return result;
    }

    /**
     * 执行更新语句(包括update,insert,delete)
     * @param sql
     * @param params
     * @return
     */
    public static int executeUpdate(String sql,Object... params){
        int rows =0;
        Connection conn = getConnection();
        try {
            rows = QUERY_RUNNER.update(conn,sql,params);
        } catch (SQLException e) {
            //e.printStackTrace();
            LOGGER.error("execute update failure",e);
            throw new RuntimeException(e);
        } finally {
            closeConnection(conn);
        }
        return rows;
    }

    /**
     * 插入实体(根据executeUpdate方法)
     * @param entityClass
     * @param fieldMap
     * @param <T>
     * @return
     */
    public static <T> boolean insertEntity(Class<T> entityClass,Map<String,Object> fieldMap){
        if (CollectionUtil.isEmpty(fieldMap)){
            LOGGER.error("can not insert entity: fieldMap is empty");
            return false;
        }

        String sql = "insert into "+getTableName(entityClass);
        StringBuilder columns = new StringBuilder("(");
        StringBuilder values = new StringBuilder("(");
        for (String fieldName:fieldMap.keySet()){
            columns.append(fieldName).append(", ");
            values.append("?, ");
        }
        columns.replace(columns.lastIndexOf(", "),columns.length(),")");
        values.replace(values.lastIndexOf(", "),values.length(),")");
        sql += columns+" VALUES" +values;
        Object[] params = fieldMap.values().toArray();
        return executeUpdate(sql,params)==1;
    }

    /**
     * 修改
     * @param entityClass
     * @param id
     * @param fieldMap
     * @param <T>
     * @return
     */
    public static <T> boolean updateEntity(Class<T> entityClass,long id,Map<String,Object> fieldMap){
        if (CollectionUtil.isEmpty(fieldMap)){
            LOGGER.error("can not update entity: fieldMap is empty");
            return false;
        }

        String sql = "update "+getTableName(entityClass) + " set ";
        StringBuilder columns = new StringBuilder();
        for (String fieldName:fieldMap.keySet()){
            columns.append(fieldName).append("=?, ");
        }
        sql+= columns.substring(0,columns.lastIndexOf(", "))+"where id=?";

        List<Object> paramList = new ArrayList<Object>();
        paramList.addAll(fieldMap.values());
        paramList.add(id);
        Object[] params = paramList.toArray();
        return executeUpdate(sql,params)==1;
    }

    /**
     * 删除
     * @param entityClass
     * @param id
     * @param <T>
     * @return
     */
    public static <T> boolean deleteEntity(Class<T> entityClass,long id){
        String sql = "delete from "+getTableName(entityClass)+" where id =?";
        return executeUpdate(sql,id)==1;
    }

    /**
     * 获取类名(不包含报名和后缀)
     * @param entityClass
     * @return
     */
    private static String getTableName(Class<?> entityClass){
        return entityClass.getSimpleName();
    }

 

架构探险笔记2

原文:https://www.cnblogs.com/aeolian/p/9457695.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!