一、Oracle XE 数据库与连接工具安装使用

Oracle数据库历来以价格昂贵出名,当然贵有贵的道理,成为一个Oracle DBA也是令人羡慕的事情,如果程序员熟悉Oracle使用也有机会接触到大型的项目,但是Oracle似乎对一般程序员不怎么友好,因为其繁琐的安装配置过程和对系统硬件的苛求,另一般人望而止步,我最早从Oracle 9i开始接触它,深有感受,特别是熟悉了SqlServer的开发人员,初次接触Oracle还是很不习惯的。比如它没有SqlServer数据“库”的概念,一个sa账号管理很多数据库,在Oracle里面,它叫做“数据服务”,通过不同的数据库用户来区分数据。

1.1 数据库服务安装

现在,Oracle推出了一个免费的数据库产品,Database 快捷版 11g ,这个就像SqlServer Express版本一样,都是免费的,与收费版在功能没有任何区别,但是有些使用条件限制,比如仅支持一个CPU,数据文件组大小有限制等,但是一般中小企业的一些中小应用还是够了。Database 快捷版 11g下载地址请点击这里。不过下载之前要先注册Oracle账号,并同意下载许可声明。

适用于 Windows x64 的 Oracle Database 快捷版 11g 第 2 版
  - 解压缩下载文件,然后运行 DISK1/setup.exe
适用于 Windows x32 的 Oracle Database 快捷版 11g 第 2 版
  - 解压缩下载文件,然后运行 DISK1/setup.exe

适用于 Linux x64 的 Oracle Database 快捷版 11g 第 2 版 - 解压缩下载文件,可以像往常一样安装 RPM 文件

根据你的情况,选择下载32位的或者64位的,我下载了64位的,安装很简单,中途没有什么特别注意的地方,一路“下一步” 即可,这比起Oracle其他版本的数据库安装来说,实在很简单,安装完成后,即可使用了,不过千万记住不要忘记了Sys,System 用户的密码。安装完成之后,在桌面会有一个快捷方式:Oracle Database 11g Express Edition 入门 ,单击,进入Web的管理界面:

如果要查看其它界面,需要输入管理员密码,比如查看存储的界面:

如果要进行创建数据库用户,建表等操作,还得启动SQL plus 程序,不用做额外的配置,可以直接启动,这相比收费版,又简单了不少:

具体创建用户,创建表的工作,可以使用Oracle的SQL语句来做,但我们这里通过另外一个工具来做,还是在之前的Oracle XE 下载页面:

  Oracle SQL Developer
  Oracle SQL Developer Data Modeler
  Oracle Application Express
  针对 Java 开发人员的 JDeveloper
  Oracle Developer Tools for Visual Studio .NET
  Zend Server

到这里下载一个最新版本的Oracle VS插件,有好几个版本,下载最上面的就好了,不过下载一样需要Oracle用户账号。

1.2 Oracle VS插件安装使用

安装这个插件的时候,注意安装提示,首先管理员账号Sys和密码,然后是要连接的Oracle服务名,输入相关的服务名,这里默认是 XE,然后保存为一个TNS名字,我用的是mydb,最后还有一个ODP.Net的安装,询问是否安装程序集到GAC,这里选择安装。

安装好后,在VS的“服务器资源管理器”--》“数据连接”,新建一个连接:

在图例中,我们选择以SysDba的角色进行登录,之后,就可以创建用户,查询表和编辑数据了,很方便,这里我建立了一个名字为SOD的用户,然后用这个用户登录:

功能很多,具体内容留给大家去研究了。不过从这里添加的用户不太方便设置成DBA角色,还是用命令行来设置。

至此,Oracle XE 的数据服务和开发工具插件,基本上安装好了。

1.3 PDF.NET集成开发工具连接Oracle

不过,我们也可以使用SOD框架的集成开发工具来连接,该工具连接过程如下:

最后点击确定,回到下面的界面,展开XE数据库,选择数据表,右键菜单查询数据:

至此,Oracle 的安装,连接过程就完成了,很简单。

二、SOD框架的Oracle CodeFirst支持

