精华内容
下载资源
问答
  • 一个简单的MVC模式范例

    千次阅读 2018-04-01 19:28:08
    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制...

    MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

    Model(模型)表示应用程序核心(比如数据库记录列表)。是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。

    View(视图)显示数据(数据库记录)。是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。

    Controller(控制器)处理输入(写入数据库记录)。是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

    MVC是一个框架模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型、视图、控制器。它们各自处理自己的任务。最典型的MVC就是JSP +servlet+javabean的模式。

    下面做一个简单的示范,我们以添加一个学生的信息为例(某些顺序可以按照自己习惯进行调整):

    1.在数据库中创建一个学生表

    if exists (select * from sysdatabases where name='Test') drop database Test
    --建数据库
    go
    create database Test
    go
    use Test
    
    
    if exists (select * from  sysobjects where  name='students') drop table students
    create table students
    (
    	stuId int not null primary key identity(1,1),
    	stuName varchar(50) not null,
    	stuAge  int not null
    )
    

    2.在myeclips里添加一个javabean类

    public class Student {
    	private int stuId;//编号
    	private String stuName;//姓名
    	private int stuAge;//年龄
    	public int getStuId() {
    		return stuId;
    	}
    	public void setStuId(int stuId) {
    		this.stuId = stuId;
    	}
    	public String getStuName() {
    		return stuName;
    	}
    	public void setStuName(String stuName) {
    		this.stuName = stuName;
    	}
    	public int getStuAge() {
    		return stuAge;
    	}
    	public void setStuAge(int stuAge) {
    		this.stuAge = stuAge;
    	}
    	
    	
    }
    

    3.连接数据库和操作方法(有一个增删改的方法和查询的方法)

    注意!不要忘记sqljdbc.jar,否则为无法连接数据库

    public class Basedao {
    
    		private static final String DRIVER="com.microsoft.sqlserver.jdbc.SQLServerDriver";
    		private static final String URL="jdbc:sqlserver://localhost:1433;DatabaseName=Test";
    		private static final String USERNAME="sa";
    		private static final String PASSWORD="sa";
    		private Connection conn;//连接对象
    		protected PreparedStatement pst;//预编译的preparedstatement对象
    		protected ResultSet rs;结果集resultset对象 
    		
    		//获取数据库的连接
    		public void getConnection(){
    			try {
    				Class.forName(DRIVER);
    				conn=DriverManager.getConnection(URL,USERNAME,PASSWORD);
    			} catch (ClassNotFoundException e) {
    				e.printStackTrace();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    		
    		//释放资源
    		public void closeConnection(){
    			//释放结果集
    			if(rs!=null){
    			try {
    				rs.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    			}
    			释放预编译的对象
    			if(pst!=null){
    			try {
    				pst.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    			}
    			//释放连接
    			if(conn!=null){
    			try {
    				conn.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    			}
    		
    		}
    
    		//增删改
    		public int executeUpdate(String sql,String []paras){
    			int count=0;
    			try {
    				this.getConnection();//连接数据库
    				pst=conn.prepareStatement(sql);//基于sql语句创建预编译对象
    				//如果paras不为空或者长度大于0 就赋值
    				if(paras!=null && paras.length>0){
    					for (int i = 0; i < paras.length; i++) {
    						pst.setString(i+1, paras[i]);
    					}
    				}
    				count=pst.executeUpdate();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}finally{
    				closeConnection();
    			}
    			return count;
    		}
    		
    		
    		//查询
    		public ResultSet executeQuery(String sql,String[]paras){
    			try {
    				this.getConnection();//连接数据库
    				pst=conn.prepareStatement(sql);//基于sql语句创建预编译对象
    				//如果paras不为空或者长度大于0 就赋值
    				if(paras!=null && paras.length>0){
    					int index=1;
    					for (String para : paras) {
    						pst.setString(index,para);
    						index++;
    					}
    				}
    				rs=pst.executeQuery();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    			return rs;
    		}
    }
    4.编写具体的添加方法
    public int stuAdd(Student stu) {
    		int count=0;
    		String sql="insert into student values (?,?)";
    		String [] paras={stu.getStuName(),String.valueOf(stu.getStuAge())};
    		count=super.executeUpdate(sql, paras);
    		return count;
    	}

    5.编写jsp页面,包含非空验证,验证成功后跳入sevlet类,用jQuery注意导入jquery-1.7.1.min.js


    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
    <%
    String path = request.getContextPath();
    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
    %>
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    <html>
      <head>
        <base href="<%=basePath%>">
        <script type="text/javascript" src="<%=path %>/jquery/jquery-1.7.1.min.js"></script>
        <script type="text/javascript">
        function onSubmit(){
    		var name=$("#stuName").val();
    		if(name==""){
               alert("姓名不能为空");
               return false;  // 返回false,不跳转
            }else{
               return true;   // 返回true,跳转
            }
    		
    	}
        </script>
        <title>添加</title>
      </head>
      
      <body>
        <form action="ServletAddStu" method="post">
        	<p>姓名:<input type="text" name="stuName" id="stuName"/></p>
        	<p>年龄:
        		<select name="stuAge">
        		<option value="18">18</option>
        		<option value="19">19</option>
        		<option value="20">20</option>
        		<option value="21">21</option>
        		<option value="22">22</option>
        		</select>
        	</p>
        	<p><input type="submit" value="提交" onClick="return onSubmit()"></p>
        </form>
      </body>
    </html>

    6.编写servlet类

    public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		this.doPost(request, response);
    	}
    public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		PrintWriter out = response.getWriter();
    		//设置编码格式
    		request.setCharacterEncoding("utf-8");
    		response.setCharacterEncoding("utf-8");
    		//得到姓名和年龄.封装到student类中
    		String name=request.getParameter("stuName");
    		int age=Integer.valueOf(request.getParameter("stuAge"));
    		Student student=new Student();
    		student.setStuName(name);
    		student.setStuAge(age);
    		//调用调价方法
    		StudentDao stuDao=new StudentDao();
    		stuDao.stuAdd(student);
    	}

    7.在数据库中查看一下是否添加成功
    展开全文
  • 他们的工作原理大家应该也比较感兴趣,下面我说说一个mvc框架长什么样。 路由机制 在互联网我们都是通过url...一个简单的controller 复制代码 代码如下://定义一个controllerclass UserControler extends Controller{ 
  • 他们工作原理大家应该也比较感兴趣,下面我说说一个mvc框架长什么样。路由机制在互联网我们都是通过url提供服务,因此不同url有不同服务。用户访问不同页面也就获得了不同服务。那么我们服务是如何通过...

    他们的工作原理大家应该也比较感兴趣,下面我说说一个mvc框架长什么样。

    路由机制

    在互联网我们都是通过url提供服务,因此不同的url有不同的服务。用户访问不同的页面也就获得了不同的服务。那么我们的服务是如何通过url来区分不同的服务呢。

    我们的web程序就要通过url寻找到不同的文件,进行不同的业务逻辑处理。我们的路由机制就是根据url,寻找到对应的controller,和action,然后由action进行具体的业务逻辑处理。

    一个简单的controller

    //定义一个controller

    class UserControler extends Controller{

    //定义一个action方法,注意一定是public的

    public function index(){

    // do business code

    }

    }

    具体的对应规则不同的框架映射不同。以下是CodeIgniter框架的URL路由,它会尽力的尝试各种的可能,来分析URL的情况。

    文件路径/system/core/URI.php

    // 看看是否是从命令行运行的

    if (php_sapi_name() == 'cli' or defined('STDIN')){

    $this->_set_uri_string($this->_parse_cli_args());

    return;

    }

    // 首先尝试 REQUEST_URI 这个适应大部分的情况

    if ($uri = $this->_detect_uri()){

    $this->_set_uri_string($uri);

    return;

    }

    // 看看PATH_INFO变量是否存在?nginx需要配置

    // Note: some servers seem to have trouble with getenv() so we'll test it two ways

    $path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');

    if (trim($path, '/') != '' && $path != "/".SELF){

    $this->_set_uri_string($path);

    return;

    }

    // 没有PATH_INFO,看看 QUERY_STRING?

    $path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');

    if (trim($path, '/') != ''){

    $this->_set_uri_string($path);

    return;

    }

    //尝试去从 $_GET 获取信息

    if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != ''){

    $this->_set_uri_string(key($_GET));

    return;

    }

    // 尽力了,放弃了路由

    $this->uri_string = '';

    return;

    通过上面的尝试,接下来就是如何利用路由机制加载正确的controller了。

    Controller加载机制

    我们来看看Codeigniter框架是如何加载到controller并且调用action的。

    在/system/core/Codeigniter.php中有如下的代码。Codeigniter在这之前会根据$_SERVER['PATH_INFO]里面的值来进行赋值(这个都是靠自己的设定的,默认的话CI他会有许多的if分支进行判断)。

    //大约在250行

    include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');

    $class  = $RTR->fetch_class();

    $method = $RTR->fetch_method();

    //大约在308行

    $CI = new $class();

    //大约在359行

    call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));

    就这样,通过这个就调用到了我们的controller及其方法了,接下来就是编写自己的业务逻辑代码了。

    视图view的显示

    当我们的业务逻辑代码写完后,就需要页面的展示了。很多常见的MVC框架在页面的调用是这么写的。

    //controller中action的方法

    public function index(){

    // ... 许多的业务逻辑代码

    $data = array('name'=>'abc', 'age'=>12, .... );

    return $this->render('view/path/file.html',$data);

    }

    接着在视图文件view/path/file.html里写上一下代码。

    姓名 : =$name ?>

    年龄 : <?php echo $age; ?>

    这段如何将数据渲染到视图中,这段代码以前我一直很好奇,现在我明白了,我们来看看是如何实现的。

    protected function render($template, array $var = array() )

    {

    extract($var);   // 抽取数组中的变量

    ob_end_clean (); //关闭顶层的输出缓冲区内容

    ob_start ();     // 开始一个新的缓冲区

    require TEMPLATE_ROOT . $template . '.html';  //加载视图view

    $content = ob_get_contents ();             // 获得缓冲区的内容

    ob_end_clean ();           // 关闭缓冲区

    //ob_end_flush();      // 这个是直接输出缓冲区的内容了,不用再次缓存起来。

    ob_start();            //开始新的缓冲区,给后面的程序用

    return $content;       // 返回文本,此处也可以字节echo出来,并结束代码。

    }

    在这短短的几行代码中,全都是精华,就是这些非常重要的,全是php的内置函数,接下来我们来具体分析分析。

    看看第一个extract($var)。这个函数从数组中将变量导入到当前的符号表。刚刚就将$data数组里面的name、age抽取出来,这样就可以在视图view中使用$name $age。更详细的请参考http://www.php.net/manual/zh/function.extract.php

    第二个ob_end_clean()的作用是关闭顶层的缓冲区,为了是之前的程序不小心echo出的一些文字给清楚了,为了下一行的重新开辟一块缓冲区。

    第三个ob_start()是开启一块新的缓冲区,为了是将视图的内容放到缓冲区。当然了,缓冲区有一定的大小,如果内容超出了缓冲区的设定值,那么会自动的发送给server。

    第四个require file,这个就是第一个参数,根据自己的规则去加载视图的文件。其中文件里可以夹杂php、html的代码。你在这个render()函数声明的任何局部变量或者这里能访问到的任何全局变量,都可以在require的file文件中访问到。

    第五个$content = ob_get_contents ()很重要,是为了将缓冲区的内容取出来,但不清除它。

    第七个ob_start()是重新开启一个缓冲区,为了是下面的程序需要使用缓冲区。有写框架可能不用对$content的内容进行操作了,那么直接ob_end_flush()将缓冲区的内容输出出来就行了。

    这个是一个很简单的展示视图的过程。如果直接使用这个不方便对视图view进行模块化,因此一些框架都不会这么直接用的。

    我们从这个函数也可以看到程序有点类似程序中断保护现场的感觉。只不过中断保护现场会先保存数据,然后在返回的时候恢复回来。这里只有关闭上一个缓冲区,开启一个新的缓冲区,关闭这个缓冲哦过去,开启另外一个缓冲区。

    至此,我们看到一个简单的PHP的MVC框架。如果你有兴趣可以自己开发一个MVC框架,或者更深入点的HMVC。

    展开全文
  • 3】存取款数额通过编辑框进行输入 程序处理流程: 第一步】构造model实例,用于存放和处理数据 第二步】构造view实例,在构造实例过程中使用makeController函数为界面创建一个对应控制器,并将第一步构造...

    程序完成功能:

    1】显示存款余额

    2】具有存取款的功能,并更新显示存取款后的余额

    3】存取款的数额通过编辑框进行输入

    程序的处理流程:

    第一步】构造model实例,用于存放和处理数据

    第二步】构造view实例,在构造实例的过程中使用makeController函数为界面创建一个对应的控制器,并将第一步构造的model实例句柄传入赋给obj.modelObj,并给这个model类的事件消息添加一个监听器,这个监听器监听到model实例中的事件信息(balanceChanged)后会调用View类的updateBalance()函数进行相应。

            function obj = View(modelObj)
                obj.viewSize = [100,100,300,200];
                obj.modelObj = modelObj;
                obj.modelObj.addlistener('balanceChanged',@obj.updateBalance);
                obj.buildUI();
                obj.controlObj = obj.makeController();
                obj.attachToController(obj.controlObj);
            end
           
    
            function controlObj = makeController(obj)
                controlObj = Controller(obj,obj.modelObj);
            end

    第三步】用View类的buildUI函数绘制主界面

    function buildUI(obj)
                obj.hfig = figure('pos',obj.viewSize);
                
                obj.drawButton = uicontrol('parent',obj.hfig,'string','withdraw','pos',[60,28,60,28]);
                obj.depositButton = uicontrol('parent',obj.hfig,'string','deposit','pos',[180,28,60,28]);
                
                obj.numBox = uicontrol('parent',obj.hfig,'style','edit','pos',[60,85,180,28],...
                    'tag','numBox');
                obj.balanceBox = uicontrol('parent',obj.hfig,'style','edit','pos',[180,142,60,28],...
                    'tag','balancebox');
                obj.text = uicontrol('parent',obj.hfig,'style','text','string','balance','pos',[60,142,60,28]);
                
                obj.updateBalance();
            end

     第四步】为主界面的按键添加控制器回调函数

            function attachToController(obj,controller)
                funcH = @controller.callback_drawbutton;
                set(obj.drawButton,'callback',funcH);
                funcH = @controller.callback_depositbutton;
                set(obj.depositButton,'callback',funcH);
            end

    第五步】按键后,对应的controller类回调函数被调用,并按照回调函数获取输入数据并对数据进行处理

            function callback_drawbutton(obj,src,event)
                obj.modelObj.withdraw(obj.viewObj.input);
            end
            function callback_depositbutton(obj,src,event)
                obj.modelObj.deposit(obj.viewObj.input);
            end

    其中回调函数调用了View类的dependent properties:obj.viewObj.input,这个变量是一个具有函数性质的变量,其具体的值取决于他的实现:实现中通过get方法获取变量input的值(get.input);这个变量input的值来源于传入的参数obj,通过获取obj.nuBox中的值赋值给get.input的返回参数input,实现变量input的确定。这里面返回参数input和成员变量input不是一回事儿,返回参数input只是个形式,在获取input的值的时候,调用的是成员变量input,也就说填入viewObj.input就相当于调用了函数get.input(),进而就获取了返回参数input的值,这个值就被赋给了viewObj.input,然后viewObj.input再作为model类obj.modelObj.withdraw函数的传入参数传了进去,进行下一步的处理。这样一圈就完成了从输入框中获取输入值的功能。

        properties(Dependent)
            input;
        end
    
            function input = get.input(obj)
                input = get(obj.numBox,'string');
                input = str2double(input);
            end
        

    第六步】 Model类中的数据处理函数响应 按键的回调函数,对数据进行处理,并触发model类的事件通知

        events
            balanceChanged
        end
    
    
            function deposit(obj,val)
                obj.balance = obj.balance + val;
                obj.notify('balanceChanged');
            end
            
            function withdraw(obj,val)
                obj.balance = obj.balance - val;
                obj.notify('balanceChanged');
            end

     第七步】因为第二步的时候再view类中给model类添加了一个事件监听器,现在发生了事件消息后,监听相应程序会根据事件做出下一步显示信息的更新,完成对事件信息的响应。

            function updateBalance(obj,scr,data)
                set(obj.balanceBox,'string',num2str(obj.modelObj.balance));
            end

     经过以上这样一套循环机制,就完成了按键的整个响应过程。

     

    以下是程序的完整代码:

    主程序

    clc
    clear 
    close all
    
    modelObj = Model(500);
    viewObj = View(modelObj);

    M(model)类

    classdef Model < handle
        properties
            balance
        end
        
        events
            balanceChanged
        end
        
        methods
            function obj = Model(balance)
                obj.balance = balance;
            end
            
            function deposit(obj,val)
                obj.balance = obj.balance + val;
                obj.notify('balanceChanged');
            end
            
            function withdraw(obj,val)
                obj.balance = obj.balance - val;
                obj.notify('balanceChanged');
            end
        end
    end

    V(view)类

    classdef View < handle
        properties
            viewSize;
            hfig;
            drawButton;
            depositButton;
            balanceBox;
            numBox;
            text;
            modelObj;
            controlObj;
        end
        properties(Dependent)
            input;
        end
        methods
            function obj = View(modelObj)
                obj.viewSize = [100,100,300,200];
                obj.modelObj = modelObj;
                obj.modelObj.addlistener('balanceChanged',@obj.updateBalance);
                obj.buildUI();
                obj.controlObj = obj.makeController();
                obj.attachToController(obj.controlObj);
            end
            function input = get.input(obj)
                input = get(obj.numBox,'string');
                input = str2double(input);
            end
            
            function buildUI(obj)
                obj.hfig = figure('pos',obj.viewSize);
                
                obj.drawButton = uicontrol('parent',obj.hfig,'string','withdraw','pos',[60,28,60,28]);
                obj.depositButton = uicontrol('parent',obj.hfig,'string','deposit','pos',[180,28,60,28]);
                
                obj.numBox = uicontrol('parent',obj.hfig,'style','edit','pos',[60,85,180,28],...
                    'tag','numBox');
                obj.balanceBox = uicontrol('parent',obj.hfig,'style','edit','pos',[180,142,60,28],...
                    'tag','balancebox');
                obj.text = uicontrol('parent',obj.hfig,'style','text','string','balance','pos',[60,142,60,28]);
                
                obj.updateBalance();
            end
            
            function updateBalance(obj,scr,data)
                set(obj.balanceBox,'string',num2str(obj.modelObj.balance));
            end
            
            function controlObj = makeController(obj)
                controlObj = Controller(obj,obj.modelObj);
            end
            
            function attachToController(obj,controller)
                funcH = @controller.callback_drawbutton;
                set(obj.drawButton,'callback',funcH);
                funcH = @controller.callback_depositbutton;
                set(obj.depositButton,'callback',funcH);
            end
        end
    end

    C(controller)类

    classdef Controller < handle
        properties
            viewObj;
            modelObj;
        end
        methods
            function obj = Controller(viewObj,modelObj)
                obj.viewObj = viewObj;
                obj.modelObj = modelObj;
            end
            
            function callback_drawbutton(obj,src,event)
                obj.modelObj.withdraw(obj.viewObj.input);
            end
            function callback_depositbutton(obj,src,event)
                obj.modelObj.deposit(obj.viewObj.input);
            end
        end
    end

     

    Context 类

    classdef Context < handle
        properties
            dataDictionary;
        end
        
        methods(Static)
            function obj = getInstance()
                persistent localObj;
                if(isempty(localObj)) || ~isvalid(localObj)
                    localObj = Context();
                end
                obj = localObj;
            end
        end
        methods (Access = private)
            function obj = Context()
                obj.dataDictionary = containers.Map();
            end
        end
        methods
            
            function register(obj,ID,data) %#ok<INUSD>
                expr = sprintf('obj.dataDictionary(\''%s\'') = data',ID);
                eval(expr);
            end
            
            function data = getData(obj,ID)
                if isKey(obj.dataDictionary,ID)
                    data = obj.dataDictionary(ID);
                else
                    error('ID NOT EXIST');
                end
            end
        end
    end

    Context 类的使用

    clc
    clear 
    close all
    
    obj1 = Model('ca');
    obj2 = Model('po');
    
    contextObj = Context.getInstance();
    contextObj.register('Camera',obj1);
    contextObj.register('PowerSource',obj2);
    
    disp(keys(contextObj.dataDictionary));
    disp(values(contextObj.dataDictionary));
    
    hCa = contextObj.getData('Camera')

    复合布局

    clc
    clear
    close all
    
    f = figure('Menubar','none','Toolbar','none','pos',[200,200,500,500]);
    % plot(1:9,[1,2,5,3,6,4,7,8,9])
    mainLayout = uiextras.HBox('Parent',f,'Spacing',10);
        leftLayout = uiextras.VBox('Parent',mainLayout,'spacing',10,'Padding',5);
            lUpperLayout = uiextras.VBox('Parent',leftLayout);
            lLowerLayout = uiextras.VBox('Parent',leftLayout);
        
        rightLayout = uiextras.VBox('Parent',mainLayout,'spacing',10);
        
    box = uicontrol('parent',lUpperLayout,'string','leftUpperButton');
    box2 = axes('parent',lLowerLayout);
    box3 = axes('parent',rightLayout);
    plot(box3,1:9,[1,2,5,3,6,4,7,8,9])
    plot(box2,1:9,[1,2,5,3,6,4,7,8,9])

     

    展开全文
  • ASP.NET的mvc模式页面精美的简单模板,可以作为一个练手网站,数据库操作包含基本的增删改查,可以作为一个范例
  • Entity Framework(通常被简称为“EF”)支持一个被称之为“code-first”的开发范例。Code-first允许你通过书写一些简单的类来创建模型对象。你可以通过访问这些类的方式来访问数据库,这是一种非常方便快捷的开发...

    在本节中我们将追加一些类来管理数据库中的电影。这些类将成为我们的MVC应用程序中的“模型”部分。

        我们将使用一个.NET Framework的被称之为“Entity Framework”的数据访问技术来定义这些模型类,并使用这些类来进行操作。Entity Framework(通常被简称为“EF”)支持一个被称之为“code-first”的开发范例。Code-first允许你通过书写一些简单的类来创建模型对象。你可以通过访问这些类的方式来访问数据库,这是一种非常方便快捷的开发模式。

    4.1  利用NuGet来安装EFCodeFirst

        我们可以利用NuGet包管理器(安装ASP.NET MVC3时会自动安装)来把EFCodeFirst类库添加到我们的MvcMovie工程中。这个类库使得我们可以直接使用code-first。点击“工具”菜单下的“Library Package Manager”子菜单下的“Add Library Package Reference”菜单选项,如图4-1所示。

    ASP.NET <wbr>MVC3 <wbr>快速入门-第四节 <wbr>添加一个模型

    图4-1 使用NuGet包管理器

        点击“Add Library Package Reference”菜单选项后,将会弹出一个对话框,标题为“Add Library Package Reference”,如图4-2所示。

    ASP.NET <wbr>MVC3 <wbr>快速入门-第四节 <wbr>添加一个模型

    4-2Add Library Package Reference”对话框

        默认状态下,左边的“All”选项处于选择状态。因为还没有安装任何包,所以右边面板中显示“找不到任何项”。点击左边面板中的“online”选项,NuGet包管理器将会在服务器上检索所有当前能够获取的包,如图4-3所示。

    ASP.NET <wbr>MVC3 <wbr>快速入门-第四节 <wbr>添加一个模型

    图4-3 NuGet包管理器正在检索包信息

        服务器上有几百个当前能够获取的包,现在我们只关注EFCodeFirst包。在右上角的搜索输入框中输入“EFCode”。在检索结果中,选择EFCodeFirst包,并且点击Install按钮安装包,如图4-4所示。

    ASP.NET <wbr>MVC3 <wbr>快速入门-第四节 <wbr>添加一个模型

    图4-4 选择EFCodeFirst包并安装

        点击了install按钮后,会弹出一个接受许可证窗口,如图4-5所示,在这个窗口中必须要点击“I Accept”按钮,接受许可证条款,安装才能继续进行。

    ASP.NET <wbr>MVC3 <wbr>快速入门-第四节 <wbr>添加一个模型

    图4-5 接受许可证窗口

        安装完毕后,点击close按钮。我们的MvcMovie工程中会自动加载EntityFramework程序集,其中包含了EFCodeFirst类库。

    ASP.NET <wbr>MVC3 <wbr>快速入门-第四节 <wbr>添加一个模型

    4-6 安装完毕后EntityFramework程序集被自动加载

    4.2  添加模型类

        在解决方案资源管理器中,鼠标右击Models文件夹,点击“添加”菜单下的“类”,如图4-7所示。

    ASP.NET <wbr>MVC3 <wbr>快速入门-第四节 <wbr>添加一个模型

    图4-7 添加模型类

        点击“类”菜单项后,会弹出“添加新项”对话框,在该对话框中将类名命名为“Movie”,如图4-8所示。

    ASP.NET <wbr>MVC3 <wbr>快速入门-第四节 <wbr>添加一个模型

    图4-8 在“添加新项”对话框中为类命名

        然后点击添加按钮,观察解决方案资源管理器中,Models文件夹下添加了一个Movie.cs类定义文件,并且该文件呈打开状态,如图4-9所示。

    ASP.NET <wbr>MVC3 <wbr>快速入门-第四节 <wbr>添加一个模型

    图4-9 Movie.cs类定义文件已被添加并呈打开状态

        在Movie.cs文件中追加如下所示的五个属性。

    public class Movie

    {

        public int ID { get; set; }

            public string Title { get; set; }

            public DateTime ReleaseDate { get; set; }

            public string Genre { get; set; }

            public decimal Price { get; set; }

    }

        我们将利用Movie类来代表数据库中的movie(电影)。每一个Movie对象的实例对应于数据表中的一行,Movie类中的每一个属性被映射到数据表的每一列。

        在同一个Movie.cs文件中,追加如下所示的MovieDBContext类。

    public class MovieDBContext : DbContext 

    {

        public DbSet<Movie> Movies { get; set; } 

    }

        MovieDBContext类代表了Entity Framework中的movie数据库的上下文对象,用来处理数据的存取与更新。MovieDBContext对象继承了Entity Framework中的DbContext基础类。为了能够引用DbContext类,你需要在Movie.cs文件的头部追加如下所示的using语句。

    using System.Data.Entity;

        完整的Movie.cs文件中的代码如代码清单4-1所示。

        代码清单4-1 完整的Movie.cs文件

    using System;

    using System.Data.Entity;

    namespace MvcMovie.Models

    {

        public class Movie

        {

            public int ID { get; set; }

            public string Title { get; set; }

            public DateTime ReleaseDate { get; set; }

            public string Genre { get; set; }

            public decimal Price { get; set; }

        }

        public class MovieDBContext : DbContext

        {

            public DbSet<Movie> Movies { get; set; }

        }

    }

        如果要从数据库中存取数据,类似以上所示的代码是必须要写的。在下一节中,我们将要创建一个新的MoviesController类,用来显示数据库中的数据,并且允许用户创建一个新的movie(电影)的列表。

    展开全文
  • 本篇是写一个草稿示例,目的是让后续编程直接“抄”这个范例代码,就能提高开发效率,以及减少设计混乱。设计MVC的目的是把模型/视图/控制代码分离,这样可以方便地独立维护其中一处,而不影响其它。我之前...
  • EF支持一个被称之为“code-first”的开发范例。Code-first允许你通过书写一些简单的类来创建模型对象,而不用关心这些类的持久化。你可以通过访问这些类的方式来访问数据库,这是一种非常方便快捷的开发模式。  1....
  • 简单聊天软件CS模式 2个目标文件 一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 ...
  • 简单聊天软件CS模式 2个目标文件 一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 ...
  • Activity Activity是一个应用程序组件,提供一个屏幕,用户可以用来交互为了完成某项任务,是一个负责与用户交互组件 SSH 为 Struts+Spring+Hibernate的一个集成框架,是目前较流行一种Web应用程序开源框架。...
  • java源码包---java 源码 大量 实例

    千次下载 热门讨论 2013-04-18 23:15:26
    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源代码...
  • 这几天在学习ASP.NET MVC3,在学习过程中要用到EntityFramework的数据访问技术,Entity Framework(通常被简称为“EF”)支持一个被称之为“code-first”的 开发范例。Code-first允许你通过书写一些简单的类来创建...
  • wxPython学习手册

    热门讨论 2014-04-19 08:01:58
    14.1.1 如何创建一个简单的网格? 433 14.1.2 如何使用网格表来创建一个网格? 435 14.2 使用网格工作 439 14.2.1 如何添加、删除行,列和单元格? 439 14.2.2 如何处理一个网格的行和列的首部? 440 14.2.3 如何...
  • java源码包2

    千次下载 热门讨论 2013-04-20 11:28:17
    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源...
  • asp.net知识库

    2015-06-18 08:45:45
    制作一个简单的多页Tab功能 一完美的关于请求的目录不存在而需要url重写的解决方案! 在C#中实现MSN消息框的功能 XmlHttp实现无刷新三联动ListBox 鼠标放在一个连接上,会显示图片(类似tooltip) 使用microsoft.web.ui...
  • java源码包3

    千次下载 热门讨论 2013-04-20 11:30:13
    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源...
  • 一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源代码...
  • java源码包

    2015-12-01 16:29:37
    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源代码...
  • JAVA上百实例源码以及开源项目

    千次下载 热门讨论 2016-01-03 17:37:40
    一个简单的CS模式的聊天软件,用socket实现,比较简单。 凯撒加密解密程序 1个目标文件 1、程序结构化,用函数分别实现 2、对文件的加密,解密输出到文件 利用随机函数抽取幸运数字 简单 EJB的真实世界模型(源代码...
  • Tomcat与Java Web开发技术详解

    千次下载 热门讨论 2008-07-05 20:53:15
    212 15.4 修改JSP文件 226 15.5 发布采用模板设计的bookstore应用 227 15.6 小结 231 第16章 Struts和MVC设计模式233 16.1 MVC设计模式简介 233 16.2 Struts实现的MVC设计模式 234 16.3 创建...
  • J2EE经典实例详解 <1>

    2008-01-28 17:20:58
    不仅如此,在对Duke应用实例解析基础上,读者能把这一实例作为一个设计模型的范例和扩充框架应用在今后工作实践中。同时,本书中介绍所有技术也是应用服务器和Web服务重要基础。 <br>本书结合了作者...
  • 12.2、定义一个简单的标签 —— 空标签 12.3、定义有属性的标签 12.4、TagSupport类 12.5、定义有标签体的标签库 12.6、开发迭代标签 12.7、BodyTagSupport类 12.8、TagExtraInfo类和VariableInfo类 12.9、...
  • 12.2、定义一个简单的标签 —— 空标签 12.3、定义有属性的标签 12.4、TagSupport类 12.5、定义有标签体的标签库 12.6、开发迭代标签 12.7、BodyTagSupport类 12.8、TagExtraInfo类和VariableInfo类 ...

空空如也

空空如也

1 2
收藏数 35
精华内容 14
关键字:

一个简单的mvc模式范例