【翻译】首个基于NHibernate的应用程序

首个基于NHibernate的应用程序

 Your first NHibernate based application

原文地址:http://www.nhforge.org/wikis/howtonh/your-first-nhibernate-based-application.aspx

本文涉及到的DEMO下载

 

定义领域模型

让我们开始通过定义一个非常简单的领域模型。目前它是由一个称为产品的实体。该产品具有 3 个属性:名称、 类别和中止。

添加一个文件夹 Domain 到您的解决方案的 FirstSample 项目。到此文件夹中添加一个新类 Product.cs。该代码是非常简单,使用自动属性 (C# 3.0新的特征)

namespace FirstSolution.Domain

{

public class Product

{

public string Name { get; set; }

public string Category { get; set; }

public bool Discontinued { get; set; }

}

}

现在我们想要能够持久化相关数据库中此实体的实例。我们选择了 NHibernate来完成这一任务。

领域模型中实体的一个实例对应数据库表中的行。所以我们必须在数据库中定义实体和相应的表之间的映射。此映射可以是另外定义一个映射文件 (一个xml 文档) 或装饰的实体和属性,可以完成此映射。随后,我将开始映射文件的定义。

定义映射

创建一个文件夹 Mappings 到 FirstSample 项目中。并在该文件夹中添加一个新的 xml 文档并命名为 Product.hbm.xml。请注意"hbm"是文件名称的一部分。这是一项约定,这个约定用于NHibernate 自动识别这个文件为一个映射文件。右键此 xml 文件点击属性,在生成操作一项定义"嵌入的资源"

在 Windows 资源管理器中找到 nhibernate mapping.xsd,它在 NHibernate 的 src 文件夹中,并将其复制到您的 SharedLibs 文件夹中。在VS菜单中的XML-架构中导入此xsd文档。编辑 xml 映射文件时,VS 然后将智能感知和验证。

回到在 VS 将架构添加到 Product.hbm.xml 文件

让我们从现在开始。每个映射文件都须定义一个 <hibernate-mapping> 根节点。

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

assembly="FirstSolution"

namespace="FirstSolution.Domain">

<!-- more mapping info here -->

</hibernate-mapping>

在映射文件引用领域模型类时你一定要提供的类的完全限定的名称(如 FirstSample.Domain.Product , FirstSample)。若要使 xml 不那么繁琐,你可以定义程序集名称和领域模型类的命名空间,到根节点的两个属性:assembly 和namespace。它是类似于使用 C# 中的声明。

现在,我们必须先为产品实体定义一个主键。技术上我们可以拿产品的名称属性作为主键,因为此属性必须定义,并且必须是唯一的。但通常会使用代理键代替它成为主键。因此我们将添加一个名为Id的属性到我们的实体。我们使用 Guid 作为 Id 的类型,但也可以是 int 或 long。

using System;

namespace FirstSolution.Domain

{

public class Product

{

public Guid Id { get; set; }

public string Name { get; set; }

public string Category { get; set; }

public bool Discontinued { get; set; }

}

}

完整的映射文件

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"

assembly="FirstSolution"

namespace="FirstSolution.Domain">

<class name="Product">

<id name="Id">

<generator class="guid" />

</id>

<property name="Name" />

<property name="Category" />

<property name="Discontinued" />

</class>

</hibernate-mapping>

NHibernate 不会以我们的方式,比如,它定义了很多合理的默认值。所以,如果您不显式地提供属性的列名,它将按属性名去对应列名。或 NHibernate从类的定义中,可以自动推断的表名或列名。因此我的 xml 映射文件不会被堆满冗余信息。映射的更详细的解释请参阅在线文档。你可以在这里找到它。(http://hibernate.org/nhibernate.html)

你解决方案资源管理器现在应该看起来像这样 (Domain.cd 包含我们简单的领域模型类图)

配置 NHibernate

我们现在必须告诉 NHibernate 我们想要使用哪个数据库产品,并提供它在详细的链接信息,以连接字符串的形式。NHibernate 支持许多数据库产品 !

向 FirstSolution 项目中添加一个新的 xml 文件,并命名为 hibernate.cfg.xml。将其属性"复制到输出目录"设置为"始终复制"。由于我们引用了SQL Server Compact Edition数据库在first sample项目中,所以输入以下信息到xml 文件中。

<?xml version="1.0" encoding="utf-8" ?>

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">

<session-factory>

<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>

<property name="dialect">NHibernate.Dialect.MsSqlCeDialect</property>

<property name="connection.driver_class">NHibernate.Driver.SqlServerCeDriver</property>

<property name="connection.connection_string">Data Source=FirstSample.sdf</property>

<property name="show_sql">true</property>

</session-factory>

</hibernate-configuration>

使用此配置文件,我们告诉 NHibernate 我们想要使用 MS SQL Server Compact Edition作为我们的目标数据库和数据库的名称是 FirstSample.sdf (= 连接字符串)。我们同时也定义了希望看到NHibernate生成并发送到数据库的 SQL语句 (在开发过程中调试时强烈推荐启用此定义)。仔细检查你的代码中有没有错别字 !

添加一个叫FirstSample.sdf的空的数据库,到 FirstSample 项目 (选择本地数据库作为模板)

单击添加并忽略数据集创建向导 (就是点击取消)。

译者的话:我们不一定安装过MS SQL Server Compact Edition数据库,我将在Demo中把它替换成SQLite和相应的配置,这样我们就不需要为了这个快速入门而去专门找一个数据库了。

测试设置

是时候来测试我们的安装了。首先验证您的 SharedLibs 文件夹中有以下文件

您可以找到Microsoft SQL Server Compact Edition在你的程序文件夹中目录最后 8 个文件。

注︰ System.Data.SqlServerCe.dll 位于子文件夹中的桌面。

所有其他文件可以在NHibernate 文件夹中找到。

在您的测试项目中添加对 FirstSample 项目的引用。另外测试项目引用 NHibernate.dll、 nunit.framework.dllSystm.Data.SqlServerCe.dll (记得要引用位于 SharedLibs 文件夹中的文件 !)。要注意为设置属性"复制本地"为 true 为 System.Data.SqlServerCe.dll, 因为在默认情况下它设置为 false !

译者的话:现在VS2012以上都有自带的单元测试项目,也非常好用。所以无需引用nunit.framework.dll,同样System.Data.SqlServerCe.dll也可以替换成System.Data.Sqlite.dll。

在测试项目中添加一个类,命名为 GenerateSchema_Fixture。

现在将下面的代码添加到 GenerateSchema_Fixture 文件

using FirstSolution.Domain;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using NUnit.Framework;
 
namespace FirstSolution.Tests
{
 [TestFixture]
 public class GenerateSchema_Fixture
 {
  [Test]
  public void Can_generate_schema()
  {
   var cfg = new Configuration();
   cfg.Configure();
   cfg.AddAssembly(typeof (Product).Assembly);
   
   new SchemaExport(cfg).Execute(false, true, false, false);
  }
 }
}

测试方法的第一行创建 NHibernate 配置类的一个新实例。此类用于配置 NHibernate。在第二行,我们告诉 NHibernate 配置本身。NHibernate 将留心配置信息,因为我们没在测试方法中提供任何信息。所以 NHibernate 将搜索输出目录中的 hibernate.cfg.xml 文件来调用。这正是我们为什么要在这个文件中这么设置的原因。

在第三行的代码,我们告诉 NHibernate 它可以发现并包含Product类的程序集的映射信息。它将在嵌入的资源中只找到一个(Product.hbm.xml)这样的文件。

第四行代码使用NHibernate中 SchemaExport 的工具类,为我们在自动生成数据库中的架构。

注︰ 我们先不用去理解此测试方法中NHibernate 如何工作 , 但应当关注是否正确地安装。

如果你有安装的 TestDriven.Net 你可以现在只是右键点击里面的测试方法并选择"运行 Test(s)"来执行测试。

译者的话:VS2012以上版本的单元测试可以不用它,微软有自带的。

如果每一件事是好的你应该看到下面的结果,在输出窗口

如果你有安装 ReSharper 你可以开始测试通过单击黄色绿色圆圈的左边框,选择运行。

译者的话:ReSharper同样也不用去理它,这个东西提示实在太多,现在版本的VS智能提醒够用了。

其结果是,如下所示

在出现问题时

如果你测试失败,请双重检查你的目标目录,在其中找到下列文件 (即︰ m:dev\projects\FirstSolution\src\FirstSolution.Tests\bin\debug)

仔细检查NHibernate 配置文件 (hibernate.cfg.xml) 中或在映射文件 (Product.hbm.xml)中是否有错别字,最后检查映射文件 (Product.hbm.xml)是否设置为"嵌入的资源"的"生成操作"。如果测试成功,才继续。

我们第一次的 CRUD 操作

现在很明显我们的系统已是准备好开始了。我们成功地实现了我们的领域模型,定义映射文件和配置 NHibernate。最后我们使用 NHibernate 从我们的领域模型 (和我们映射文件) 自动生成数据库架构。

在 DDD (参考Eric Evans的《领域驱动设计》) 的精神,我们为所有的 crud 操作(创建、 读取、 更新和删除)定义了Repository。Repository接口是领域模型不实现的一部分!执行是特定的基础设施。我们要保持我们的领域模型和持久化无关 (PI)。

译者的话:这一段我不知道该如何去翻译它,但我可以解释它的意思。它的大致意思是根据DDD的思想,领域模型Domain里面不应该有和持久化有关的东西,比如我们的Product中不该包含数据库CRUD操作,而这些CRUD的基础操作该在仓储Repository接口中实现。

到我们的 FirstSolution 项目的域文件夹中添加一个新的界面。把它叫做 IProductRepository。让我们定义以下接口

using System;
using System.Collections.Generic;
 
namespace FirstSolution.Domain
{
 public interface IProductRepository
 {
  void Add(Product product);
  void Update(Product product);
  void Remove(Product product);
  Product GetById(Guid productId);
  Product GetByName(string name);
  ICollection<Product> GetByCategory(string category);
 }
}

添加一个类 ProductRepository_Fixture 到测试项目下,并添加下面的代码

[TestFixture]
 public class ProductRepository_Fixture
 {
  private ISessionFactory _sessionFactory;
  private Configuration _configuration;
 
  [TestFixtureSetUp]
  public void TestFixtureSetUp()
  {
   _configuration = new Configuration();
   _configuration.Configure();
   _configuration.AddAssembly(typeof (Product).Assembly);
   _sessionFactory = _configuration.BuildSessionFactory();
  }
 }

在 TestFixtureSetUp 方法的第四行,我们创建一个session factory。这是一个开销很大的过程,因此应该只有一次执行。这就是为什么把它放到这种测试期间只执行一次的方法的原因。

要保持我们测试方法无副作用,每个测试方法执行之前,我们重新创建我们的数据库架构。因此我们添加下面的方法

[SetUp]

public void SetupContext()

{

new SchemaExport(_configuration).Execute(false, true, false, false);

}

现在我们可以实现向数据库中添加一个新的Product实例的测试方法。添加一个新的文件夹名为Repositories到 FirstSolution 项目。到此文件夹中添加一个类 ProductRepository。使 ProductRepository 从 IProductRepository 接口继承。

using System;
using System.Collections.Generic;
using FirstSolution.Domain;
 
namespace FirstSolution.Repositories
{
 public class ProductRepository : IProductRepository
 {
  public void Add(Product product)
  {
   throw new NotImplementedException();
  }
 
  public void Update(Product product)
  {
   throw new NotImplementedException();
  }
 
  public void Remove(Product product)
  {
   throw new NotImplementedException();
  }
 
  public Product GetById(Guid productId)
  {
   throw new NotImplementedException();
  }
 
  public Product GetByName(string name)
  {
   throw new NotImplementedException();
  }
 
  public ICollection<Product> GetByCategory(string category)
  {
   throw new NotImplementedException();
  }
 }
}

操作数据

现在回到ProductRepository_Fixture测试类和实现第一个测试方法

[Test]

public void Can_add_new_product()

{

var product = new Product {Name = "Apple", Category = "Fruits"};

IProductRepository repository = new ProductRepository();

repository.Add(product);

}

首次运行的测试方法将失败,因为我们的仓储类未实现 Add 方法。让我们做它。但是,等一等,我们必须首先定义一个小的帮助器类提供我们会话对象上的需求。

using FirstSolution.Domain;
using NHibernate;
using NHibernate.Cfg;
 
namespace FirstSolution.Repositories
{
 public class NHibernateHelper
 {
  private static ISessionFactory _sessionFactory;
 
  private static ISessionFactory SessionFactory
  {
   get
   {
    if(_sessionFactory == null)
    {
     var configuration = new Configuration();
     configuration.Configure();
     configuration.AddAssembly(typeof(Product).Assembly);
     _sessionFactory = configuration.BuildSessionFactory();
    }
    return _sessionFactory;
   }
  }
 
  public static ISession OpenSession()
  {
   return SessionFactory.OpenSession();
  }
 }
}

运行期间,此类只创建session factory第一次,不管客户端何时需要一个新的session。

现在我们可以定义 Add 方法在 ProductRepository 中,如下所示

public void Add(Product product)

{

using (ISession session = NHibernateHelper.OpenSession())

using (ITransaction transaction = session.BeginTransaction())

{

session.Save(product);

transaction.Commit();

}

}

第二次运行的测试方法会再次失败并显示以下消息

这是因为 NHibernate 是默认情况下配置为使用延迟加载的所有实体。这是推荐的方法,我强烈建议不要更改,为了最大的灵活性。

我们怎样才能解决这个问题?很容易,让领域模型中所有属性 (方法) 加上Virtual关键字即可。让我们为我们的Product类加上这个。

public class Product

{

public virtual Guid Id { get; set; }

public virtual string Name { get; set; }

public virtual string Category { get; set; }

public virtual bool Discontinued { get; set; }

}

现在再次运行测试。它应该会成功,我们得到以下输出

请注意NHibernate输出的 sql 语句。

现在我们觉得,我们成功地向一个新的Product插入数据库。但让我们测试它是否真的是这样。让我们来扩展我们的测试方法

[Test]
  public void Can_add_new_product()
  {
   var product = new Product {Name = "Apple", Category = "Fruits"};
   IProductRepository repository = new ProductRepository();
   repository.Add(product);
 
   // use session to try to load the product
   using(ISession session = _sessionFactory.OpenSession())
   {
    var fromDb = session.Get<Product>(product.Id);
    // Test that the product was successfully inserted
    Assert.IsNotNull(fromDb);
    Assert.AreNotSame(product, fromDb);
    Assert.AreEqual(product.Name, fromDb.Name);
    Assert.AreEqual(product.Category, fromDb.Category);
   }
  }

再次运行测试。希望它会成功......

现在我们准备也实现repository中的其他方法。为了测试这我们宁愿要一个repository  (即数据库表) 已经包含了一些产品。没有什么比这更简单。只是添加 CreateInitialData 方法,如下所示添加到测试类

private readonly Product[] _products = new[]
     {
      new Product {Name = "Melon", Category = "Fruits"},
      new Product {Name = "Pear", Category = "Fruits"},
      new Product {Name = "Milk", Category = "Beverages"},
      new Product {Name = "Coca Cola", Category = "Beverages"},
      new Product {Name = "Pepsi Cola", Category = "Beverages"},
     };
 
  private void CreateInitialData()
  {
   
   using(ISession session = _sessionFactory.OpenSession())
    using(ITransaction transaction = session.BeginTransaction())
    {
     foreach (var product in _products)
      session.Save(product);
     transaction.Commit();
    }
  }

(在创建架构调用后) 从 SetupContext 方法调用此方法。现在每次数据库架构创建数据库后填充一些产品。

让我们测试用下面的代码库的更新方法

[Test]
  public void Can_update_existing_product()
  {
   var product = _products[0];
   product.Name = "Yellow Pear";
   IProductRepository repository = new ProductRepository();
   repository.Update(product);
 
   // use session to try to load the product
   using (ISession session = _sessionFactory.OpenSession())
   {
    var fromDb = session.Get<Product>(product.Id);
    Assert.AreEqual(product.Name, fromDb.Name);
   }
  }

第一次运行时此代码将失败,因为更新方法尚未在Repository中实现。注︰ 这是预期的行为,因为在 TDD 第一次运行测试时它应该总是失败 !

译者的话:这篇快速开始的入门教程水非常深,又是DDD,又是TDD,吓死人了,没接触过的人可以忽略。同时也可见NHibernate更多是面向一些资深的面向对象程序员,可悲的是很多程序员未入门时就接触到了它。叹息!

类似于 Add 方法我们实现Repository中的 Update 方法。唯一的区别是我们调用NHibernate session对象的update 方法而不是Save方法。

public void Update(Product product)

{

using (ISession session = NHibernateHelper.OpenSession())

using (ITransaction transaction = session.BeginTransaction())

{

session.Update(product);

transaction.Commit();

}

}

再次运行测试希望它成功。

Delete 方法是直截了当。测试是否真的已删除记录时,我们只是断言由会话的 get 方法返回的值是等于 null。这里是测试方法

[Test]

public void Can_remove_existing_product()

{

var product = _products[0];

IProductRepository repository = new ProductRepository();

repository.Remove(product);

using (ISession session = _sessionFactory.OpenSession())

{

var fromDb = session.Get<Product>(product.Id);

Assert.IsNull(fromDb);

}

}

Repository中删除方法的实现

public void Remove(Product product)

{

using (ISession session = NHibernateHelper.OpenSession())

using (ITransaction transaction = session.BeginTransaction())

{

session.Delete(product);

transaction.Commit();

}

}

查询数据库

我们仍然必须执行查询的数据库对象的三个方法。我们先从最容易的一个,GetById。我们首先编写测试

[Test]

public void Can_get_existing_product_by_id()

{

IProductRepository repository = new ProductRepository();

var fromDb = repository.GetById(_products[1].Id);

Assert.IsNotNull(fromDb);

Assert.AreNotSame(_products[1], fromDb);

Assert.AreEqual(_products[1].Name, fromDb.Name);

}

然后完成测试的代码

public Product GetById(Guid productId)

{

using (ISession session = NHibernateHelper.OpenSession())

return session.Get<Product>(productId);

}

现在,那很简单。为以下两种方法,我们使用session对象的新方法。让我们开始用 GetByName 方法。像往常一样我们先写测试

[Test]

public void Can_get_existing_product_by_name()

{

IProductRepository repository = new ProductRepository();

var fromDb = repository.GetByName(_products[1].Name);

Assert.IsNotNull(fromDb);

Assert.AreNotSame(_products[1], fromDb);

Assert.AreEqual(_products[1].Id, fromDb.Id);

}

GetByName 方法的实现可以通过使用两个不同的方法。第一使用 HQL (Hibernate Query Language) 和第二个 HCQ (Hibernate Criteria Query)。让我们开始使用 HQL。HQL 是面向对象的查询语言 SQL 类似 (但不是等于)。

在上面的示例中我介绍了常用的技术使用 NHibernate 时。它被称为fluent接口。作为结果的代码是简练也更易于理解。你可以看到一个 HQL 查询是一个字符串,它可以具有嵌入 (命名) 参数。参数使用前缀 ‘:‘。NHibernate 定义很多的helper方法 (如示例中使用 SetString),将各种类型的值分配给这些参数。最后通过使用 UniqueResult 我告诉 NHibernate 希望只有一条记录返回。如果多个然后引发异常,HQL 查询将返回一条记录。要获取更多的信息 HQL 请阅读在线文档。

第二个版本使用criteria query来搜索请求的Product。

public Product GetByName(string name)

{

using (ISession session = NHibernateHelper.OpenSession())

{

Product
product = session

.CreateCriteria(typeof(Product))

.Add(Restrictions.Eq("Name", name))

.UniqueResult<Product>();

return product;

}

}

NHibernate 的许多用户认为这种做法是更多面向的对象。在另一方面编写的标准语法复杂查询可以迅速成为难以理解。

实现的最后一个方法是 GetByCategory。此方法返回Product的列表。测试可以实现,如下所示

[Test]

public void Can_get_existing_products_by_category()

{

IProductRepository repository = new ProductRepository();

var fromDb =
repository.GetByCategory("Fruits");

Assert.AreEqual(2, fromDb.Count);

Assert.IsTrue(IsInCollection(_products[0],
fromDb));

Assert.IsTrue(IsInCollection(_products[1], fromDb));

}

private bool IsInCollection(Product product, ICollection<Product> fromDb)

{

foreach (var item in fromDb)

if (product.Id == item.Id)

return true;

return false;

}

方法本身可能包含下面的代码

public ICollection<Product> GetByCategory(string category)

{

using (ISession session = NHibernateHelper.OpenSession())

{

var
products = session

.CreateCriteria(typeof(Product))

.Add(Restrictions.Eq("Category", category))

.List<Product>();

return products;

}

}

摘要

在这篇文章中我已经给你如何实现基本示例领域模型,定义映射到数据库以及如何配置 NHibernate 能够持久化领域对象在数据库中。我给你展示了如何通常编写和测试您的领域对象的 CRUD 方法。我拿MS SQL Compact Edition 作为示例数据库,但可以使用任何其他受支持的数据库 (你只需要相应地更改 hibernate.cfg.xml
文件)。我们没有依赖于外部框架或工具以外的数据库和 NHibernate 本身 (.NET 当然从来没有计算在内)。

译者的话:终于翻译完了,这篇快速开始非常适合初学者,因为提供的例子是可以被实现的,而且可以同时入门DDD和TDD,看得出作者非常用心。而我也在其中加入了批注,以适应我们当下的情况。

时间: 2024-08-01 22:47:14

【翻译】首个基于NHibernate的应用程序的相关文章

翻译:打造基于Sublime Text 3的全能python开发环境

原文地址:https://realpython.com/blog/python/setting-up-sublime-text-3-for-full-stack-python-development/ 原文标题:Setting Up Sublime Text 3 for Full Stack Python Development 翻译:打造基于sublime text 3的全能Python开发环境 Sublime Text 3 (ST3) is lightweight, cross-platfo

[Fluent NHibernate]第一个程序

目录 写在前面 Fluent Nhibernate简介 基本配置 总结 写在前面 在耗时两月,NHibernate系列出炉这篇文章中,很多园友说了Fluent Nhibernate的东东,也激起我的兴趣,想对它一探究竟,这里也将Fluent Nhibernate写成一个系列,记录自己的学习过程,关于这东东,也是第一次接触,也只能边摸索,边记录了.如果有描述错误的地方,还望多多包涵. 通过Nhibernate的学习,都觉得Nhibernate的使用映射文件的编写很麻烦,这里通过Fluent Nhi

华为云推出业界首个基于ARM框架的云手机解决方案

华为云推出业界首个基于ARM框架的云手机解决方案在手机已经普及到千家万户的时代,人们对手机应用的诉求日益提升.为此,华为云推出了云手机. 华为云云手机提供基于云的虚拟仿真手机服务,将手机上的应用转移到云上的虚拟手机来运行,重新定义了手机应用的开发和使用. 1 华为云云手机靠谱么?就在2019年新年伊始,华为云云手机就斩获"2018年度杰出云计算创新产品奖".该奖项由51CTO主办的<中国企业"IT印象◆创新IT,赋能未来"年终评选>活动颁发. 同时,在绿

基于DevExpress的Winform程序安装包的制作

在我们做系统开发的时候,都会面临一个安装包制作的问题,如何把我们做好的系统,通过安装包工具整合成一个安装包给客户进行安装.安装包的优势就是一步步安装就可以了,不用复制一大堆文件给客户,还怕缺少那个文件导致系统运行出错.本文主要介绍基于DevExpress的Winform程序安装包的制作内容,包括VS2010和VS2013/V2105的不同处理方式. 我们知道,VS2010是最后一个可以使用微软安装包制作工具的VS版本了,所以后面VS2012/2013/2015版本都需要使用第三方安装包制作工具,

【翻译】在Ext JS 5应用程序中如何使用路由

原文:How to Use Routing in Your Ext JS 5 Apps 简介 Ext JS 5是一个重要的发布版本,它提供了许多新特性来创建丰富的.企业级的Web应用程序.MVVM和双向数据绑定为开发人员承担了大量的繁重工作.在Ext JS 5种,另一个新特性就是路由,它可以在控制器内轻松的管理历史记录.前进和后退按钮是每个浏览器都会拥有的公共用户接口,现在,使用Ext JS 5在单页面应用程序中处理导航变得相当简单了. Ext JS 5路由 在Ext JS,已经可以使用Ext.

ok6410[002] ubuntu1604系统下搭配ckermit和dnw基于RAM的裸机程序调试环境

ubuntu1604系统下搭配ckermit和dnw基于RAM的裸机程序调试环境 系统:  ubuntu16.04 裸板: 飞凌公司OK6410开发板 目标:搭建基于ubuntu1604系统和基于RAM的裸机程序开发环境 1.安装配置ckermit 在ubuntu1604下一般做裸板开发时都是使用ckermit作为远程通讯终端,下面我们就开始讲解下其安装与配置. 1.1.安装ckermit 在ubuntu系统下安装ckermit,使用 sudo  apt-get  install  ckermi

Win10 IoT C#开发 2 - 创建基于XAML的UI程序 及 应用的三种部署方法

原文:Win10 IoT C#开发 2 - 创建基于XAML的UI程序 及 应用的三种部署方法 Windows 10 IoT Core 是微软针对物联网市场的一个重要产品,与以往的Windows版本不同,是为物联网设备专门设计的,硬件也不仅仅限于x86架构,同时可以在ARM架构上运行. 上一章我们讲了Raspberry安装Win10 IoT系统及搭建Visual Studio 2015开发环境的方法(http://www.cnblogs.com/cloudtech/p/5562120.html)

最简单的基于FFMPEG的Helloworld程序

===================================================== 最简单的基于FFmpeg的视频播放器系列文章列表: 100行代码实现最简单的基于FFMPEG+SDL的视频播放器(SDL1.x) 最简单的基于FFMPEG+SDL的视频播放器 ver2 (採用SDL2.0) 最简单的基于FFmpeg的解码器-纯净版(不包括libavformat) 最简单的基于FFMPEG+SDL的视频播放器:拆分-解码器和播放器 最简单的基于FFMPEG的Hellowor

学习基于OpenGL的CAD程序的开发计划(一)

本人目前从事的工作面对的客户中很多来自高端制造业,他们对CAD/CAE/CAM软件的应用比较多.公司现有的软件产品主要是用于渲染展示及交互,但面对诸如CAD方面的应用(比如基于约束的装配.制造工艺的流程演示等),功能比较薄弱.本人计划在工作之余开始研究一下基于OpenGL的CAD程序开发的基础功能实现.由于目前工作直接使用的商业游戏引擎进行开发,对底层的OpenGL还不是特别熟悉,从产品发展的长远来看,结合CAD的功能应该是大势所趋,而目前利用一些三维CAD二次开发来实现虽然可以临时解决一些功能