SOD框架是PDF.NET开发框架的数据框架,目前已经支持了SqlServer,SqlServerCe,Access,MySQL,PostgreSQL等主流数据库的Code First,但  PDF.NET_SOD Ver 5.2.1.0307  还未实现Oracle的Code First支持,主要原因是我对 Oracle 目前使用较少,如果不是SOD会员用户的强烈要求,可能SOD对Oracle Code First支持还要往后推延一段时间。

2.1 Oracle自增列处理

实际上SOD框架对Oracle Code First的支持并不复杂,主要需要解决的问题就是Oracle数据库自增字段的处理,大部分情况下,这都是通过触发器来实现的。

改写下 EntityCommand 类的创建表的方法,添加Oracle的处理:

 public string CreateTableCommand
{
get {
if (_createTableCommand == null)
{
string script = @"
CREATE TABLE @TABLENAME(
@FIELDS
)
"; if (this.currDb.CurrentDBMSType == PWMIS.Common.DBMSType.PostgreSQL && !string.IsNullOrEmpty(currEntity.IdentityName))
{
string seq =
"CREATE SEQUENCE " + currEntity.TableName + "_" + currEntity.IdentityName + "_" + "seq INCREMENT 1 MINVALUE 1 MAXVALUE 9223372036854775807 START 1 CACHE 1;"; script = seq + script;
}
else if (this.currDb.CurrentDBMSType == PWMIS.Common.DBMSType.Oracle && !string.IsNullOrEmpty(currEntity.IdentityName))
{
// --; 语句分割符号
string seqTemp = @" CREATE SEQUENCE @TableName_@IDName_SEQ MINVALUE 1 NOMAXVALUE INCREMENT BY 1 START WITH 1 NOCACHE
;-- CREATE OR REPLACE TRIGGER @TableName_INS_TRG BEFORE
INSERT ON [@TableName] FOR EACH ROW WHEN(new.[@IDName] IS NULL)
BEGIN
SELECT @TableName_@IDName_SEQ.NEXTVAL INTO :new.[@IDName] FROM DUAL;
END;
;--
";
script = script + ";--\r\n" + seqTemp.Replace("@TableName", currEntity.TableName).Replace("@IDName", currEntity.IdentityName);
} var entityFields = EntityFieldsCache.Item(this.currEntity.GetType());
string fieldsText = "";
foreach (string field in this.currEntity.PropertyNames)
{
string columnScript =entityFields.CreateTableColumnScript(this.currDb as AdoHelper, this.currEntity, field);
fieldsText = fieldsText + "," + columnScript+"\r\n";
}
string tableName =this.currDb.GetPreparedSQL("["+ currTableName+"]");
_createTableCommand = script.Replace("@TABLENAME", tableName).Replace("@FIELDS", fieldsText.Substring());
}
return _createTableCommand;
}
}

2.2 SOD Oracle Code First实现过程

由于Oracle 数据库的字段类型名称,对应DbType的名字并不完全相符,所以需要对AdoHelper类的Oracle实现类稍加修改:

public class Oracle : AdoHelper
{
//其它略
public override string GetNativeDbTypeName(IDataParameter para)
{
OracleParameter oraPara = (OracleParameter)para;
OracleType oraType = oraPara.OracleType;
if (oraType == OracleType.DateTime)
return "Date";
else if (oraType == OracleType.Int32)
return "INT";
else
return oraType.ToString(); }
}

能够根据实体类,得到生成表的建表脚本,任务已经完成了一半,不过SOD提供了一个DbContext类的封装,可以自动完成这个过程,下面就来实现一个Oracle的DbContext:

