锘??xml version="1.0" encoding="utf-8" standalone="yes"?> ADO.NET鏄笓闂ㄤ負甯姪寮鍙戜漢鍛樺紑鍙戦珮鏁堢殑澶氬眰鏁版嵁搴撳簲鐢ㄧ▼搴忚璁$殑銆侫DO.NET瀵硅薄妯″瀷鍙垎涓轟袱綾伙細涓綾諱負鈥滆繛鎺ョ殑鈥濓紝涓綾諱負鈥滄柇寮榪炴帴鐨勨濆璞★紝鍚庤呭厑璁稿皢鏌ヨ緇撴灉淇濆瓨鍦ㄥ唴瀛樹腑榪涜澶勭悊銆?/P>
鈥濊繛鎺ョ殑鈥滃璞℃ā鍨嬮【鍚嶆濅箟錛屽畠鏄洿鎺ヤ笌鏁版嵁搴撹繘琛岃繛鎺ユ搷浣?鈥滄柇寮榪炴帴鈥濈殑瀵硅薄妯″瀷鍙互璇存槸寤虹珛鍦ㄢ滆繛鎺ョ殑鈥濆璞℃ā鍨嬬殑鍩虹涓婅繘琛岀殑錛屽洜涓哄畠蹇呴』鍏堣繘琛屼竴嬈♀滆繛鎺ョ殑鈥濇搷浣滐紝鎵嶈兘寰楀埌鎵闇鐨勭粨鏋溿?/P>
涓句釜渚?錛?nbsp; SqlConnection con=new SqlConnection("server=localhost;database=db,uid=sa,pwd=;"); SqlDataAdapter ad=new SqlDataAdapter("select * from table",con); DataSet ds=new Dataset(); ad.Fill(ds,"table"); //娉ㄦ剰榪欓噷宸茬粡灝嗕粠鏁版嵁搴撻噷鏌ヨ鍑烘潵鐨勭粨鏋滄斁鍒頒竴涓狣ataset瀵硅薄閲岋紝浠庢鍒誨紑濮嬶紝浣犲氨寮濮嬩嬌鐢ㄢ滄柇寮榪炴帴鈥濈殑瀵硅薄妯″瀷鏉ュ鏁版嵁搴撹繘琛屾搷浣滐紝DataSet瀵硅薄鏄竴涓湪鍐呭瓨涓殑鈥濊櫄鏁版嵁琛ㄢ滐紝浣犲彲浠ュ瀹冭繘琛屼換浣曟搷浣滆屼笉褰卞搷鏁版嵁搴擄紝鍙互瀵瑰畠榪涜鎺掑簭錛屼慨鏀癸紝鏌ヨ錛屽鍔狅紝鍒犻櫎銆傝屽鏋滀綘鎯蟲洿鏀規暟鎹簱鍐呭鐨勮瘽錛屼篃鍙互閫氳繃DataSet瀵硅薄鏉ユ搷浣滐紝寰堢畝鍗曪紝璋冪敤瀹冪殑update()鏂規硶鍗沖彲瀹屾垚鏇存柊鏁版嵁搴撱備篃鍙互浣跨敤瀹冪殑GetChanges()鏂規硶鏉ヨ幏鍙栧彧鏇存敼榪囩殑琛岋紝瀹冭繑鍥炰竴涓狣ataSet錛岃繖涓狣ataset涓嶅悓浜庤皟鐢℅etChanges()鏂規硶鐨勯偅涓紝榪斿洖鐨勮繖涓彧鏄畠鐨勪竴寮犲瓙琛紝涔熷氨鏄洿鏀硅繃鐨勬暟鎹紝鍒╃敤姝ゆ柟娉曞彲浠ュぇ澶у湴鎻愰珮澶氬眰ADO.NET搴旂敤紼嬪簭鐨勬ц兘銆侱ataSet綾昏繕鏈変竴涓狹erge鏂規硶鐢ㄦ潵鍚堝茍涓や釜DataSet瀵硅薄鐨勬暟鎹紝ADO.NET榛樿瑕嗙洊琚皟鐢∕erge()鏂規硶鐨凞ataSet涓殑琛屻?/P>
ADO.NET榪樻彁渚涗簡涓縐嶅己綾誨瀷鐨凞ATASET瀵硅薄錛氬畠鍙互甯姪浣犵畝鍖栧緩绔嬫暟鎹闂簲鐢ㄧ▼搴忕殑榪囩▼銆備緥濡傦細鏈変釜琛ㄥ彨table,鍏朵腑鏈変竴鍒楀彨column浣犲彲浠ヨ繖鏍鋒潵璁塊棶姝ゅ垪錛?/P>
vb.net: Dim ds as DataSet Console.WriteLine(ds.table(0).column); (table(0).琛ㄧずtable琛ㄤ腑鐨勭1琛岋級 c#: DataSet ds; Console.WriteLine(ds.table[0].column); (table[0].琛ㄧずtable琛ㄤ腑鐨勭1琛岋級 鏄笉鏄緢綆媧? ^_^ 鍏充簬DataSet閲岄潰榪樻湁濂藉涓滆タ鏂逛究鐢ㄥ錛欴ataTable,DataView,DataRow,DataColumn,DataRelation,Constraint涓澶у爢鐨勫ソ涓滆タ錛屽湪浠ュ悗鐨勬棩蹇椾腑浼氭彁鍒幫紒
http://www.cnblogs.com/William_Fire/articles/125819.html
http://www.cnblogs.com/william_fire/articles/126665.html
http://www.cnblogs.com/tintown/archive/2005/03/23/124395.html
http://www.cnblogs.com/tintown/category/12787.html
http://www.cnblogs.com/tintown/archive/2005/04/04/131784.html
http://www.cnblogs.com/tintown/archive/2005/04/04/131784.html?Pending=true#PostPost
http://www.cnblogs.com/tintown/archive/2005/04/07/132876.html
http://blog.sunmast.com/sunmast/articles/816.aspx
ADO.NET瀵硅薄妯″瀷錛?BR>http://www.phome.net/document/net/200504/net111246243813950.html
http://www.phome.net/document/net/200504/net111246243713949.html
http://www.phome.net/document/net/200504/net111246244913952.html
ADO.NET瀵硅薄妯″瀷
http://blog.csdn.net/jabby12/archive/2004/08/02/59221.aspx
鍙錛屽湪鍒嗗眰鐨勬椂鍊欙紝鎴戜滑浼氬鍔犱竴涓疄浣撳眰錛屽畠鐨勪綔鐢ㄥ涓嬶細
鈶?灝嗘樉紺烘暟鎹拰瀹為檯鐨勫瓨鍌ㄥ尯鍩熼殧紱伙紝淇濊瘉浜嗕笟鍔$殑鐙珛鎬э紝鎻愰珮浜嗗彲閲嶇敤鎬с?
鈶?鍦ㄤ笟鍔″眰鍜岃〃鐜板眰涔嬮棿浼犻掓暟鎹傦紙濡傛灉娌℃湁瀹炰綋灞傜殑璇濓紝鎴戜滑闇瑕佹妸琛ㄧ殑姣忎釜瀛楁浣滀負涓涓弬鏁板湪瀹冧滑涔嬮棿浼犻掞紝濡傛灉淇敼鐨勮瘽錛屽皢闇瑕佸獎鍝嶅埌紼嬪簭鐨勫悇涓眰錛?
鈶?鎻愪緵鏇村ぇ鐨勫彲鏀剁緝鎬с?
2錛?涓氬姟瀹炰綋灞傜殑鍑犵閫夋嫨鏂規鍙婂叾浼樼己鐐廣?
鍦?NET鐜涓嬪疄鐜頒笟鍔″疄浣撴湁涓嬮潰鐨勫嚑縐嶉夋嫨錛?
鈶?DataReader BE 鍏鋒湁鏈蹇殑璇誨彇閫熷害錛岀敤浜庡彧璇葷殑鍦哄悎錛屼笉鍏鋒湁OO鐨勬蹇點?
鈶?XML BE 鍙互涓嶺ML Reader鍜孌ataSet杞崲銆傜己鐐癸細鎬ц兘浣庯紝楠岃瘉銆佽В鏋愩佹樉紺恒佹帓搴忕瓑閮藉緢澶嶆潅銆?
鈶?Generic DataSet BE 浼樼偣錛氭暟鎹粦瀹氱瓑銆傜己鐐癸細瀹㈡埛绔繀欏婚氳繃闆嗗悎鏉ヨ幏鍙栨暟鎹紝娌℃湁綾誨瀷錛屽疄渚嬪寲寮閿澶э紝璋冨害鎬ц兘浣庛?
鈶?Typed DataSet BE 浼樼偣錛氱敱綾誨瀷錛屽彲浠ヨ繘琛岀被鍨嬫鏌ャ傜己鐐癸細鍙兘浠嶥ataSet緇ф壙錛岄儴緗蹭笉鏂逛究錛屽彲鎵╁睍鎬у樊錛屽疄渚嬪寲寮閿澶э紝璋冨害鎬ц兘浣庛?
鈶?Custom BE銆浼樼偣錛氭ц兘璋冧紭錛屼唬鐮佹洿鍏鋒湁鍙鎬э紝鐢ㄨ嚜瀹氫箟瀹炰綋綾誨畾涔変竴涓壇濂界殑鎺ュ彛錛屽皢澶嶆潅闂闅愯棌鍦ㄥ叾涓傜己鐐癸細璁捐寮鍙戦兘寰堝鏉傦紝闇瑕佽嚜宸卞幓瀹炵幇CURD鎿嶄綔錛岃嚜宸卞幓瀹炵幇鏁版嵁緇戝畾錛屽伐浣滈噺寰堝ぇ銆?
鈶?O/R Mapping鐨勫疄鐜?瀹冨叿鏈夎嚜瀹氫箟綾葷殑鎵鏈変紭鐐癸紝鍚屾椂瀹炵幇浜咰RUD錛屾暟鎹粦瀹氱瓑鎿嶄綔銆?
鍏充簬ObjectSpaces 鍜?U>llblgen
http://www.llblgen.com/defaultgeneric.aspx
http://www.sinzy.net/blog/Read.asp?ID=44&BID=931
http://www.csdn.net/develop/author/NetAuthor/sun2bin/
]]>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconworkingwithtypeddataset.asp
Implementing Data Transfer Object in .NET with a Typed DataSet
Version 1.0.0
GotDotNet community for collaboration on this pattern
Complete List of patterns & practices
Context
You are implementing a distributed application with the .NET Framework. The client application displays a form that requires making multiple calls to an ASP.NET Web service to satisfy a single user request. Based on performance measurements you have found that making multiple calls degrades application performance. To increase performance, you would like to retrieve all the data that the user request requires in a single call to the Web service.
Background
Note: The following is the same sample application that is described in Implementing Data Transfer Object in .NET with a DataSet.
The following is a simplified Web application that communicates with an ASP.NET Web service to deliver recording and track information to the user. The Web service in turn calls a database to provide the data that the client requests. The following sequence diagram depicts the interaction among the application, the Web service, and the database for a typical page.
Figure 1 illustrates the sequence of calls needed to fulfill the entire user request. The first call retrieves the recording information, and the second call retrieves the track information for the specified recording. In addition, the Web service must make separate calls to the database to retrieve the required information.
Database Schema
The schema that is used in the example shown in Figure 2 depicts a recording record that has a one-to-many relationship with a track record.
Implementing a DTO
One way to improve the performance of this user request is to package all the required data into a data transfer object (DTO) that can be sent with a single call to the Web service. This reduces the overhead associated with two separate calls and allows you to use a single connection with the database to retrieve both the recording and the track information. For a detailed description of how this improves performance, see the Data Transfer Object pattern.
Implementation Strategy
A typed DataSet is a generated subclass of System.Data.DataSet. You provide an XML schema file which is then used to generate a strongly-typed wrapper around the DataSet. The following two code samples illustrate the differences. The first sample is implemented with an ordinary DataSet:
DataTable dataTable = dataSet.Tables["recording"]; DataRow row = dataTable.Rows[0]; string artist = (string)row["artist"];
This sample indicates that you need to know the table and column names to access the tables and fields contained in the DataSet. You also have to know the return type of the Artist field to ensure that the correct cast is done. If you do not use the correct type, you will get a runtime error. The following is the same example implemented with a typed DataSet:
Recording recording = typedDataSet.Recordings[0]; string artist = recording.Artist;
This example demonstrates the benefits that the typed interface provides. You no longer have to refer to table or column by name and you do not have to know that the return type of the Artist column is a string. A typed DataSet defines a much more explicit interface that is verifiable at compile time instead of at runtime. In addition to the strongly-typed interface a typed DataSet also can be used in all places a DataSet can be used; therefore, it also can be used as a DTO. It is loaded in a similar fashion as a DataSet and it can be serialized to and from XML. In comparison to an ordinary DataSet you do have to write and maintain an XML schema that describes the typed interface. The Microsoft Visual Studio .NET development system provides a number of tools that simplify the creation and maintenance of the schema.The rest of this implementation strategy outlines the steps required in creating a typed DataSet for the sample application just described.
Creating a Typed DataSet
A typed DataSet is generated from an XML schema. Visual Studio .NET provides a drag-and-drop tool which automates the creation of the schema (see Figure 3) and the generation of the typed DataSet classes. If you do not use Visual Studio.NET, you can write the XML schema and use a command-line tool called XSD.exe to generate the typed DataSet. For detailed instructions on both of these methods, see "Typed DataSets in ADO.NET" from the May 2001 issue of .NET Developer [Wildermuth02].
RecordingDto.xsd
The following is the XML schema for the DTO to be used in this example. It combines both the recording table along with its associated track records in a single typed DataSet named RecordingDto:
<?xml version="1.0" encoding="utf-8" ?> <xs:schema id="RecordingDto" targetNamespace="http://msdn.microsoft.com/practices/RecordingDto.xsd" elementFormDefault="qualified" attributeFormDefault="qualified" xmlns="http://tempuri.org/RecordingDTO.xsd" xmlns:mstns="http://msdn.microsoft.com/practices/RecordingDto.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:codegen="urn:schemas-microsoft-com:xml-msprop"> <xs:element name="RecordingDto" msdata:IsDataSet="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="recording" codegen:typedName="Recording" codegen:typedPlural="Recordings" codegen:typedChildren="Track"> <xs:complexType> <xs:sequence> <xs:element name="id" type="xs:long" codegen:typedName="Id" /> <xs:element name="title" type="xs:string" codegen:typedName="Title" /> <xs:element name="artist" type="xs:string" codegen:typedName="Artist" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="track" codegen:typedName="Track" codegen:typedPlural="Tracks" codegen:typedParent="Recording"> <xs:complexType> <xs:sequence> <xs:element name="id" type="xs:long" codegen:typedName="Id" /> <xs:element name="title" type="xs:string" codegen:typedName="Title" /> <xs:element name="duration" type="xs:string" codegen:typedName="Duration" /> <xs:element name="recordingId" type="xs:long" codegen:typedName="RecordingId" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> <xs:unique name="RecordingDTOKey1" msdata:PrimaryKey="true"> <xs:selector xpath=".//mstns:recording" /> <xs:field xpath="mstns:id" /> </xs:unique> <xs:unique name="RecordingDTOKey2" msdata:PrimaryKey="true"> <xs:selector xpath=".//mstns:track" /> <xs:field xpath="mstns:id" /> </xs:unique> <xs:keyref name="recordingtrack" refer="mstns:RecordingDTOKey1"> <xs:selector xpath=".//mstns:track" /> <xs:field xpath="mstns:recordingId" /> </xs:keyref> </xs:element> </xs:schema>
This schema is not the exact file produced by Visual Studio .NET. It is annotated with a number of attributes that are prefixed from the codegen namespace. This modification is desirable because the code that is generated does not adhere to the .NET naming conventions. For example, without the modification, Visual Studio .NET would generate a track class that corresponds to the track table, whereas according to conventions used in the .NET Framework the class should be named Track. To change the name of the class that is generated, you must add the codegen:typedName attribute to the element definition in the XML schema:
<xs:element name="track" codegen:typedName="Track"> </element>
There are a number of other attributes besides codegen:typedName. For a detailed description of all the attributes, see "Typed DataSets in ADO.NET" from the May 2001 issue of .NET Developer [Wildermuth02].
Filling a Typed DataSet from the Database
The following code example demonstrates how to fill a typed DataSet with the data that the sample application requires. This includes the specific recording record and all of its associated track records. The difference between this code and filling an ordinary DataSet is that you do not need to explicitly define the relationship between the recording and track records.
Assembler.cs
Just as in Implementing a Data Transfer Object in .NET with a DataSet, an Assembler class maps the actual database calls into the typed DataSet:
using System; using System.Data; using System.Data.SqlClient; using Recording; public class Assembler { public static RecordingDto CreateRecordingDto(long id) { string selectCmd = String.Format( "select * from recording where id = {0}", id); SqlConnection myConnection = new SqlConnection( "server=(local);database=recordings;Trusted_Connection=yes;"); SqlDataAdapter myCommand = new SqlDataAdapter(selectCmd, myConnection); RecordingDto dto = new RecordingDto(); myCommand.Fill(dto, "recording"); String trackSelect = String.Format( "select * from Track where recordingId = {0} order by Id", id); SqlDataAdapter trackCommand = new SqlDataAdapter(trackSelect, myConnection); trackCommand.Fill(dto, "track"); return dto; } }
Note: The example shown here is not meant to describe the only way to fill the typed DataSet. There are many ways to retrieve this data from the database. For example, you could use a stored procedure.
Using a Typed DataSet in an ASP.NET Page
As mentioned previously, a typed DataSet inherits from System.Data.DataSet. This means that it can be substituted for a DataSet. For example, when using the .NET user interface controls (Web Forms or Windows Forms) a typed DataSet can be used in all places you could use a DataSet. The sample application page shown in the following code example uses two DataGrid controls, RecordingGrid and TrackGrid. You can use the typed DataSet, RecordingDto when setting the DataSource properties on the controls because a typed DataSet inherits from DataSet.
using System; using System.Data; using RecordingApplication.localhost; public class RetrieveForm : System.Web.UI.Page { private RecordingCatalog catalog = new RecordingCatalog(); // protected void Button1_Click(object sender, System.EventArgs e) { string stringId = TextBox1.Text; long id = Convert.ToInt64(stringId); RecordingDTO dto = catalog.Get(id); RecordingGrid.DataSource = dto.recording; RecordingGrid.DataBind(); TrackGrid.DataSource = dto.track; TrackGrid.DataBind(); } }
Tests
Because the typed DataSet is generated by tools in the .NET Framework, you do not need to write tests to verify that it functions correctly. In the following tests, you are testing that the Assembler class loaded the typed DataSet correctly.
AssemblerFixture.cs
using NUnit.Framework; using System.Data; using Recording; [TestFixture] public class AssemblerFixture { private RecordingDto dto; private RecordingDto.Recording recording; private RecordingDto.Track[] tracks; [SetUp] public void Init() { dto = Assembler.CreateRecordingDto(1234); recording = dto.Recordings[0]; tracks = recording.GetTracks(); } [Test] public void RecordingCount() { Assert.Equals(1, dto.Recordings.Rows.Count); } [Test] public void RecordingTitle() { Assert.Equals("Up", recording.Title.Trim()); } [Test] public void RecordingChild() { Assert.Equals(10, tracks.Length); foreach(RecordingDto.Track track in tracks) { Assert.Equals(recording.Id, track.RecordingId); } } [Test] public void TrackParent() { RecordingDto.Track track = tracks[0]; RecordingDto.Recording parent = track.Recording; Assert.Equals("Up", parent.Title.Trim()); } [Test] public void TrackContent() { RecordingDto.Track track = tracks[0]; Assert.Equals("Darkness", track.Title.Trim()); } [Test] public void InvalidRecording() { RecordingDto dto = Assembler.CreateRecordingDto(-1); Assert.Equals(0, dto.Recordings.Rows.Count); Assert.Equals(0, dto.Tracks.Rows.Count); } }
These tests describe how to access the individual elements of the DataSet. Because of the use of a typed DataSet, the test code does not require the actual column names and does not require the return type to be cast. Comparing these tests with the ones described in Implementing Data Transfer Object in .NET with a DataSet reveals the differences between using a strongly-typed interface and a generic interface. The strongly-typed interface is easier to use and understand. It also provides the added benefit of compile-time checking on return types.
Resulting Context
Implementing DTO with a typed DataSet shares a number of the same benefits and liabilities as implementing DTO with a DataSet; however, certain benefits and liabilities are unique to a typed-DataSet implementation.
Benefits
The typed DataSet shares the following benefits with a DataSet when used as a DTO:
Development tool support. Because the DataSet class is implemented in ADO.NET, there is no need to design and implement the DTO. There is also extensive support in Visual Studio for automating the creation and filling of DataSet and typed-DataSet objects.
Integration with controls. A DataSet works directly with the built-in controls in Windows Forms and Web Forms, making it a logical choice as a DTO.
Serialization. The DataSet comes complete with the ability to serialize itself into XML. Not only is the content serialized, but the schema for the content is also present in the serialization.
Disconnected database model. The DataSet represents a snapshot of the current contents of the database. This means that you can alter the contents of the DataSet and subsequently use the DataSet as the means to update the database.
An additional benefit that might persuade you to use a typed DataSet as opposed to an ordinary DataSet is the strongly-typed interface of the typed DataSet. A typed DataSet, as described here, generates classes that can be used to access the contained data. The classes present an interface which defines how the class is to be used in a more explicit manner. This removes the need for casting which was present in the DataSet implementation.
Liabilities
The typed DataSet shares the following liabilities with a DataSet when used in the context of a DTO:
Interoperability. Because the DataSet class is part of ADO.NET, it is not the best choice for a DTO in cases requiring interoperability with clients that are not running the .NET Framework.. You can still use DataSet, however, the client will be forced to parse the XML and build its own representation. If interoperability is a requirement, see Implementing Data Transfer Object in .NET with Serialized Objects.
Stale data. The typed DataSet, like a DataSet, is disconnected from the database. It is filled with a snapshot of the data in the database when it is constructed. This implies that the actual data in the database may be different from what is contained in the typed DataSet. For reading primarily static data, this is not a major issue. If the data is constantly changing, however, using any kind of DataSet is not recommended.
Potential for performance degradation. Instantiating and filling a DataSet can be an expensive operation. Serializing and deserializing a DataSet can also be very time consuming. A good rule of thumb for using a DataSet is that a DataSet is a good choice when you are using more than one table or relying on the capability of the DataSet to update the database. If you are displaying the results from a single table, then using a DataReader with strongly-typed objects may offer better performance. For more information, see Implementing Data Transfer Object in .NET with Serialized Objects.
The following are additional liabilities when using a typed DataSet as opposed to an ordinary DataSet:
A typed DataSet is still a DataSet. A typed DataSet can be substituted at runtime with a DataSet. This means that even though the strongly-typed interface exists, programmers can still access the data without the typed interface. A possible result of doing this is that there could be parts of the code which couple the application tightly to the DataSet table and column names.
The need for an XML schema. When using a typed DataSet you have to create and maintain an XML schema to describe the strongly-typed interface. Visual Studio .NET provides a number of tools to assist in this process, but nevertheless you still have to maintain an additional file.
Related Patterns
For more information, see the following related patterns:
Implementing Data Transfer Object in .NET with Serialized Objects.
Assembler. In Enterprise Application Architecture Patterns, Fowler defines Assembler as a specialized instance of the Mapper pattern [Fowler03].
Acknowledgments
[Beau02] Beauchemin, Bob. Essential ADO.NET. Addison-Wesley, 2002.
[Fowler03] Fowler, Martin. Enterprise Application Architecture Patterns. Addison-Wesley, 2003.
[Wildermuth01] Wildermuth, Shawn. "Typed DataSets in ADO.NET." .NET Developer. May 2001.
钂叉案杈?鍙戣〃浜?2005-3-30 8:26:00 |
鐗堟潈澹版槑錛氬彲浠ヤ換鎰忚漿杞斤紝杞澆鏃惰鍔″繀浠ヨ秴閾炬帴褰㈠紡鏍囨槑鏂囩珷鍘熷鍑哄鍜屼綔鑰呬俊鎭強鏈0鏄?BR>
http://www.chedong.com/tech/cms.html鍏抽敭璇嶏細"content manage system" cms 鍐呭綆$悊緋葷粺
鍐呭鎽樿錛?BR>
鍐呭綆$悊緋葷粺鏄竴涓緢娉涚殑姒傚康錛氫粠鍟嗕笟闂ㄦ埛緗戠珯鐨勬柊闂葷郴緇熷埌涓漢鐨刉eblog閮藉彲浠ョО浣滃彂甯冪郴緇熴?BR>
浣嗘棤璁哄浣曪紝鍦ㄥ彂甯冪郴緇熼夊瀷涔嬪墠錛岄鍏堜簡瑙h嚜宸辯殑瀹為檯闇姹傛槸鏈閲嶈鐨勶細鎯蟲牴鎹幇鎴愮郴緇熷皢鑷繁鐨勯渶姹傜‖寰涓婄収鎼槸闈炲父涓嶅彲鍙栫殑銆傝闂噺錛屾潈闄愭帶鍒跺拰鍚勭鍔熻兘闇姹傘傛瘡涓ā鍧楀拰鍔熻兘鑷繁閮芥瘮杈冩竻鏅頒竴鐐逛互鍚庯紝鍐嶅幓緗戜笂鎵炬壘綾諱技鐨勫疄鐜幫細浣犱細鍙戠幇鍏跺疄姣忎釜鐜妭鍒扮洰鍓嶄笂閮芥湁姣旇緝鎴愮啛鐨勫疄鐜頒簡錛岃屼笖榪樺湪涓嶆柇瀹屽杽鍜屽彂灞曚腑錛屽鏋滄病鏈夛細浣犵殑闇姹傚お鐗規畩錛屾垨鑰呭彲浠ュ皾璇曞垎瑙f垚鏇村皬鐨勭郴緇熺粍鍚堝疄鐜般?BR>
鍐呭綆$悊緋葷粺琚垎紱繪垚浠ヤ笅鍑犱釜灞傞潰錛氬悇涓眰闈紭鍏堣冭檻鐨勯渶姹備笉鍚?BR>
鍐呭綆$悊鍜岃〃鐜扮殑鍒嗙錛氬緢澶氭垚濂楃殑CMS緋葷粺娌℃湁鎶婂悗鍙板悇縐嶅瓙緋葷粺鍜孭ortal鍒嗙寮璁捐錛屼互鑷充簬鍦≒ortal灞傜殑妯℃澘琛ㄧ幇綆$悊鍜屾柊闂誨瓙緋葷粺鐨勫唴瀹圭鐞嗛昏緫娣峰悎鍦ㄤ竴璧鳳紝鐢氳嚦鍜孊BS絳夊瓙緋葷粺鐨勭鐞嗛兘鑰﹀悎鐨勯潪甯擱珮錛屾暣涓郴緇熶細鏄懼緱闈炲父搴炴潅銆傝屼笖榪欐牱鐨勭郴緇熷悇涓瓙緋葷粺鎹嗙粦鐨勬瘮杈冩錛屽鏋滃悗鍙扮殑妯″潡寰堥毦鏀瑰彉銆備絾鏄鏋滄妸鍚庡彴鍚勭瀛愮郴緇熷唴瀹圭鐞嗛昏緫鍜屽墠鍙扮殑琛ㄧ幇/鍙戝竷鍒嗙鍚庯紝Portal鍜屽悗鍙板悇涓瓙緋葷粺涔嬮棿鍙槸鏁版嵁浼犻掔殑鍏崇郴錛歅ortal鍙喅瀹氬悗鍙板悇涓瓙緋葷粺鏁版嵁鐨勫彇鑸嶅拰琛ㄧ幇錛岃屽悗鍙扮殑鍚勪釜瀛愮郴緇熶篃閮介潪甯稿鏄撴彃鎷斻?BR>
鍐呭綆$悊鍜屾暟鎹垎鍙戠殑鍒嗙錛氶渶瑕佽Portal緋葷粺璁捐鐨勬椂鍊欐敞鎰?/A>鍙紦瀛樻э紙Cache Friendly錛夋ц璁?/A>錛欳MS鍚庡彴綆$悊鍜屽彂甯冩満鍒訛紝鏈韓涓嶈榪囧鑰冭檻鈥滄晥鐜団濋棶棰橈紝鍙鏈緇堥〉闈㈣緭鍑鴻璁$殑姣旇緝Cacheable錛屾晥鐜囬棶棰樺彲閫氳繃鏇村墠绔笓闂ㄧ殑緙撳瓨鏈嶅姟鍣ㄨВ鍐熾?BR>
姝ゅ錛屽氨鏄櫎浜嗛潰鍚戞渶緇堟祻瑙堝櫒鐢ㄦ埛澶栵紝榪樿娉ㄦ剰闈㈠悜鎼滅儲寮曟搸鍙嬪ソ(Search engine Friendly)鐨刄RL璁捐錛氶氳繃URL REWRITE杞悜鎴栧熀浜嶱ATH_INFO鐨勫弬鏁拌В鏋愪嬌寰楀姩鎬佺綉欏靛湪閾炬帴錛圲RI錛夊艦寮忎笂鏇村儚闈欐佺殑鐩綍緇撴瀯錛屾柟渚跨綉绔欏唴瀹硅鎼滅儲寮曟搸鏀跺綍錛?BR>
--------------- --------------- ---------------
|鏂伴椈綆$悊瀛愮郴緇焲 | BBS璁哄潧瀛愮郴緇焲 | 鍟嗗煄瀛愮郴緇? |
--------------- --------------- ---------------
| \ / | \ / 鍐?
| ----------|--- \ / 瀹? <== 涓氬姟瀛愮郴緇燂紙闆朵歡鐢熶駭錛?BR> | / | \ \ / 綆?
--------------- | --------------- 鐞?
|涓撻鍒朵綔瀛愮郴緇焲 | |鍏ㄦ枃媯绱㈠瓙緋葷粺|
--------------- | ---------------
\ | /
-------------------------|---------------------------------------------
\ | / 棰?
--------------- 閬? <== Portal緋葷粺錛堜駭鍝佺粍瑁咃級
| Portal 緋葷粺 | 綆?
--------------- 鐞?
|
-------------------------|---------------------------------------------
| 鍓?
| 鍙? <== 鍙戝竷緋葷粺錛堝垎鍙戜唬鐞嗭級
--------------- 鍙?
|鍓嶅彴鍙戝竷緋葷粺 | 甯?
---------------
/ \
/ \
--------------- ---------------
| 鐢ㄦ埛嫻忚鍣? | |Search Engine|
--------------- ---------------
榪欓噷錛屾垜鎶婂湪鍐呭鍙戝竷緋葷粺閫夊瀷涓壘鍒扮殑涓浜涜祫鏂欐葷粨濡備笅錛?
鍏抽敭璇嶏細CMS Content Manage System
CMS琛屼笟鐮旂┒
CMS璁ㄨ閭歡鍒楄〃
鍟嗕笟杞歡鍜屽紑婧愰」鐩垪琛細
鎺ㄨ崘錛氬熀浜嶺ML鐨勫彂甯冩鏋?BR>
http://cocoon.apache.org/鍏蜂綋瀹炵幇澶嶆潅紼嬪害鍙兘浼氭牴鎹渶姹傜殑涓嶅悓鑰屼笉鍚岋紝浣嗚秺鏄ぇ鍨嬬殑緋葷粺瓚婃槸闇瑕佸垎宸ワ細灝嗗唴瀹癸紙鏁版嵁錛夛紝琛ㄧ幇錛堟ā鏉匡級鍜屽簲鐢ㄩ昏緫錛堢▼搴忥級灝藉彲鑳藉垎紱誨拰瀵硅繖3 鑰呯殑綆$悊銆?BR>
Portal---闂ㄦ埛緋葷粺
Open source Projects:
鍏抽敭璇嶏細ad server
騫垮憡緋葷粺鍜屽唴瀹圭殑鍒嗙錛屽彲浠ュぇ澶ч檷浣庣郴緇熶箣闂寸殑鍏寵仈搴︺?BR>
涓撲笟琛屼笟鐮旂┒緗戠珯錛?BR>
鎺ㄨ崘錛?BR>
http://www.phpadsnew.com/ 鍔熻兘鎬ф瘮杈冨己鍏抽敭璇嶏細 BBS FORUM
璁哄潧杞歡浠嬬粛錛?BR>
鍦ㄥ唴瀹圭殑褰曞叆綆$悊鏂歸潰錛屾墍瑙佸嵆鎵寰楁槸姣旇緝閲嶈鐨勶紝榪欐牱鍙互澶уぇ綆鍖栧緋葷粺涓竷灞鎺掔増鐨勯渶姹傘?BR>鍩轟簬嫻忚鍣ㄧ殑WYSIWYG錛堟墍瑙佸嵆鎵寰楋級緙栬緫鍣ㄦ槸CMS璁捐涓紝緙栬緫宸ュ叿鐨勪富瑕佽冭檻鏂歸潰銆傜洰鍓嶄富瑕佹槸閫氳繃JAVASCRIPT璋冪敤IE鎴栧叾浠栨祻瑙堝櫒鐨勫唴緗柟娉曞疄鐜般傚叾涓熀浜嶪E5.5嫻忚鍣ㄧ殑瀹炵幇鏈涓虹畝媧併傝繖閲屾湁涓涓畬鏁寸殑渚嬪瓙錛?BR>
Building a WYSIWYG HTML Editor Part 1/2閫夊瀷鎸囨爣錛?BR>
鍙鍖栫紪杈戝櫒澶у叏錛?BR>
http://www.bris.ac.uk/is/projects/cms/ttw/ttw.html鍥劇墖鍜屾枃浠剁瓑闈炵粨鏋勫寲鏁版嵁榪樻槸鍒嗗埆浣跨敤鍙﹀鐨勬湇鍔¤В鍐蟲瘮杈冨ソ銆傝繖鏍峰彲浠ュぇ澶х畝鍖朇MS鏈韓鐨勫鏉傜▼搴︺?BR>
鎺ㄨ崘錛?BR>鏂囦歡涓婁紶錛?BR>
褰撳墠FCKeditor瀵笽E鐨勬敮鎸佸緢濂斤紝涓嶈繃鍦∕ozilla Firefox涓笉鑳芥甯稿伐浣溿備粠瀹樻柟緗戠珯涓婂緱鍒扮殑娑堟伅琛ㄦ槑FCKeditor鐨勫紑鍙戝皬緇勬鍦ㄥ疄鐜板叾瀵筂ozilla鐨勬敮鎸併?BR>http://www.lividecay.org/doc_view.php?doc_id=1123
http://www.redsaga.com/mambo/content/view/12/2/
鍦╦sp涓嬩嬌鐢‵CKeditor鏄潪甯稿鏄撶殑錛?鍦‵CKeditor鐨勮〃涓甫鏈変竴涓湪JSP涓嬩嬌鐢═aglib錛岄氳繃璋冪敤榪欎釜taglib錛?寰堝鏄撲嬌鐢‵CKeditor錛?涓嬮潰灝辯畝鍗曡涓涓嬪畠鐨勪嬌鐢?BR>FCKeditor鍦‵uture浣跨敤鎸囧崡
toolbarSet鐨勫畾涔夋槸闈炲父瀹規槗鐨勶紝 鍦‵CKeditor涓敤鍒扮殑鎵鏈夊姛鑳芥寜閽鏄湁鍞竴鐨勫悕縐扮殑錛?榪欎釜鍚嶇О浣犲彲浠ュ湪FCKeditor甯姪鏂囦歡鎴栬?fckeditor/js/fck_config.js涓畾涔夌殑Default toolbarSet涓壘鍒?
1.2
http://www.freetextbox.com/ 涓嶈繃濂藉儚涓嶆敮鎸乯sp鍟?BR>
Javascript瀹炵幇鐨?BR>http://tinymce.moxiecode.com/
2.
涓涓湪綰垮瓧鍏?
http://livid.3322.org/lividict/livid.html
3.
寮婧愮殑鍩轟簬php鐨勯」鐩細
http://xoops.org.cn/modules/wfdownloads/singlefile.php?cid=4&lid=222
http://xoops.org.cn/modules/wfdownloads/topten.php?list=hit
4.
http://forum.javaeye.com/viewtopic.php?t=2047&highlight=cvs
http://forum.javaeye.com/viewtopic.php?t=8360&highlight=cvs
http://sourceforge.net/cvs/?group_id=94626
5.
http://www.blog.edu.cn/blog.asp?name=yonghui
http://www.magnolia.info/en/community.html
6.
http://duduwolf.winzheng.com/
http://www.bris.ac.uk/is/projects/cms/ttw/ttw.html
http://www.aine.be/aynhtml/
6.
http://www.jdsl.org/
http://www.cmswiki.com/tiki-index.php?page=JSR170
http://jsr170tools.day.com/crx/index.jsp
7.
欏圭洰綆$悊錛?BR>http://www.codeproject.com/tools/ToDoList2.asp
http://www.moon-soft.com/doc/45036.htm
http://www.moon-soft.com/doc/45036.htm
http://www.neokeen.com/mornlee/2005/02/23/1109168404234.html
http://cosoft.org.cn/forum/forum.php?forum_id=6559
http://blog.csdn.net/kasam/archive/2004/12/30/234644.aspx
http://www.redsoftfactory.com/chinese/opensource/opensource.html
http://forum.javaeye.com/viewtopic.php?t=2300
http://forum.javaeye.com/viewtopic.php?t=8360
8銆?BR>
http://java-source.net/open-source/content-managment-systems