我需要创建一个Book 金沙js娱乐场官方网站Type的Matter,均可以直接使用该框架结构进行开发学习

前面的书房初始化的前端信息已经完善,我去试试前端能不能初始化信息进DB,因为我把Book相关的信息拆分的比较多,我需要创建一个Book Type的Matter,或其他项目,均可以直接使用该框架结构进行开发学习,因为ORM最终生成的sql是需要转给db,我们需要先对db,如何把服务端的验证错误信息传递给前端视图呢,1、服务端的验证错误信息是可以收集起来的以json形式传递个视图的

金沙js娱乐场官方网站 6

 

继续,插入Binding信息(也需要判断name不存在才insert),返回BindingID;

主要:

  5.在执行sql语句时,需要创建游标,然后执行sql语句

前台视图为了显示错误信息等,需要控制器传来的json可能包含如下构成:

填写不动书房的信息:

继续,插入BookNbr信息;

下载查看该项目源码:

  通过对代码的简单分析,可以看到整个模块在初化时,载入数据库链接配置,对数据库的操作也只有简单读与写操作。这样的功能对于一般的数据库增删改查操作已经足够了,但如果业务复杂,有多个库、需要用到事务或者需要访问不同类型数据库时,它就不够用了。所以首先要做的就是对它进行重构,功能进行完善。

没有填写信息报错:

查看下DB有没有数据:

 

安全访问项目目录

class PgHelper(object):
    """postgresql数据库操作类"""

    def __init__(self, db, is_output_sql):
        self.connect = None
        self.cursor = None
        # 初始化数据库参数
        self.db_name = db.get('db_name')
        self.db_user = db.get('db_user')
        self.db_pass = db.get('db_pass')
        self.db_host = db.get('db_host')
        self.db_port = db.get('db_port')
        # 是否将所有要执行的Sql语句输出到日志里
        self.is_output_sql = is_output_sql

 

金沙js娱乐场官方网站 1

 1 CREATE PROCEDURE [base].[BookTag#Insert](@json nvarchar(max), @bookID bigint)
 2 WITH ENCRYPTION
 3 AS
 4 BEGIN
 5 ...
 6 
 7         -- insert Tag
 8         insert    base._Tag(Name)select value
 9         from    openjson(@json, '$.Tags') x
10         where    not exists(select 1 from base._Tag p where p.Name=x.value);
11 
12         insert    base._BookTag(BookID, TagID) select @bookID, x.ID
13         from    openjson(@json, '$.Tags') j join base.Tag#Raw() x on x.Name=j.value
14 
15 ...
16 END

小结:

主要实现了 引入路径优化, 类的自动加载, 封装优化入口文件,目录访问限制

MVC微型框架到此基本完成。其实还有很多还是可以继续扩展,如

  1, 类文件命名此处都用了 .class.php结尾,
实质可以优化直接使用.php结尾

  2, 引入命名空间,更方便的加载类

3, 项目中出现错误,此时是直接显示在浏览器上的,
可以写一个日志类,发生错误写入文件或数据库都可

  4, 数据库连接信息此处是直接写在DB类和BaseModel中了, 是不安全的。
可以创建一个配置目录,将这些信息写入配置文件,再写一个加载配置文件的类。

  5. 此架构目录 ,是在C,V中分平台,如Controller/Home,
Controller/Admin; 实际也可以写成 平台下分MVC结构, 如Admin/Controller,
Admin/Model, Home/Controller,Home/View ..
这个是比较灵活的,可以根据需求选择更加合适的方式

  实际上线项目,还是建议使用框架,安全快捷;
自己模仿定义的框架结构适合学习研究使用,容易遗漏,造成安全隐患,操作不便等问题

下一步:根据博客前端模板,分析创建数据表,
开始搭建博客后台程序,后续首先准备实现
“分类模块”。既分类的展示,修改,添加,删除功能

    def commit(self):
        """提交事务"""
        try:
            if self.connect:
                self.connect.commit()
                self.close_conn()
        except Exception as e:
            log_helper.error('提交事务失败:' + str(e.args))
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;

namespace DataAnnotationAjax.Controllers
{
    public class BaseController : Controller
    {
        /// <summary>
        /// 把部分视图转换成string
        /// </summary>
        /// <param name="viewName">部分视图名称</param>
        /// <param name="model">view model</param>
        /// <returns>部分视图字符串</returns>
        public string RenderPartialViewToString(string viewName, object model)
        {
            ViewData.Model = model;
            using (var sw = new StringWriter())
            {
                //根据部分视图名称+ControllerContext获得ViewEngineResult
                //ViewEngineResult中有View属性
                var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);

                //创建ViewContext对象实例
                var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);

                //把ViewEngineResult中的视图渲染到StringWriter实例中
                viewResult.View.Render(viewContext,sw);

                //获取视图string
                return sw.GetStringBuilder().ToString();
            }
        }

        /// <summary>
        /// 获取ModelState中的错误信息,以字典集合的形式返回
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, object> GetErrorFromModelState()
        {
            var errors = new Dictionary<string, object>();
            foreach (var key in ModelState.Keys)
            {
                if (ModelState[key].Errors.Count > 0)
                {
                    errors[key] = ModelState[key].Errors;
                }
            }
            return errors;
        }
    }
}