namespace PWMIS.Core.Extensions
{
public abstract class OracleDbContext :DbContext
{
/// <summary>
/// 用连接字符串名字初始化本类
/// </summary>
/// <param name="connName"></param>
public OracleDbContext(string connName)
: base(connName)
{ }
/// <summary>
/// 检查实体类对应的数据表是否在数据库中存在
/// </summary>
protected override void CheckTableExists<T>()
{
//创建表
if (CurrentDataBase.CurrentDBMSType == PWMIS.Common.DBMSType.Oracle)
{
var entity = new T();
var dsScheme = CurrentDataBase.GetSchema("Tables", null);
string owner = CurrentDataBase.ConnectionUserID;
var rows = dsScheme.Select("OWNER='"+ owner +"' and table_name='" + entity.GetTableName() + "'");
if (rows.Length == )
{
EntityCommand ecmd = new EntityCommand(entity, CurrentDataBase);
string sql = ecmd.CreateTableCommand;
//OracleClient 不能批量执行多条SQL语句
string[] sqlArr = sql.Split(new string[] {";--" }, StringSplitOptions.RemoveEmptyEntries);
foreach (string item in sqlArr)
{
if(item.Length >) //去除回车行
CurrentDataBase.ExecuteNonQuery(item);
} }
}
}
}
}

2.3  Code First 使用示例

将SOD框架源码的 SampleORMTest 测试项目的LocalDbContext 的代码稍加修改:

namespace SampleORMTest
{
/// <summary>
/// 用来测试的本地SqlServer 数据库上下文类
/// </summary>
public class LocalDbContext : DbContext //OracleDbContext, SqlServerDbContext 会根据 local连接字符串自动决定内部使用
{
public LocalDbContext()
: base("local")
{
//local 是连接字符串名字
} #region 父类抽象方法的实现 protected override bool CheckAllTableExists()
{
//创建用户表
CheckTableExists<User>();
return true;
} #endregion
}
}

只需要在OracleDbContext 实现类的CheckAllTableExists 方法内,实现各个实体类的表创建工作即可,比如本例创建用户表。

修改下App.config 文件的连接配置:

<connectionStrings>
<!--<add name="local" connectionString="Data Source=.;Initial Catalog=LocalDB;Integrated Security=True" providerName="SqlServer" />-->
<!--下面的配置适应于 Oracle.Client-->
<add name="local" connectionString="Data Source=XE;User Id=SOD;Password=sod123;Integrated Security=no;" providerName="Oracle" />
</connectionStrings>

然后,像下面这样使用,即可自动创建数据库和表,并且添加一条初始数据:

LocalDbContext context = new LocalDbContext();//自动创建表
User zhang_san = new User() { Name = "zhang san", Pwd = "" };
count += context.Add<User>(zhang_san);//采用 DbContext 方式插入数据

当然插入数据的方式很多,具体请看本文提供的源码下载。

最后,像下面这样使用查询即可:

User user = new User(){  Name="zhang san";};
OQL q=OQL.From(user)
.Select()
.Where(user.Name)
.END;
List<User> users = EntityQuery<User>.QueryList(OQL);

这种方式适合简单的相等条件查询,如果需要复杂的条件,可以修改成下面这个样子:

User user = new User();
OQL q = OQL.From(user)
.Select()
.Where(cmp => cmp.Comparer(user.Name, "=", "zhang san") )
.END;
List<User> users = EntityQuery<User>.QueryList(q);

示例代码中的  可以修改成 >,<,like 等SQL支持的比较符号。

如果需要更多条件,可以使用 &表示SQL的AND,| 表示 SQL的OR 逻辑关系,比如:

User user = new User();
OQL q = OQL.From(user)
.Select()
.Where(cmp => cmp.Comparer(user.Name, "=", "zhang san") &
cmp.Comparer(user.Pwd, "=", "123") )
.END;

  

这样,一个简单的ORM使用实例就做好了。上面这段ORM例子,不仅仅适用于Oracle,使用在其它数据库都是可以得,只需要修改 连接字符串配置的 providerName和 connectionString 即可,比如 privideName="SqlServer"

三、使用ODP.Net 访问Oracle数据库

3.1 创建SOD的ODP.Net扩展程序集

在本文中,已经说到安装了Oracle 的.net数据访问组件ODP.Net,MS也建议用这个组件来代替MS自己的Oracle.Client,下面,我们只需要新建立一个项目,引用下ODP.Net组件即可:

把SOD框架的核心程序集PWMIS.Core 的Oracle.cs 文件拷贝下来,只需要修改下命名空间即可使用。

编译这个项目,让SampleORMTest 测试项目引用它,或者直接拷贝DLL到测试项目,

3.2 运行32位的ODP.Net

重新修改下App.config文件的连接配置:

<add name="local" connectionString="Data Source=XE;User Id=SOD;Password=sod123"
providerName="PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient" />

运行项目,首先抛出下面这样一个异常:

其他信息: 未能加载文件或程序集“Oracle.DataAccess, Version=2.121.2.0, Culture=neutral, PublicKeyToken=89b483f429c47342”或它的某一个依赖项。试图加载格式不正确的程序。

第一反应,应该是32位于6位程序不兼容的问题,仔细回想下,这可能是 Oracle VS插件安装时候安装到GAC里面的程序集。于是将测试程序修改成32位的(编译目标为x86),运行良久,再次报错,说TNS无法解析。
奇怪,使用MS Oracle Client都没有问题,为何用了ODP.Net缺不行了呢?百度了下,但觉得别人说的跟我当前不太一样。

检查Oracle的VS插件程序的安装目录,在 E:\app\client\dth\product\12.1.0\client_1\Network\Admin 目录中发现TSN配置文件 tnsnames.ora ,打开,原来是这样的内容:

mydb =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
)

分析内容,这应该是安装VS插件的时候,配置生成的。 那么原来的XE服务的监听名字是怎么来的? 在搜索下Oracle服务的安装目录,在 E:\oraclexe\app\oracle\product\11.2.0\server\network\ADMIN  下面找到了 tnsnames.ora 文件,打开:

XE =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = dth-home)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
) EXTPROC_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
)
(CONNECT_DATA =
(SID = PLSExtProc)
(PRESENTATION = RO)
)
) ORACLR_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1))
)
(CONNECT_DATA =
(SID = CLRExtProc)
(PRESENTATION = RO)
)
)

原来默认的Oracle XE 监听服务名是这样定义的。

重新配置连接,将服务名从XE更改为mydb,顺利通过。

<add name="local" connectionString="Data Source=mydb;User Id=SOD;Password=sod123"
providerName="PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient" />

如果不配置mydb这个TNS名字,可否直接使用呢?答案是可以,只需要将连接字符串做如下修改即可:

 <add name="local" connectionString="Data Source=(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = XE)
)
);User Id=SOD;Password=sod123"
providerName="PWMIS.DataProvider.Data.OracleDataAccess.Oracle,PWMIS.OracleClient" />

测试运行,成功,可惜目前为止,还是基于32位的ODP.Net做的测试。

3.3 64位ODP.Net 使用

回忆之前安装XE数据库服务,确认当时安装的是64位的数据库,那么去它的安装目录,看看有没有ODP,一看,果然有:
E:\oraclexe\app\oracle\product\11.2.0\server\odp.net\bin\2.x
这里的 Oracle.DataAccess.dll 是64位的。
将它拷贝到SOD框架下面,再运行,终于看到了成功界面:

四、免安装Oracle客户端,使用ODP.Net

前面使用ODP.Net的过程,都是在本地机器安装了Oracle XE数据库和Oracle VS 开发插件的情况下进行的,但是,如果把访问Oracle的程序部署到一台没有装过Oracle程序的机器上,程序是无法使用的,这还得做下Oracle 环境的部署,过程如下:

4.1,下载ODAC

打开下面的链接:

http://www.oracle.com/technetwork/topics/dotnet/downloads/index-2235287.html?ssSourceSiteId=otncn


Oracle Data Access Components (12.1.0.1.0) Beta 2 - Oracle Universal Installer            [Released September 23, 2014]

-->

Download 32-bit ODAC
  ODAC121010Beta2_32bit.zip 291 MB (305,236,226 bytes)
     
     