前面的书房初始化的前端信息已经完善,所以现在开始实现DB的Script部分。

 1 CREATE PROCEDURE [base].[BookAuthor#Insert](@json nvarchar(max), @bookID bigint)
 2 WITH ENCRYPTION
 3 AS
 4 BEGIN
 5 ...
 6 
 7         -- insert Author
 8         insert    base._Author(Name)select value
 9         from    openjson(@json, '$.Authors') x
10         where    not exists(select 1 from base._Author p where p.Name=x.value);
11 
12         insert    base._BookAuthor(BookID, AuthorID) select @bookID, x.ID
13         from    openjson(@json, '$.Authors') j join base.Author#Raw() x on x.Name=j.value
14 
15 ...
16 END
--------------文件结构:--------------------------------------blog
├─App
│ ├─Model 模型
│ │ └─UserModel.class.php 用户模型类 
│ ├─View 视图
│ │ ├─Back后台
│ │ │ └─Index
│ │ │ └─index.html 后台首页面
│ │ └─Home前台
│ │ └─User 用户视图目录
│ │ └─login.html 登录表单页面
│ ├─Controller 控制器
│ │ ├─Back后台
│ │ │ └─IndexController.class.php 后台首页控制器
│ │ └─Home前台
│ │ └─UserController.class.php 用户控制器
├─Public 静态公共文件(js,css,images)
│ ├─Plugins 插件
│ │ └─layui 前端框架插件
│ ├─Back后台
│ │ ├─js/ js文件
│ │ ├─css/ css样式文件
│ │ └─image img图片 
│ └─Home前台
│ ├─js/ js文件
│ ├─css/ css样式文件
│ └─image img图片 
├─Frame 公共使用的类
│ ├─BaseModel.class.php 数据库连接类
│ ├─BaseController.class.php 控制器公共操作(设置编码,信息跳转)
│ ├─FactoryModel.class.php 模型工厂类
│ ├─Init.class.php 初始化应用类
│ └─MySQLDB.class.php 数据库操作工具类
└─index.php 入口文件-----------------------------------------------------------------

 

填写分数不在定义区间报错:

金沙js娱乐场官方网站 2

Book_Init.sql


#!/usr/bin/env python
# coding=utf-8

import psycopg2
from common import log_helper
from config import const

# 初始化数据库参数
db_name = const.DB_NAME
db_host = const.DB_HOST
db_port = const.DB_PORT
db_user = const.DB_USER
db_pass = const.DB_PASS


def read(sql):
    """
    连接pg数据库并进行数据查询
    如果连接失败,会把错误写入日志中,并返回false,如果sql执行失败,也会把错误写入日志中,并返回false
    如果所有执行正常,则返回查询到的数据,这个数据是经过转换的,转成字典格式,方便模板调用,其中字典的key是数据表里的字段名
    """
    try:
        # 连接数据库
        conn = psycopg2.connect(database=db_name, user=db_user, password=db_pass, host=db_host, port=db_port)
        # 获取游标
        cursor = conn.cursor()
    except Exception as e:
        print(e.args)
        log_helper.error('连接数据库失败:' + str(e.args))
        return False
    try:
        # 执行查询操作
        cursor.execute(sql)
        # 将返回的结果转换成字典格式
        data = [dict((cursor.description[i][0], value) for i, value in enumerate(row)) for row in cursor.fetchall()]
    except Exception as e:
        print(e.args)
        log_helper.error('sql执行失败:' + str(e.args) + ' sql:' + str(sql))
        return False
    finally:
        # 关闭游标和数据库链接
        cursor.close()
        conn.close()
    # 返回结果(字典格式)
    return data


def write(sql, vars):
    """
    连接pg数据库并进行写的操作
    如果连接失败,会把错误写入日志中,并返回false,如果sql执行失败,也会把错误写入日志中,并返回false,如果所有执行正常,则返回true
    """
    try:
        # 连接数据库
        conn = psycopg2.connect(database=db_name, user=db_user, password=db_pass, host=db_host, port=db_port)
        # 获取游标
        cursor = conn.cursor()
    except Exception as e:
        print(e.args)
        log_helper.error('连接数据库失败:' + str(e.args))
        return False
    try:
        # 执行sql语句
        cursor.execute(sql, vars)
        # 提交事务
        conn.commit()
    except Exception as e:
        print(e.args)
        # 如果出错,则事务回滚
        conn.rollback()
        log_helper.error('sql执行失败:' + str(e.args) + ' sql:' + str(sql))
        return False
    else:
        # 获取数据
        try:
            data = [dict((cursor.description[i][0], value) for i, value in enumerate(row))
                         for row in cursor.fetchall()]
        except Exception as e:
            # 没有设置returning或执行修改或删除语句时,记录不存在
            data = None
    finally:
        # 关闭游标和数据库链接
        cursor.close()
        conn.close()

    # 如果写入数据后,将数据库返回的数据返回给调用者
    return data
  • key).html(value[value.length – 1].ErrorMessage)。

svc.sql

好了,开始测试。

  思路

  问题:
此时,项目中所有目录都是可以通过浏览器访问的,如直接访问Frame/Db.class.php文件
直接可以去查看数据库登录信息,显然是不安全的。

  解决方法:

    方式1:
在可以访问的文件开始处定义常量,访问是判断是否定义常量defined,
没有定义指定常量则直接exit(‘Access Deny’);

    方式2: 开启分布式权限配置,编写.htaccess文件, 如禁止访问,
将该文件放置在禁止访问的目录中

 

几个关键点:
1、显示错误信息的元素id的命名有讲究的:Err_Name,Name与Model中的属性一致。
2、遍历服务端传来的错误信息字典集合时,对每个属性,即key,拿的是最近一次错误:$(‘#Err_’

 1 CREATE PROCEDURE [svc].[Shelf$Init](@json nvarchar(max))
 2 WITH ENCRYPTION
 3 AS
 4 BEGIN
 5     SET    NOCOUNT    ON;
 6     SET XACT_ABORT ON;
 7     BEGIN TRY
 8         BEGIN    TRAN;
 9 
10         declare    @nickName nvarchar(20), @shelfName nvarchar(20);
11         select    @nickName=NickName,     @shelfName=ShelfName
12         from    openjson (@json, '$')
13         with (
14             NickName        nvarchar(20),
15             ShelfName        nvarchar(20)
16         );
17 
18         insert    core._Party(Type, Alias) select k._User, @nickName
19         from    core.Party#Type() k;
20         declare    @userID int=@@identity;
21 
22         
23         insert    core._Party(PID, Type, Alias) select @userID, k._Shelf, @shelfName
24         from    core.Party#Type() k;
25 
26         COMMIT    TRAN;
27     END TRY
28     BEGIN CATCH
29         if (xact_state() = -1) ROLLBACK TRAN; throw;
30     END CATCH
31 END
 1 CREATE PROCEDURE [svc].[Book$Init](@json nvarchar(max))
 2 WITH ENCRYPTION
 3 AS
 4 BEGIN
 5 ...
 6 
 7         declare    @stringID varchar(36), @userID int,  @shelfID int;
 8         select    @stringID=u.StringID,  @userID=u.ID, @shelfID=s.ID
 9         from    openjson (@json, '$') with (StringID varchar(36))
10         cross    apply core.User#For(StringID) u
11         join    core.Party#Raw() s on s.PID=u.ID;
12 
13         declare    @stateID int=(select BookCreated from core.Status#ID());
14 
15         -- init Matter
16         insert    core._Matter(Type, UserID, StateID)
17         select    k._Book, @userID, @stateID from core.Matter#Type() k;
18         declare    @matterID int=@@identity;
19 
20         -- init FileBank
21         insert    base._FileBank(Type, Url)
22         select    k._BookImage, ImageUrl
23         from    openjson(@json, '$') with (ImageUrl varchar(200))
24         cross    apply base.FileBank#Type() k;
25         declare    @imageID int=@@identity;
26         
27         -- insert Publisher
28         declare    @publisherID int;
29         exec    base.Publisher#Insert @json=@json, @id=@publisherID out;
30         
31         -- insert Binding
32         declare    @bindingID int;
33         exec    base.Binding#Insert @json=@json, @id=@bindingID out;
34 
35         -- insert Book
36         insert    base._Book(ID, Title, PublisherID, BindingID, ImageID)
37         select    @matterID, Title, @publisherID, @bindingID, @imageID
38         from    openjson(@json, '$') with (Title nvarchar(100));
39         
40         -- insert BookInfo
41         insert    base._BookInfo(ID, OriginTitle, PageCnt, Pubdate, SubTitle)
42         select    @matterID, OriginTitle, Pages, Pubdate, SubTitle
43         from    openjson(@json, '$')
44         with (
45             Pages       int, 
46             Pubdate     char(10), 
47             SubTitle    nvarchar(150), 
48             OriginTitle nvarchar(150)
49         );
50         
51         -- insert BookNbr
52         insert    base._BookNbr(ID, Type, Number)
53         select    @matterID, k._ISBN13, Isbn13
54         from    base.BookNbr#Type() k, openjson(@json, '$') with (Isbn13 char(13));
55         
56         insert    base._BookNbr(ID, Type, Number)
57         select    @matterID, k._ISBN10, Isbn10
58         from    base.BookNbr#Type() k, openjson(@json, '$') with (Isbn10 char(10));
59         
60         -- insert BookSupplement
61         insert    base._BookSupplement(ID, Type, Supplement)
62         select    @matterID, k._AuthorIntro, AuthorIntro
63         from    base.BookSupplement#Type() k, openjson(@json, '$') with (AuthorIntro nvarchar(max));
64         
65         insert    base._BookSupplement(ID, Type, Supplement)
66         select    @matterID, k._Summary, Summary
67         from    base.BookSupplement#Type() k, openjson(@json, '$') with (Summary nvarchar(max));
68         
69         insert    base._BookSupplement(ID, Type, Supplement)
70         select    @matterID, k._Catalog, Catalog
71         from    base.BookSupplement#Type() k, openjson(@json, '$') with (Catalog nvarchar(max));
72 
73         -- insert BookTag
74         exec    base.BookTag#Insert @json=@json, @bookID=@matterID;
75         
76         -- insert BookAuthor
77         exec    base.BookAuthor#Insert @json=@json, @bookID=@matterID;
78 
79         -- insert BookTranslator
80         exec    base.BookTranslator#Insert @json=@json, @bookID=@matterID;
81         
82         -- insert ShelfBook
83         insert    base._ShelfBook(BookID, ShelfID) values(@matterID, @shelfID);
84 
85 ...
86 END

  4.它需要支持查询、添加、修改、删除等操作,方便我们操作关系型数据库记录(需要创建sql执行方法)

  View model

 1     using M = Shelf;
 2     public class InitModel : PageModel
 3     {
 4         private readonly IShelfRepo _shelfRepo;
 5         public InitModel(IShelfRepo shelfRepo)
 6         {
 7             _shelfRepo = shelfRepo;
 8         }
 9         [BindProperty]
10         public InitInputModel Input { get; set; }
11 
12         public void OnGet()
13         {
14 
15         }
16 
17         public async Task<IActionResult> OnPostAsync()
18         {
19             if (ModelState.IsValid)
20             {
21                 await _shelfRepo.InitAsync(new M.InitSpec
22                 {
23                     NickName = Input.NickName.Trim(),
24                     ShelfName = Input.ShelfName.Trim()
25                 });
26                 return RedirectToPage("New");
27             }
28             return Page();
29         }
30     }

最后,关联新增的Book信息和Shelf,插入ShelfBook信息。

常量优化路径

准备: 创建分支

1 $ git checkout master2 $ git checkout -b "MVC"
 1 #!/usr/bin/evn python
 2 # coding=utf-8
 3 
 4 import unittest
 5 from common import db_helper
 6 from config import db_config
 7 
 8 class DbHelperTest(unittest.TestCase):
 9     """数据库操作包测试类"""
10 
11     def setUp(self):
12         """初始化测试环境"""
13         print('------ini------')
14 
15     def tearDown(self):
16         """清理测试环境"""
17         print('------clear------')
18 
19     def test(self):
20         # 使用with方法,初始化数据库连接
21         with db_helper.PgHelper(db_config.DB, db_config.IS_OUTPUT_SQL) as db:
22             # 设置sql执行语句
23             sql = """insert into product (name, code) values (%s, %s) returning id"""
24             # 设置提交参数
25             vars = ('张三', '201807251234568')
26             # 生成sql语句,并打印到控制台
27             print(db.get_sql(sql, vars))
28 
29             db.execute('select * from product where id=1000')
30             db.execute('insert into product (name, code) values (%s, %s) returning id', ('张三', '201807251234568'))
31             db.commit()
32 
33 if __name__ == '__main__':
34     unittest.main()

  HomeController

Shelf_Init.sql

 1 CREATE PROCEDURE [base].[Publisher#Insert](@json nvarchar(max), @id int out)
 2 WITH ENCRYPTION
 3 AS
 4 BEGIN
 5 ...
 6 
 7         declare    @name nvarchar(100);
 8         select    @name=Publisher from openjson(@json, '$') with (Publisher nvarchar(100))
 9 
10         -- insert Publisher
11         insert    base._Publisher(Name)select @name
12         where    not exists(select 1 from base._Publisher p where p.Name=@name);
13 
14         select    @id=ID from base.Publisher#Raw() where Name=@name;
15 ...
16 END

  代码实现

  1) 入口文件实现类的自动加载

 1 <?php 2 /** 3  * 入口文件 4  */ 5 $p = !empty($_GET['p']) ? $_GET['p'] : 'Home';  //平台 6 $c = !empty($_GET['c']) ? $_GET['c'] : 'User';  //控制器 7 $a = !empty($_GET['a']) ? $_GET['a'] : 'login'; //动作 8  9 define('PLAT', $p);  //平台常量10 define('CTR', $c);  //控制器11 define('ACTION', $a); //动作12 13 14 define('DS', DIRECTORY_SEPARATOR); //目录分割符15 define('ROOT', getcwd;  //当前所在目录 项目目录16 define('FRAME', ROOT.'Frame'.DS);17 define('APP', ROOT.'App'.DS);18 define('PUB', ROOT.'Public'.DS);19 define('ADMIN', PUB.'Admin'.DS);20 define('HOME', PUB.'Home'.DS);21 22 //MVC目录23 define('MODEL', APP.'Model'.DS);24 define('VIEW', APP.'View'.DS.PLAT.DS.CTR.DS);25 define('CTRONLLER', APP.'Controller'.DS.PLAT.DS);26 27 $ctr = $c."Controller";28 29 spl_autoload_register('autoload'); //注册自动加载函数30 //自动加载类31 /**32  * 实自动加载类文件33  * @param  string $className 类名34  */35 function autoload($className)36 {37     $upperClassName = strtoupper($className);38     $frame = array('BaseController','BaseModel','Db','FactoryModel');39     if(in_array($className, $frame)) {  //加载公共Frame目录中的类文件40         require_once FRAME."$className.class.php";41     } elseif(substr($upperClassName, -5) == 'MODEL'){  //加载模型Model目录中的类文件42         require_once MODEL."$className.class.php";43     } elseif(substr($upperClassName, -10) == 'CONTROLLER'){  //加载控制器目录中的类文件44         require_once CTRONLLER."$className.class.php";45     }46 }47 48 //实例化控制器49 $userCtr = new $ctr();50 $userCtr -> $a();

2) 提交代码

1 $  git add -A2 $  git commit -m "自动加载类完成"

  数据库最常见的操作就是增删改查操作,由于postgresql有个非常好用的特殊参数:returning,它可以在sql执行增改删结束后,返回我们想要的字段值,方便我们进行相应的判断与操作,所以增改删操作我们不需要将它与查询操作分离成两个方法,统一使用这个方法来获取数据库中返回的记录值。

1、服务端的验证错误信息是可以收集起来的以json形式传递个视图的。
2、服务端把错误信息存放在一个字典集合Dictionary<string,
object>,让key是属性名,value是错误信息。
3、前台视图中,显示错误信息的元素id,比方说是Err_Name,当遍历从服务端传来的字典集合时,取出key,然后把错误信息动态赋值给$(‘#Err_’

新增Action:Shelf_Init.sql

 

优化入口文件

    def __enter__(self):
        """初始化数据库链接"""
        self.open_conn()
        return self

    def __exit__(self, type, value, trace):
        """关闭postgresql数据库链接"""
        self.close_conn()
using System;

using System.ComponentModel.DataAnnotations;

 

namespace DataAnnotationAjax.Models

{

    public class Student

    {

        public int Id { get; set; }

 

        [Required(ErrorMessage = "姓名为必填项")]

        [Display(Name = "姓名")]

        public string Name { get; set; }

 

        [Required(ErrorMessage = "分数是必选项")]

        [Range(60, 100, ErrorMessage = "分数必须在60和100之间")]

        [Display(Name = "分数")]

        public int Score { get; set; }

 

        [Display(Name = "招收日期")]

        public DateTime Enrollment { get; set; }

    }

}

金沙js娱乐场官方网站 3

 

  1. 常量优化路径
  2. 自动加载类
  3. 优化入口文件
  4. 安全访问项目目录

  5.它需要支持sql执行优化,将超出指定执行时间的sql语句记录到日志中,方便开发人员进行分析(需要记录sql执行起始时间与结束时间,并进行计算,当这个时间大于指定值时执行日志写入程序)

using System.Web.Mvc;

using DataAnnotationAjax.Models;

using DataAnnotationAjax.Service;

 

namespace DataAnnotationAjax.Controllers

{

    public class HomeController : BaseController

    {

        public ActionResult Index()

        {

            return View(StudentRepository.GetStudents());

        }

 

        [HttpPost]

        public ActionResult AddStudent()

        {

            var student = new Student();

            var valid = TryUpdateModel(student);

            string studentPartialViewHtml = string.Empty;

            if (valid)

            {

                StudentRepository.AddStudent(student);

                var students = StudentRepository.GetStudents();

                studentPartialViewHtml = RenderPartialViewToString("Students", students);

            }

            return Json(new {Valid = valid, Errors = GetErrorFromModelState(), StudentsPartial = studentPartialViewHtml});

        }

    }

}

 

哈哈,看来一切正常。

查询DB,看看有没有数据进DB:

  思路

  问题: 入口文件中已经require_once
引入6个类,既增加一个需要引入一个,容易遗漏,重复和出错。

  解决方法:自动加载类文件

     方式1: 使用自动加载类函数__autoload()可以实现自动加载
  方式2: 实际项目中,多人开发,根据实用性,更多的是使用
sql_autoload_register()注册函数自动加载

  根据目录的特点实现自动加载
  Model类文件特点,以Model结尾的类名 substr($className,-5)
  Controller文件特点: 以Controller结尾的类名, substr($class,-10)

    公共类:
类名没有统一形式,可以将Fame下的公共类放入到数组中,然后判断类是否在数组中,
从而自动加载该目录下的类文件

金沙js娱乐场官方网站 4金沙js娱乐场官方网站 5

1、显示一个异步提交的视图Index.cshtml
2、完成了验证通过情况下的数据添加。
3、不管是否验证通过,都要返回json字符串。

 点击Save按钮提交,OK,正常提交了并跳转了。

继续,插入BookTag信息;

  代码实现

  1) 在Frame目录中创建Init.class.php文件,
将入口文件index中的代码复制进行修改为类

  【Frame/Init.class.php】

 1 <?php 2 /** 3  * 应用初始化操作类 4  * User: young 5  */ 6  7 class Init 8 { 9     protected static $frame = array('BaseController','BaseModel','Db','FactoryModel'); //Frame目录公共操作类10     public static function run()11     {12         //平台13         self::dispatch();14 15         //定义常量16         self::setConst();17 18         //自动加载类19         self::loadClass();20 21         $ctr = CTR."Controller";  //拼接控制器名称22 23         //实例化控制器24         $ctrObj = new $ctr();25         $a = ACTION;26         $ctrObj -> $a();27     }28     /**29      * 设置自动加载类方法30      */31     private static function loadClass()32     {33         spl_autoload_register('self::autoload');34     }35 36     /**37      * 实现自动加载38      * @param  string $className 类名39      */40     private static function autoload($className)41     {42         $upperClassName = strtoupper($className);43         if(in_array($className, static::$frame)) {44             require_once FRAME."$className.class.php";45         } elseif(substr($upperClassName, -5) == 'MODEL'){46             require_once MODEL."$className.class.php";47         } elseif(substr($upperClassName, -10) == 'CONTROLLER'){48             require_once CTRONLLER."$className.class.php";49         }50     }51 52     /**53      * 定义常量54      */55     private static function setConst()56     {57         define('DS', DIRECTORY_SEPARATOR); //目录分割符58         define('ROOT', getcwd().DS);59         define('FRAME', ROOT.'Frame'.DS);60         define('APP', ROOT.'App'.DS);61         define('PUB', ROOT.'Public'.DS);62         define('ADMIN', PUB.'Admin'.DS);63         define('HOME', PUB.'Home'.DS);64 65 66         define('MODEL', APP.'Model'.DS);67         define('VIEW', APP.'View'.DS.PLAT.DS.CTR.DS);68         define('CTRONLLER', APP.'Controller'.DS.PLAT.DS);69     }70 71     /**72      * 获取 p c a 的GET值,并设置为常量73      * @return void74      */75     private static function dispatch()76     {77         $p = !empty($_GET['p']) ? $_GET['p'] : 'Home';  //平台78         $c = !empty($_GET['c']) ? $_GET['c'] : 'User';  //控制器79         $a = !empty($_GET['a']) ? $_GET['a'] : 'login'; //动作80 81         define('PLAT', $p);82         define('CTR', $c);83         define('ACTION', $a);84     }85 }

2) 入口文件引入初始化类,并调用其方法 【index.php】

1 <?php2 /**3  * 入口文件4  */5 6 require_once './Frame/Init.class.php';7 Init::run();

3) 提交代码