Download 64-bit ODAC
  ODAC121010Beta2_64bit.zip 282 MB (296,156,450 bytes)
     
     
    OUI Install and Configuration Instructions
  ODAC 12c Release 3 Beta 2 Installation Instructions
    1. Un-GAC any existing ODP.NET 12.1.0.1 versions you have installed. If you plan to use only the ODP.NET, Managed Driver beta, only un-GAC existing managed ODP.NET 12.1.0.1 versions then.
    2. In Visual Studio 2012 or 2013, open NuGet Package Manager from an existing Visual Studio project.
    3. Click on the Settings button in the lower left of the dialog box.
    4. Click the "+" button to add a package source. In the Source field, enter in the directory location where the NuGet package(s) were downloaded to. Click the Update button, then the Ok button.
    5. In the drop down box at the top center-left of the page, select "Include Prerelease".
    6. On the left side, under the Online root node, select the package source you just created. The ODP.NET NuGet packages will appear.
    7. Click on the Install button to select the desired NuGet package(s) to include with the project. Accept the license agreement and Visual Studio will continue the setup.
    8. Open the app/web.config file to configure the ODP.NET connection string and local naming parameters (i.e. tnsnames.ora).
     

Oracle Data Access Components (12.1.0.1.0) Beta 2 - Xcopy           [Released September 23, 2014]

Download 32-bit ODAC
  ODAC121010Beta2_32bitXcopy.zip 61.6 MB (64,608,758 bytes)
     
     
Download 64-bit ODAC
  ODAC121010Beta2_64bitXcopy.zip 65.8 MB (69,024,274 bytes)
     
     
ODP.NET, Managed Driver
  ODP.NETManaged12010Beta2_Xcopy.zip 2.41 MB (2,532,077 bytes)
     

这里提供了2种下载安装方式,前一种,Oracle Universal Installer  安装包比较大,略过,我们选择第二种,XCopy方式来部署。

根据你的需要,下载32位或者 64位的ODAC,并且下载 ODP.Net ,Managed Driver.

4.2,安装ODAC

比如我下载的是 64位的ODAC,以管理员权限启动命令行

第一步,输入下面的命令:

install.bat all c:\oracle odac

这里表示将Oracle客户端程序复制到 c:\oracle 目录下面

第二步,安装ODP.Net,输入下面的命令:

install_odpm.bat c:\oracle x64 true

注意:c:\oracle 目录是第一步命令里面指定的路径。

第三步,关键,在系统环境变量里面,Path变量里面,包含Oracle程序的路径:

c:\oracle;c:\oracle\bin;

这样设置以后,本文的Oracle访问程序,就可以正常运行了。

五、获取Oracle SOD Code First支持

当前程序的全部代码已经签入SOD框架的开源项目,地址 http://pwmis.codeplex.com ,你在源码栏目可以查看到当前最新的更改,如果你有codeplex账号,可以直接连接TFS下载,如果没有,可以用SVN下载,独立下载包,

     Oracle_ORM_Sample

     PDFNetTools20150324

下载说明,请看https://pwmis.codeplex.com/releases/view/612310

如果你们有Oracle服务器,但不再本地机器,可能需要单独下载ODP并安装, 64位程序下载地址:http://www.oracle.com/technetwork/database/windows/downloads/index-090165.html

SOD框架开发团队一直致力于广大程序员的CRUD解放工作,打造最轻,最方便而又灵活的数据开发框架,感谢你的支持!

欢迎加入SOD开发者团队,更多详细信息,请看框架官网 http://www.pwmis.com/sqlmap

Oracle 免费的数据库--Database 快捷版 11g 安装使用与"SOD框架"对Oracle的CodeFirst支持的更多相关文章

  1. Oracle 免费的数据库

    Oracle 免费的数据库--Database 快捷版 11g 安装使用与"SOD框架"对Oracle的CodeFirst支持 一.Oracle XE 数据库与连接工具安装使用 O ...

  2. Oracle Database 快捷版 安装 连接

    Oracle Database 快捷版 11g 第 2 版 下载地址:http://www.oracle.com/technetwork/cn/database/database-technologi ...

  3. oracle 11g快捷版的安装与使用

    oracle 11g快捷版的安装与使用 [oracle 11g 下载地址(]https://www.oracle.com/technetwork/cn/database/enterprise-edit ...

  4. Oracle 数据库 Database Express Edition 11g Release 2 (11.2) 错误解决集锦(安装方面)

    前言:第一次接触数据库,想下载个oracle试玩下(虽然听说一般大企业才用),到 官网下载 了个简易版 XE 版本,安装时要注意记住自己输入的数据库密码(口令)  还有安装路径不能含有空格(Do no ...

  5. Oracle 数据库 Database Express Edition 11g Release 2 (11.2) 错误解决集锦(使用语法)

    ORA-14552: 在查询或 DML 中无法执行 DDL, 提交或回退 PL/SQL“ORA-14551:无法在查询中执行DML操作 解决:在声明函数时加上: PRAGMA AUTONOMOUS_T ...

  6. 《Oracle Database 12c DBA指南》第二章 - 安装Oracle和创建数据库(2.1 安装Oracle数据库软件和创建数据库概览)

    当前关于12c的中文资料比较少,本人将关于DBA的一部分官方文档翻译为中文,很多地方为了帮助中国网友看懂文章,没有按照原文句式翻译,翻译不足之处难免,望多多指正. 2.1 安装Oracle数据库软件和 ...

  7. Oracle 11g安装步骤以及Oracle11g创建表空间和用户,并授权

    Oracle 11g安装步骤详解 一.Oracle 下载 注意Oracle分成两个文件,下载完后,将两个文件解压到同一目录下即可. 路径名称中,最好不要出现中文,也不要出现空格等不规则字符. 官方下地 ...

  8. oracle 脚本创建数据库的相关文章,教程,源码

    学步园推荐专题: 关于oracle 脚本创建数据库的相关文章 文章标题 文章链接 文章简介 oracle命令行创建数据库的示例脚本 http://www.xuebuyuan.com/964527.ht ...

  9. Oracle Database 11g For Windows7 旗舰版的安装

    系统环境:win7 32位系统 安装步骤: 1,Oracle(甲骨文)官网下载适合自己的数据库安装包,下载地址http://www.oracle.com/technetwork/cn/indexes/ ...

随机推荐

  1. eclipse导入cordova创建的项目

    eclipse导入cordova创建的项目 看图不说话 run这个MainActivity就可以了,bin目录下会生成APK

  2. JS面向对象逆向学习法,让难理解的统统一边去(1)~

    对于面向对象我只能说呵呵了,为什么呢,因为没对象--- 既然你看到了这里,说明你有一定的基础,虽然本系列文章并不会过多的讲述基础部分,请做好心理准备. 本篇比较简单,这篇文章的意义是让你明白学习面向对 ...

  3. java 模拟qq源码

    java 模拟qq源码: http://files.cnblogs.com/files/hujunzheng/QQ--hjzgg.zip

  4. 轻松搭建Unity3D 安卓Android开发环境

    1,下载安装Java的JDK: http://www.oracle.com/technetwork/java/javase/downloads/index.html (JDK中,包含JRE) 如果是6 ...

  5. PHP面试出场率较高的题目<转载>

    --------------------PHP部分--------------------- PHP中几个输出函数echo,print(),print_r(),sprintf(),var_dump() ...

  6. 借助 CSS Colorguard 来避免使用重复的颜色

    每一个 CSS 项目开始时愿望都是很美好的,但不可避免地,多人协作的项目相互之间可能重复使用了相似的颜色,而你从来不知道它们的存在.CSS Colorguard 帮助您保持您想要的颜色设置,当你添加的 ...

  7. 【环境配置】Linux环境下下载、配置java环境、安装eclipse、建立eclipse快捷方式详解

    一.首先是下载Java JDK 到目前为止的最新版本为(jdk1.8.0_60),有两种方式进行下载: 1.使用shell来进行下载,可使用如下命令直接进行下载: wget --no-check-ce ...

  8. js每天进步一点点3

    JS之样式的改变

  9. Sql Server优化之索引提示----我们为什么需要查询提示,Sql Server默认情况下优化策略选择的不足

    环境: Sql Server2012 SP3企业版,Windows Server2008 标准版 问题由来: 最近在做DB优化的时候,发现一个存储过程有非常严重的性能问题, 由于整个SP整体逻辑是一个 ...

  10. 20个设计精致的用户界面 PSD 源文件免费下载

    今天这篇文章收集了20个新鲜出炉的用户界面 PSD 源文件素材,你可以免费下载使用.这些免费素材不仅能帮助设计师们节省大量的时间,而且能有很好的效果.感谢那些很有才华的设计师分享它们的劳动成果,让更多 ...