1 $  git add -A2 $  git commit -m "优化入口文件,封装初始化类"

  完成的db_helper.py代码

金沙js娱乐场官方网站 6

….

然后,将图片路径保存到FileBank中,并返回FileBankID;

  思路

  1)把常用的目录路径定义成常量。如 模型目录,控制器目录等
 2)引入类使用定义的常量替代部分路径。 如 include
FRAME.BaseModel.class.php
3) 载入视图使用常量替代部分路径 如 include VIEW.’login.html’ 简单形式

    def open_conn(self):
        """连接数据库,并建立游标"""
        try:
            if not self.connect:
                self.connect = psycopg2.connect(database=self.db_name, user=self.db_user, password=self.db_pass, host=self.db_host, port=self.db_port)
            return self.connect
        except Exception as e:
            log_helper.error('连接数据库失败:' + str(e.args))
            return False

    def close_conn(self):
        """关闭postgresql数据库链接"""
        # 关闭游标
        try:
            if self.cursor:
                self.cursor.close()
        except Exception:
            pass
        # 关闭数据库链接
        try:
            if self.connect:
                self.connect.close()
        except Exception:
            pass
using System;

using System.Collections.Generic;

using DataAnnotationAjax.Models;

 

namespace DataAnnotationAjax.Service

{

    public static class StudentRepository

    {

        private static int _idSeed = 1;

        private static readonly List<Student>  _students = new List<Student>();

 

        static StudentRepository()

        {

            Random rand = new Random();

            for (int i = 0; i < 3; i++)

            {

                var student = new Student();

                int id = _idSeed++;

                student.Id = id;

                student.Name = "姓名" + id.ToString();

                student.Score = (60 + Convert.ToInt16(rand.NextDouble()*40));

                student.Enrollment = DateTime.Now;

                _students.Add(student);

            }

        }

 

        public static void AddStudent(Student stu)

        {

            stu.Id = _idSeed++;

            stu.Enrollment = DateTime.Now;

            _students.Add(stu);

        }

 

        public static List<Student> GetStudents()

        {

            return _students;

        }

    }

}