Monday, December 31, 2012

User: Manage, Profile in ASP.NET, visual studio 2008, sql server 2005

User: Manage, Profile in ASP.NET, visual studio 2008, sql server 2005
[youtube=http://youtu.be/Qt0B7poAsjg]

Wednesday, December 26, 2012

Hướng dẫn tạo trang giỏ hàng đơn giản với jsp

Chúng ta cùng nhau xây dựng chức năng giỏ hàng một cách đơn giản nhất trong jsp như sau:

[caption id="attachment_859" align="alignnone" width="300"]Trang chọn sản phẩm Trang chọn sản phẩm[/caption]

Sau khi chọn sản phẩm sẽ chuyển sang trang giỏ hàng

[caption id="attachment_860" align="alignnone" width="300"]Giỏ hàng Giỏ hàng[/caption]

Các bạn có thể tham khảo bên dưới

Trang sản phẩm
[sourcecode language="html"]
<%--
Document : index
Created on : Dec 25, 2012, 3:08:22 PM
Author : Ngo Tuong Dan
--%>

<%@page import="java.util.ArrayList"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
h1
{
color: yellowgreen;
font-style: italic;
}
div
{
margin-left: auto;
margin-right: auto;
width: 300px;
}
input[type=text]
{
width:150px;
text-align:left;
border:thin solid gray;
padding: 2px 5px 2px 5px;
border-radius: 3px 3px 3px 3px;
}
input[type=submit]
{
width:75px;
text-align:center;
border:thin solid gray;
padding: 3px 5px 3px 5px;
border-radius: 3px 3px 3px 3px;
background-color: orange;
}
input[type=submit]:hover
{
width:75px;
text-align:center;
border:thin solid gray;
padding: 3px 5px 3px 5px;
border-radius: 3px 3px 3px 3px;
background-color: yellowgreen;
}
</style>

<title>JSP Page</title>
</head>
<body>
<div>
<h1>Shopping card demo</h1>
<%
if (request.getParameter("btnOK") != null) {
codes.item item = new codes.item();

item.setId(Integer.parseInt(request.getParameter("txtID")));
item.setPrice(Integer.parseInt(request.getParameter("txtPrice")));
item.setQuantity(Integer.parseInt(request.getParameter("txtQuantity")));
java.util.ArrayList orders = new ArrayList();
if (session.getAttribute("Orders") != null) {
orders = ((java.util.ArrayList) session.getAttribute("Orders"));
}
orders.add(item);
session.setAttribute("Orders", orders);

response.sendRedirect("list.jsp");
}
%>

<form method="post">
<table>
<tr>
<td>
ID</td>
<td>
<input type="text" name="txtID" />
</td>
</tr>
<tr>
<td>
Price
</td>
<td>
<input type="text" name="txtPrice"/>
</td>
</tr>
<tr>
<td>
Quantity
</td>
<td>
<input type="text" name="txtQuantity"/>
</td>
</tr>
<tr>
<td>
</td>
<td>
<input type="submit"value="OK" name="btnOK"/>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>

[/sourcecode]

Trang giỏ hàng

[sourcecode language="html"]
<%@page import="java.util.ArrayList"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>JSP Page</title>
<style>
h1
{
color: yellowgreen;
font-style: italic;
}
div
{
margin-left: auto;
margin-right: auto;
width: 300px;
}

table
{
border: 1px solid gray;
padding: 3px 3px 3px 3px;
}

th
{
color: brown;
}
.back
{
width:75px;
text-align:center;
border:thin solid gray;
padding: 2px 5px 2px 5px;
border-radius: 3px 3px 3px 3px;
background-color: orange;
}
.back:hover
{
width:75px;
text-align:center;
border:thin solid gray;
padding: 3px 5px 3px 5px;
border-radius: 3px 3px 3px 3px;
background-color: yellowgreen;
}
</style>
</head>
<body>
<div>
<h1>Your card</h1>
<table>
<tr>
<th>ID</th>
<th>Price</th>
<th>Quantity</th>
<th>Total</th>
<th>Operator</th>
</tr>
<%
java.util.ArrayList orders = new ArrayList();
codes.item item = new codes.item();
if (session.getAttribute("Orders") != null) {
orders = ((java.util.ArrayList) session.getAttribute("Orders"));
}

int count = orders.size() - 1;
while (count > 0) {
item = (codes.item) orders.get(count);

if (request.getParameter("id") != null) {
if (item.getId() == Integer.parseInt(request.getParameter("id"))) {
orders.remove(item);
count--;
continue;
}
}

out.print("<tr>");
out.print("<td>" + item.getId() + "</td>");
out.print("<td>" + item.getPrice() + "</td>");
out.print("<td>" + item.getQuantity() + "</td>");
out.print("<td>" + item.getQuantity() * item.getPrice() + "</td>");
out.print("<td> <a href='?id=" + item.getId() + "'>Delete</a></td>");
count--;
out.print("</tr>");
}
%>
</table>
<br/>
<a class="back" href="index.jsp">continue</a>
</div>
</body>
</html>
[/sourcecode]

JSP Expression language with static function

http://youtu.be/PnCEZrbnb8I

JSP Expression language with static function

Saturday, December 22, 2012

Java script

Một ví dụ nho nhỏ

js

[sourcecode language="html"]
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Java script</title>
<style>
input[type=text]
{
width:50px;
text-align:center;
border:thin solid gray;
padding: 2px 5px 2px 5px;
border-radius: 3px 3px 3px 3px;
}
#result
{
width:60px;
background:#33CC66;
color: #FFFFFF;
font-weight:bold;
}

</style>
<script>
function show()
{
var f = document.getElementById("f");
var s = document.getElementById("s");
var r = document.getElementById("result");

r.value = new Number(f.value) + new Number(s.value);
}
</script>
</head>
<body>
<input type="text" id="f" onkeyup="show();"/>+<input type="text" id="s" onkeyup="show();"/>
<input type="text" id="result" readonly="true" />
</body>
</html>

[/sourcecode]

Friday, December 21, 2012

Sử dụng builtin attribute và tạo attribute mới trong C#

[sourcecode language="csharp"]
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Reflection;

namespace ACS_Lab01
{
class Program
{
DateTime date = DateTime.Now;

/// <summary>
/// Tach ham tu thu vien he thong
/// </summary>
/// <param name="c"></param>
/// <param name="text">Noi dung hien thi</param>
/// <param name="caption">Tieu de hop thoai</param>
/// <param name="type">Kieu hop thoai</param>
/// <returns></returns>
[DllImport("User32.dll")]
public static extern int MessageBox(int c, string text, string caption, int type);

static void Main(string[] args)
{
Program objPro = new Program();
objPro.add(3, 5);

Console.WriteLine("*****************************************");
// doc thong tin cac phuong thuc cua lop program
MethodInfo[] methods = typeof(Program).GetMethods();
object[] attributes = null;
for (int i = 0, l = methods.GetLength(0); i < l; i++)
{
MethodInfo mi = methods[i];
// chi lay ve cac custom attribute
attributes = mi.GetCustomAttributes(true);
foreach (Attribute attribute in attributes)
{
if (attribute is Author)
{
Console.WriteLine("Thong tin lien quan phuong thuc " + mi.Name);
Author author = (Author)attribute;
System.Console.WriteLine("Ten tac gia: {0} ,ghi chu: {1} , tao vao : {2}", author.FullName, author.Comment, author.CreateDate.ToShortDateString());
}
}
}

Console.ReadLine();
}

// [Obsolete("Do not use this method")]
[Conditional("DEBUG")]
public void add(int a, int b)
{
Console.WriteLine("Ket qua: " + (a + b));

MessageBox(0, "Ket qua: " + (a + b), "Thong tin", 0);
}

[Author("Nguyen Van Mit", "Very easy")]
[Author("Tran Thi Chom Chom", "Sai giai thuat")]
public int Add(int a, int b)
{
return a + b;
}
}
}
[/sourcecode]

Author attribute
[sourcecode language="csharp"]
using System;
using System.Collections.Generic;
using System.Text;

namespace ACS_Lab01
{
/// <summary>
///
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple=true)]
class Author: System.Attribute
{
/// <summary>
/// Ham khoi tao su dung de cung cap thong tin cho cac thuoc tinh
/// </summary>
/// He ten tac gia
/// Ngay tao ra
public Author(string FullName, string Comment)
{
this.FullName = FullName;
this.CreateDate = DateTime.Now;
this.Comment = Comment;
}

private string _comment;
/// <summary>
/// Ghi chu
/// </summary>
public string Comment
{
get { return _comment; }
set { _comment = value; }
}


private string _name;
/// <summary>
/// Ho ten tac gia
/// </summary>
public string FullName
{
get { return _name; }
set { _name = value; }
}

private DateTime _create;
/// <summary>
/// Ngay toa ra
/// </summary>
public DateTime CreateDate
{
get { return _create; }
set { _create = value; }
}

}
}
[/sourcecode]

Nếu cần demo ban gửi mail cho tôi

Sunday, December 16, 2012

Video hướng dẫn từng bước xây dựng ứng dựng với C# SqlServer

Do một số bạn không có điều kiện đến lớp tôi sẽ post một loạt video hướng dẫn xây dựng một ứng dụng quản lý đơn giản nhằm giúp các bạn ôn tập tốt hơn môn học Window form with C# chương trình ACCP.

Nội dung môn học WFC#

  1. Thiết kế giao diện từ Session 01 ->06

  2. Thao tác với CSDL Session 07-10

  3. Nhóm bài hỗ trợ


Xây dựng phần mềm quản lý hồ sơ sinh viên

-         SinhVien(masv, hoten, ngay,gioitinh)

-         DiemDanh(masv,ngayhoc,vang)

Yêu cầu chức năng

-         Viết CT tạo sinh viên mới

-         Tìm sinh viên theo mã số

-         Hiển thị ds sinh viên (edit,delete)

-         Điểm danh theo sinh viên tham gia lớp học theo từng ngày

-         Báo cáo:

  • In ra ds sinh viên

  • Thống kê tỉ lệ tham gia lớp học của sinh viên

  • Đóng gói, triển khai và cập nhật phần mềm thông qua hệ thống mạng


Tôi sẽ sớm upload để các bạn tham khảo.

Tổng quan và giao diện

http://www.youtube.com/watch?v=OYV9xsZSFgA

Giao diện

http://www.youtube.com/watch?v=0upGEc3Ij1k

Kết nối dữ liệu

http://www.youtube.com/watch?v=kG3qahrmhOU
Đọc dữ liệu

http://www.youtube.com/watch?v=YMZ5gYc9g3o

Thao tác dữ liệu

http://www.youtube.com/watch?v=S778YynB308
Báo cáo

http://www.youtube.com/watch?v=WSYD-XUr1a8

Đóng gói

http://www.youtube.com/watch?v=XgNE9zkCjog

Custom control

http://www.youtube.com/watch?v=6isPeiXcFx4

Login

http://www.youtube.com/watch?v=p4T5UmUvGD8

Các bạn tham khảo nguồn tại đây.

Sunday, December 9, 2012

Wednesday, December 5, 2012

Xử lý ngoại lệ trong dịch vụ web



Service with name “Accounting” have some API as:



  1. Create_Account(string id, string pin,string fullname,datetime createdate)

  2. View_Detail(string id)

  3. Delete_Account(string id) only call by authenticated user with admin permission


----------------------------------------------------------------------------------------------------------------------------

  1. Create webservice

    1. Define all necessary API for it

    2. Using SoapHeader to config using condition of these above API

    3. Using SoapException to raise and handle error on server also at the client

    4. Create webservice client

      1. ASP.Net website as client






i.      AddWebReferrences

ii.      Create object proxy

iii.      Call service API with SoapHeader

iv.      Handle exceptions

  1. Window form as client same as above


http://youtu.be/BEwhsBMHDaM

Xử lý ngoại lệ trong dịch vụ web

VIdeo Exception handling in webservice with asp.net VS 2008 ACCPi10

[youtube=http://youtu.be/7ALn-kPEMf0]

Exception handling in webservice with asp.net VS 2008

Tuesday, December 4, 2012

Metro JS

Xây dựng web mang bóng dáng metro với JQuery
JSMetro
Metro JS is a JavaScript plugin for jQuery developed to easily enable Metro interfaces on the web. This release focuses on Live Tiles, the Application Bar and Theming. It's early in the development phase, but all features should work on at least IE7+(Win/WinPhone), Firefox, Chrome, Android, Opera, and Safari(OSX/iOS).
Want to make a 'Me' tile or a 'People' tile like you see on Windows Phone for your website? Metro JS makes it easy!

Với thư viện này việc xây dựng web với giao diện metro rất nhanh chóng.

Tuesday, November 27, 2012

Chuyển đổi hình thành chuỗi và ngược lại (IMAGE TO BASE64 STRING and BASE64 STRING TO IMAGE)

Image to Base64 String


[sourcecode language="CSharp"]
public string ImageToBase64(Image image, System.Drawing.Imaging.ImageFormat format)
{
using (MemoryStream ms = new MemoryStream())
{
// Convert Image to byte[]
image.Save(ms, format);
byte[] imageBytes = ms.ToArray();

// Convert byte[] to Base64 String
string base64String = Convert.ToBase64String(imageBytes);
return base64String;
}
}
[/sourcecode]

Base64 String to Image


[sourcecode language="CSharp"]
public Image Base64ToImage(string base64String) {
// Convert Base64 String to byte[] byte[]
imageBytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
return image;
}
[/sourcecode]

Friday, November 23, 2012

Hướng dẫn tạo và sử dụng webservice với asp.net

http://youtu.be/gkRv24Ma4YA

Hướng dẫn tạo và sử dụng webservice với asp.net
VS 2008

Thursday, November 15, 2012

Hướng dẫn tạo ứng dụng JMS với Netbean 5.5 Sun App

Trong video này chúng ta cùng thực hiện xây dựng một ứng dụng JMS đơn giản.





Thursday, November 1, 2012

CMR – Container Managed Relationships trong EJB 2.1

Mục đích của chủ đề này mô tả khái niệm CMR giữa các Entity Bean trong mô hình EJB và qui tắc cài đặt CMR

Chủ đề này đòi hỏi bạn phải nắm vững được khái niệm entity bean, CMP và quan hệ trong CSDL

Định nghĩa

  • CMR cho phép các entity bean liên hệ qua lại với nhau tương tự như relationship được cài đặt trong các công cụ quản lý CSDL quan hệ (DBMS)
  • CMR thể hiện mối quan hệ giữa các đối tượng thông qua các thuộc tính của hai hay nhiều entity bean nhằm đảm bảo toàn vẹn dữ liệu khi thao tác
  • Ngoài ra, CMR được dùng để thao tác, xử lý, cập nhật, tổng hợp dữ liệu trên nhiều entity bean. EJB Container sẽ quản lý quan hệ giữa các thành phần bean
  • CMR được áp dụng trên các entity bean được vận dụng với CMP và CMR thể hiện mối quan hệ giữa các CMP thông qua tập tin mô tả cài đặt – deployment descriptor (ejb-jar.xml)
  • CMR hỗ trợ 3 loại quan hệ
    • one-to-one(1-1): 1 instance bean quan hệ với duy nhất 1 instance bean
      • Ví dụ: Con người và địa chỉ nhà tại một thời điểm
    • one-to-many(1-n): 1 instance bean quan hệ với nhiều instance bean khác có liên quan
      • Ví dụ: Khách hàng và Hóa đơn
    • many-to-many(m-n): nhiều instance bean quan hệ với nhiều instance bean khác
      • Ví dụ: Người sử dụng (User) và Phân quyền sử dụng (Roles)
  • Đặc biệt CMR còn qui định hướng truy xuất dữ liệu trên các thành phần instance bean dựa trên các thành phần quan hệ đã nêu trên
    • Unidirectional: dữ liệu tổng hợp trên một tập hợp instance bean chỉ được xác định theo duy nhất 1 chiều trong quan hệ
      • Ví dụ:
        • Chúng ta có quan hệ giữa Hóa đơn và Khách hàng.
        • Chúng ta phát biểu một Khách hàng sẽ có nhiều Hóa đơn và một Hóa đơn chỉ của một Khách hàng. Do vậy, đây là mối quan hệ 1 – n theo hai object Khách hàng và Hóa đơn
        • Theo qui tắc cài đặt của một số công cụ hỗ trợ cài đặt CSDL, chúng ta thường đặt khóa chính của bảng 1 vào trong bảng nhiều để làm khóa ngoại
        • Ở đây, chúng ta sẽ thấy rằng Hóa đơn sẽ chứa thông tin của Khách hàng (đó là khóa chính của bảng Khách hàng).
        • Câu hỏi đặt ra rằng nếu chúng ta che bảng Hóa đơn và hỏi rằng Khách hàng này có bao nhiêu hóa đơn? Câu trả lời sẽ là không thể truy vấn.
        • Nhưng ngược lại chúng ta che bảng Khách hàng và đặt câu hỏi Hóa đơn của Khách hàng nào? Câu trả lời của chúng ta sẽ lấy được ít nhất thông tin là mã số của Khách hàng
        • Ví dụ trên đã mô tả việc lấy dữ liệu tổng hợp trên mối quan hệ Khách hàng và Hóa đơn thì chúng ta chỉ thể lấy thông tin tổng quát đầy đủ chỉ trên hướng Hóa đơn. Đây chính là dạng truy xuất 1 chiều
    • Bi-directional: dữ liệu tổng hợp trên một tập hợp instance bean được xác định theo cả 2 hướng trong quan hệ
      • Từ ví dụ của Unidirectional, chúng ta muốn truy vấn dữ liệu trên cả 02 chiều thì Bi-directional hướng tới là chúng ta có thể truy cập dữ liệu tổng hợp từ một instance bean bất kỳ trong mối quan hệ
      • Ý tưởng này theo nghĩa bảng Khách hàng phải chứa tập mã số hóa đơn để chúng ta có thể truy vấn thông tin của instance bean còn lại mà không cần phải xác định là phải đứng trên scope của instance bất kỳ
    • Kết hợp với mối quan hệ và định hướng dữ liệu, CMR đưa ra các loại quan hệ cụ thể như sau
      • One-to-one, unidirectional
        • 01 bảng chứa đựng khóa ngoại của bảng khác
        • Chỉ có 01 bean chứa đựng phương thức abstract getter and setter dùng để lấy thông tin của bean khác trong quan hệ
      • One-to-one, bidirectional
        • Cả 02 bảng chứa đựng khóa ngoại của nhau
        • Cả 02 bean chứa đựng phương thức abstract getter and setter dùng để lấy thông tin lẫn nhau trong quan hệ
      • One-to-many, unidirectional
        • Thực hiện lấy thông tin dựa trên một tập khóa ngoại trên bảng quan hệ 1
        • Sử dụng kiểu dữ liệu java.util.Collection or java.util.Set cho việc lưu trữ tập khóa ngoại
      • One-to-many, bidirectional
        • Trên bean quan hệ 1 chứa tập khóa ngoại của bean quan hệ nhiều, bean quan hệ nhiều chỉ chứa duy nhất instance bean của quan hệ 1
        • Sử dụng kiểu dữ liệu java.util.Collection or java.util.Set cho việc lưu trữ tập khóa ngoại
      • Many-to-many, unidirectional
        • Tập khóa ngoại giữa 02 bean chỉ tồn tại trên duy nhất 1 bean
        • Sử dụng bảng liên kết (link table) giữa 02 bean – bảng này sẽ được thể hiện trong deployment descriptor
      • Many-to-many, bidirectional
        • Cả 02 bean đều chứa tập khóa ngoại của đối tượng bean còn lại
        • Sử dụng bảng liên kết (link table) giữa 02 bean – bảng này sẽ được thể hiện trong deployment descriptor
      • Quan hệ many-to-many là dạng kết hợp giữa many-to-one và one-to-many
  • CMR hỗ trợ việc đảm bảo toàn vẹn tham chiếu (Referential Integrity)
    • Đảm bảo mối quan hệ về giữa 02 của đối tượng instance bean không bị phá vỡ khi một entity bean được thêm (insert) hay xóa hay cập nhật tương tự như cách bỏ khóa chính sang bảng nhiều để làm khóa ngoại trong 1 số công cụ quản lý CSDL (DBMS)
    • Cơ chế này được đảm bảo thực hiện bởi EJB Container
  • CMR cũng hỗ trợ việc xóa dữ liệu và instance trên bộ nhớ liên hoàn (cascade Delete and Remove). Vấn đề này hướng tới chúng ta có thể hủy toàn bộ dữ liệu trên các instance object quan hệ
  • Mối quan hệ của các đối tượng trong CMR được thể hiện thông qua “abstract persistence schema”
    • abstract persistence schema chứa các thông tin liên quan đến việc ánh xạ giữa thuộc tính trong instance và cột dữ liệu trong bảng của CSDL
    • abstract persistence scheme có thể được xem là cấu trúc hình dạng tương tự như table và các ràng buộc về quan hệ bên dưới CSDL
    • abstract persistence schema được mô tả trong xml file mô tả thông tin cấu hình ejb-jar.xml
    • Mọi thao tác của EJB container trên các instance bean là thực hiện trên abstract persistent schema, không phải trên table hay ràng buộc cụ thể dưới CSDL
      • Việc thao tác và truy vấn dữ liệu trên bean dựa trên thuộc tính của bean và các tập dữ liệu quan hệ không phải column hay field hay constraint dưới CSDL
      • Các property khi được truy cập phải xác định rõ ràng property của instance bean cụ thể nào theo đúng khái niệm lập trình hướng đối tượng
      • Ngôn ngữ truy vấn cho các đối tượng dựa trên ngôn ngữ OQL – Object Query Language không phải SQL

Qui tắc cài đặt CMR

  • Tất cả các component interface (remote và local interface), home interface (home interface và local home interface) tương tự như CMP
  • Implement trên bean class
    • Xác định field quan hệ trên cả 02 entity bean liên kết
    • Khai báo thêm 02 phương thức abstract get và set của field quan hệ theo qui luật liên kết
      • 1:n – phương thức get và set có kiểu trả về và tham số truyền của đối tượng 1 là kiểu tập hợp: đối tượng n là kiểu component interface của đối tượng 1.
      • n:n – phương thức get và set có kiểu trả về và tham số truyền của cả 02 đối tượng là kiểu tập hợp.
      • 1:1’ – phương thức get và set có kiểu trả về và tham số truyền của đối tượng 1 là component interface của đối tượng 1’ và ngược lại.
  • Thể hiện ràng buộc giữa các entity bean thông qua deployment descriptor
    • ejb-jar.xml

<relationships>

<ejb-relation>

<ejb-relation-name>tên quan hệ</ejb-relation-name>

<ejb-relationship-role>

<ejb-relationship-role-name>tên role</ejb-relationship-role-name>

<multiplicity>One/Many</multiplicity>

<relationship-role-source>

<ejb-name>tên tham chiếu</ejb-name>

</relationship-role-source>

<cmr-field>

<cmr-field-name>tên đối tượng</cmr-field-name>

<cmr-field-type>loại dữ liệu</cmr-field-type>

</cmr-field>

</ejb-relationship-role>

<ejb-relationship-role>

<ejb-relationship-role-name>tênquanhệ1</ejb-relationship-role-name>

<multiplicity>Many/One</multiplicity>

<cascade-delete/>

<relationship-role-source>

<ejb-name>tên tham chiếu</ejb-name>

</relationship-role-source>

<cmr-field>

<cmr-field-name>tên field khóa ngoại</cmr-field-name>

</cmr-field>

</ejb-relationship-role>

</ejb-relation>

</relationships>

jbosscmp-jdbc.xml : bổ sung thêm vào phần relationship descriptor như sau (nội dung này sẽ được thể hiện rõ trong các tutorial tiếp theo chủ đề này)

<relationships>

<ejb-relation>

<ejb-relation-name>tên quan hệ</ejb-relation-name>

<ejb-relationship-role>

<ejb-relationship-role-name>tên quan hệ</ejb-relationship-role-name>

<key-fields>

<key-field>

<field-name>field class làm khóa ngoại</field-name>

<column-name>fieldtablethamchiếukhóangoại</column-name>

</key-field>

</key-fields>

</ejb-relationship-role>

<ejb-relationship-role>

<ejb-relationship-role-name>tên quan hệ</ejb-relationship-role-name>

<key-fields/>

</ejb-relationship-role>

</ejb-relation>

</relationships>

Lưu ý: implement tập tin jbosscmp-jdbc.xml tuân theo qui luật

1:n – xác định element field-name là tên field là khóa chính của đối tượng 1.

n:n – xác định bảng trung gian và áp dụng như đối tượng 1:n

<relation-table-mapping>

<table-name>tên bảng trung gian</table-name>

</relation-table-mapping>

1:1 xác định element field-name tương ứng tên field khóa chính của từng đối tượng

Trên đây là một số nội dung khái niệm cơ bản về CMR.

Hướng dẫn tạo EJB - CMP

http://youtu.be/aYm7_Udq1aY

Hướng dẫn tạo một ứng dụng đơn giản nhất bằng EJB với CMP

Friday, October 12, 2012

Tài liệu PHP tham khảo

Hi đây là tài liệu PHP và MySql khá hay tôi share ra đây để mọi người tham khảo nhé.

PHP and MySQL Web Development 4th Edition

Tuesday, October 9, 2012

RMI - ví dụ tạo ứng dụng phân tán đơn giản

Create RMI Application




  1. Create Remote Interface

  2. Create Remote Object

  3. Implement the Remote Interface

  4. Built RMI Server

  5. Built RMI Client


Step I.               Create Java Application

Create the Java application with name RMI.

Create Remote Interface

[sourcecode language="csharp"]

/*Create Remote Interface
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
*
* @author Administrator
*/
public interface WeatherInterface extends Remote{
public Weather getWeather() throws RemoteException;
}
[/sourcecode]

Step II.            Create Remote Object

[sourcecode language="csharp"]
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package rmi;

import java.io.Serializable;

/**
*
* @author Administrator
*/
public class Weather implements Serializable{

private String name = "";
private float temperature = 0.0F;

/**
* @return the name
*/
public String getName() {
return name;
}

/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}

/**
* @return the degree
*/
public float getTemperature() {
return temperature;
}

/**
* @param degree the degree to set
*/
public void setTemperature(float temperature) {
this.temperature = temperature;
}

public Weather() {
name = "NoCity";
temperature = 0.0F;
}
}
[/sourcecode]

Step III.         Implement the Remote Interface

[sourcecode language="csharp"]
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
*
* @author Administrator
*/
public class WeatherImpl extends UnicastRemoteObject implements WeatherInterface{

Weather weather;

public WeatherImpl(Weather weatherObj) throws RemoteException
{
super();
this.weather = weatherObj;
}

public Weather getWeather() throws RemoteException {
return weather;
}

}
[/sourcecode]

Step IV.          Built RMI Server

When click on Start server

[sourcecode language="csharp"]
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
weather = new Weather();
weather.setName("Can Tho");
weather.setTemperature(50.5F);
try {
weatherImpl = new WeatherImpl(weather);
LocateRegistry.createRegistry(5000);
Naming.rebind("rmi://localhost:5000/WeatherServer",weatherImpl);
JOptionPane.showMessageDialog(this, "Server started");
jButton1.setEnabled(false);
jButton2.setEnabled(true);
} catch (Exception ex) {
ex.printStackTrace();
}
}
[/sourcecode]


When click on  Update

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                        

        // TODO add your handling code here:

        weather.setName(jTextField1.getText());

        weather.setTemperature(Float.parseFloat(jTextField2.getText()));

    }

Step V.             Built RMI Client

When click on Get weather

[sourcecode language="csharp"]
Weather weather;
WeatherInterface weatherInter;
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
try {
weatherInter = (WeatherInterface)Naming.lookup("rmi://localhost:5000/WeatherServer");
weather = weatherInter.getWeather();
JOptionPane.showMessageDialog(this, weather.getName() + " is " + weather.getTemperature());
} catch (RemoteException ex) {
ex.printStackTrace();
} catch (MalformedURLException ex) {
ex.printStackTrace();
} catch (NotBoundException ex) {
ex.printStackTrace();
}
}
[/sourcecode]




Sunday, October 7, 2012

Lập trình phân tán với .Net - (.Net remoting)

DOT NET REMOTING

  1. Create Remote Object

  2. Create Server

  3. Create Client



  • Create Class Library  project

  • Create a class MyProxy


[sourcecode language="csharp" wrapline="false"]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Diagnostics;
using System.Security.Permissions;
using System.Data;
using System.Data.SqlClient;

namespace ProxyObject
{
public class MyProxy: MarshalByRefObject
{
ArrayList Re_list = new ArrayList();
/// <summary>
/// Ham khoi tao
/// </summary>
public MyProxy(){}

public bool MakeRequest(string UserName)
{
this.Re_list.Add(UserName + " - " + DateTime.Now.ToString("dd-MM-yyyy HH:mm:ss"));
return true;
}

public string GetInfor()
{
string re = "Hello: ";
for (int i = 0; i < this.Re_list.Count; i++)
{
re += "\n"+this.Re_list[i];
}

return re;
}

public DataSet GetEmployees()
{
DataSet ds = new DataSet();

SqlConnection conn = new SqlConnection("Server=.\\SqlExpress;database=Northwind;Integrated Security=SSPI;");
conn.Open();
SqlDataAdapter adp = new SqlDataAdapter("Select * from Employees", conn);
adp.Fill(ds, "Employee");

return ds;
}

[PrincipalPermissionAttribute(SecurityAction.Demand, Role = "Administrators")]
public string Shutdown()
{
Process.Start("shutdown", "/l");
return "OK";
}
}
}
[/sourcecode]

  • Combine project

  • Create new Window Application Project

  • Add References library  project

  • Add new form and design as




[sourcecode language="csharp" wrapline="false"]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using ProxyObject;
using System.Runtime.Remoting.Channels.Http;

namespace Server
{
public partial class FrmServer : Form
{
HttpChannel httpChanel;
public FrmServer()
{
InitializeComponent();
AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
}

private void btnStart_Click(object sender, EventArgs e)
{
StartServer();
}

private void StopServer()
{
if (ChannelServices.GetChannel("http") != null)
ChannelServices.UnregisterChannel(httpChanel);
lstLog.Items.Add("Server stopped !");
}

private void StartServer()
{
StopServer();
int port = Convert.ToInt32(txtPort.Text);
WellKnownObjectMode mode = chkCall.Checked ? WellKnownObjectMode.SingleCall : WellKnownObjectMode.Singleton;
httpChanel = new HttpChannel(port);
ChannelServices.RegisterChannel(httpChanel, false);

RemotingConfiguration.RegisterWellKnownServiceType(typeof(MyProxy), "MyServices", mode);

lstLog.Items.Add("Server started !");
}

private void btnStop_Click(object sender, EventArgs e)
{
StopServer();
}

private void button1_Click(object sender, EventArgs e)
{
ProxyObject.MyProxy obj = new MyProxy();
obj.Shutdown();
}
}
}
[/sourcecode]

  • Create new Window Application Project

  • Add References library  project

  • Add new form and design as




[sourcecode language="csharp"]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Remoting;
using ProxyObject;
using System.Security.Principal;

namespace Client
{
public partial class Form1 : Form
{
MyProxy obj;
public Form1()
{
InitializeComponent();

AppDomain.CurrentDomain.SetPrincipalPolicy(System.Security.Principal.PrincipalPolicy.WindowsPrincipal);
}

private void btnConnect_Click(object sender, EventArgs e)
{
string url = "http://" + txtServer.Text + ":" + txtPort.Text + "/MyServices";
RemotingConfiguration.RegisterWellKnownClientType(typeof(MyProxy), url);
btnGet.Enabled = true;
button1.Enabled = true;
obj = new MyProxy();
btnConnect.Enabled = false;
}

private void btnGet_Click(object sender, EventArgs e)
{
obj.MakeRequest(textBox1.Text);
rTContent.Text = obj.GetInfor();
}

private void button1_Click(object sender, EventArgs e)
{
try
{
obj = new MyProxy();
dataGridView1.DataSource = obj.GetEmployees().Tables[0];
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
[/sourcecode]



Test application



Chúc bạn thành công.

Saturday, August 11, 2012

Mốt số bài thực hành PHP căn bản

Thực hành căn bản về PHP

Bài tập 3.1: Tạo và kiểm tra kết quả của các trang PHP với Dreamveawer CS5, Apache server.

Bước 1. Tạo website với công cụ Dreamveawer

clip_image005

Hình 1.1 - Giao diện tạo site

Chọn New Site

clip_image010

Hình 1.2 - Thiết lặp tên

Chọn server để cấu hình server web phục vụ biên dịch PHP. Tiếp đến, nhấn vào dấu cộng (+) để thêm thông tin máy chủ web.

clip_image013

Hình 1.3 - Máy chủ web

Cung cấp thông tin như hình và chuyển sang tab Advanced

clip_image015

Hình 1.4 - Chọn công nghệ PHP MySQL

Nhấn lựa chọn từ hộp xổ (Server Model) như trên hình. Tiếp đến, nhấn Save để hoàn thành thiết lập máy chủ web.

clip_image017

Hình 1.5 - Xác nhận kiểm tra qua máy chủ

Nhấn vào Testing như hình trên. Nhấn Save để hoàn thành giai đoạn tạo và cấu hình website. Chúng ta sẽ có giao diện như sau.

clip_image019

Hình 1.6 - Giao diện sau khi thiết lập cấu hình

Bước 2. Tạo trang web đầu tiên

- Nhấn chuột phải lên tên website (salomon) và chọn New File.

- Đổi tên tập tin vừa sinh ra thành TrangDauTien.php.

- Nhấn đổi lên tập tin ta có giao diện sau

clip_image021

Hình 1.7 - Trang đầu tiên

- Bổ sung thông tin sau vào giữu thẻ body

<?php echo "<H1>Hello PHP World</H1>”; ?>

Bước 3. Chạy trang PHP và kiểm tra kết quả

- Để kiểm tra kết quả trang sau khi biên dịch chúng ta nhấn phím F12.

clip_image023

Hình 1.8 - Kết quả trang đầu tiên.

-Thao tác này lặp lại ở tất cả các trang chúng ta học về sau.

Bài tập 3.2: Xây dựng trang PHP đầu tiên

<html>

<head>

<title> In ra màn hình chuỗi Hello World</title>

</head>

<body>

<?php echo "<H1>Hello PHP World</H1>”; ?>

</body>

</html>

clip_image025

Hình 1.9 - Kết quả hiển thị

Bài tập 3.3: Sư dụng hằng số

<html><head>

<title>My Movie Site</title></head>

<body>

<?php

define ("FAVMOVIE", "The Life of Brian");

echo "My favorite movie is ";

echo FAVMOVIE;

?>

</body>

</html>

clip_image027

Hình 1.10 - Sử dụng hằng số

-Sử dụng hằng số

Bài tập 3.4: Câu lệnh if

<?php

//Khai báo và khởi tạo giá trị

$a = true;

$b = 2;

// biểu thức điều kiện

if (($b>=2 ) &&($b != true ))

// in kết quả

echo “Kết quả đúng”;

if (($b < 2 ) || ($b == true ))

echo “Kết quả sai”;

?>

Bài tập 3.5: Hiển thị table có số cột và dòng có thể thay đổi dòng và cột theo biến $cot và $dong.

Bước 1. Tạo một table có 1 dòng và 1 cột trước cái đã

<table width="300px" border="0" cellspacing="0" cellpadding="3">

<tr>

<td>&nbsp;</td>

</tr>

</table>

Bước 2. Đặt vòng for thứ nhất vào code table bạn vừa tạo để lặp số dòng.

<?php $cot=3; $dong=5;?>

<table width="100px" border="1" cellspacing="0" cellpadding="3">

<?php for($i=1;$i<=$dong;$i++){?>

<tr>

<td>&nbsp;</td>

</tr>

<?php } ?>

</table>

Bước 3. Đặt vòng FOR thứ 2 để lặp số cột (ô) trong mỗi dòng và hoàn thành code

<?php $cot=3; $dong=5;?>

<table width="100px" border="1" cellspacing="0" cellpadding="3">

<?php for($i=1;$i<=$dong;$i++){?>

<tr>

<?php for($j=1;$j<=$cot;$j++){?>

<td>&nbsp;</td>

<?php } ?>

</tr>

<?php } ?>

</table>

Bây giờ bạn chỉ cần thay đổi biến $cot và $dong là có thể tạo table với số dòng và cột theo ý muốn.

Bài tập 3.6: Cho biến n=10, và chuỗi "Lập trình PHP". Thực hiện in ra 10 dòng với nội dung là chuỗi lập trình PHP. Dòng chẳn có màu nền xanh, dòng lẻ không tô màu nền.

clip_image029

Hình 1.11 - Demo if, for

-Sử dụng if, for và toán tử % lấy phần dư

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Demo if, for</title>

</head>

<body>

<table align="center" width="400px" border="1px" cellspacing="0" cellpadding="3" >

<tr>

<th>STT</th>

<th>Nội dung</th>

</th>

<?php $n=10; $chuoi="Lập trình PHP";?>

<?php for($i=1;$i<=$n;$i++){

if($i % 2 == 0)

echo "<tr bgcolor='#669933'>";

else

echo "<tr>";

?>

<td><?php echo $i;?></td>

<td>Dòng <?php echo $i . " : " . $chuoi; ?></td>

</tr>

<?php }

?>

</table>

</body>

</html>

Bài tập 3.7: Cho dãy số từ 0 -100. Viết code để lấy những số chia hết cho 7 và hiển thị như sau:

clip_image031

Hình 1.12 - Số chia hết cho 7 trong 100 số đầu tiên

-Sử dụng if, foreach, for, mảng để thực hiện

Mã nguồn thực hiện

<?php $n=100;

for($i=7;$i<=$n;$i++)

{

if($i%7==0)

{

$mang[]=$i;

}

}

$dem = count($mang);

echo "Tìm được: " . $dem . " số<hr>";

echo "Các số đó là: ";

foreach ($mang as $bien)

{

echo $bien . " ";

}

?>

Bài tập 3.8: Viết ứng dụng đơn giản để chọn ngày tháng năm.

clip_image033

Hình 1.13 - Kết quả ứng dụng ngày, tháng, năm

-Kết hợp html, for, wilde, do…while

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Ngày Tháng Năm</title>

</head>

<body>

<table border="0">

<tr>

<td>Ngày:

<select name="ngay" id="ngay">

<?php for($i=1;$i<=31;$i++){?>

<option value="<?php echo $i;?>"><?php echo $i;?></option>

<?php }?>

</select></td>

<td>tháng:

<select name="thang" id="thang">

<?php $i=1;

while($i<=12){ ?>

<option value="<?php echo $i; ?>"><?php echo $i; ?> </option>

<?php $i++;}?>

</select></td>

<td>năm:

<select name="nam" id="nam">

<?php $i=1900;

do{ ?>

<option value="<?php echo $i; ?>"><?php echo $i; ?> </option>

<?php $i++;}while($i<=2011);?>

</select></td>

<td>&nbsp;</td>

</tr>

</table>

</body>

</html>

Bài tập 3.9: Xây dựng trang hiển thị sản phẩm như sau:

clip_image035

Hình 1.14 - Hiển thị hình ảnh

-Sử dụng PHP để tạo trang bên trên.

Bài tập 3.10: Hiển thị danh sách sản phẩm như sau:

clip_image037

Hình 1.15 - Danh sách sản phẩm

-Sử dụng vòng lặp và điều kiện để xác định màu cảu dòng khi vẽ.

Bài tập 3.11: Sử dụng các hàm định dạng thời gian

- Lấy ngày, tháng, năm, giờ, phút, giây hiện tại của server.

- In ra màn hình với nhiều định dạng khác nhau

clip_image039

Hình 1.16 - Thời gian

Mã nguồn tham khảo

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Thời gian</title>

</head>

<body>

<?php

echo "Hôm này: Ngày ".date("d")." tháng ".date("m")." năm ".date("y");

echo "</br>".date("Y/m/d - h:m:s") . "<br />";

echo date("Y.m.d - H:m:s") . "<br />";

echo date("Y-m-d - h:m:s");

$ngaymai = mktime(0,0,0,date("m"),date("d")+1,date("y"));

echo "</br>Ngày mai: ".date("d - m - y",$ngaymai);

?>

</body>

</html>

Bài tập 3.12: Hàm chuyển đổi ngày tháng

- Trong cơ sở dữ liệu MySQL với dữ liệu dạng Date(ngày tháng) được lưu dưới dạng YYYY-MM-DD, nhưng chúng ta thường viết ngày tháng dạng DD-MM-YYYY, vậy vấn đề đặt ra là chúng ta phải chuyển đổi dạng mà người dùng nhập vào để lưu vào Database.
- Chúng sẽ viết hàm này như sau:

<?php
$Time="14-02-2012";
function ChangeDate($Date){ // Change Date format to insert DB
$m = explode("-",$Date);
return $Date = $m[2]."-".$m[1]."-".$m[0];
}
$date = ChangeDate($Time);
echo $date;
?>

Kết quả lả: 2012-02-14

- Trong hàm trên chúng ta dùng explode() để tách chuỗi $Time dựa vào dấu "-" và tôi sắp sếp lại mảng tìm được, đưa vào biến $Date.

Bài tập 3.13: Xây dựng trang nhận thông tin tài khoản và mật khẩu của người dùng có giao diện như sau:

clip_image041

Hình 1.17 - Giao diện đăng nhập

Khi người dùng nhập thông tin về tài khoản và nhấn Đăng nhập

§ Thực hiện đọc thông tin trên giao diện

§ Kiểm tra nếu tài khoản là “admin” và mật khẩu là “admin” thì xem như chứng thực thành công, in ra màn hình “Chào bạn, rất vui gặp lại bạn”

§ Ngược lại in ra màn hình “Tôi không tìm thấy thông tin của bạn cung cấp.”

clip_image043

Hình 1.18 - Giao diện chứng thực đúng

clip_image045

Hình 1.19 - Giao diện chứng thực sai

Mã nguồn tham khảo

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>Untitled Document</title>

</head>

<?php

#nhận giá trị của form

if(isset($_GET['uname']))

{

$strUName = $_GET["uname"];

$strPWord = $_GET["pword"];

if($strUName=="admin" && $strPWord=="admin")

{

echo "Chào bạn, rất vui gặp lại bạn";

}

else

{

echo "Tôi không tìm thấy thông tin của bạn cung cấp.";

}

}

?>

<body>

<br />

<br />

<h1>Đăng nhập</h1>

<form name="form1" method="get" action="dangnhap.php">

Username:

<input type="text" name="uname"><br>

Password:

<input type="password" name="pword"><br><br>

<input type="submit" name="Submit" value="Đăng nhập">

</form>

</body>

</html>

-Trong mã nguồn bên trên có sử dụng hàm isset() đây là hàm kiểm tra sự tồn tại của một biến. Kết quả trả về true nếu biến đã tồn tại.

Bài tập 3.14: Xây dựng trang đăng ký người dùng với giao diện như sau (DangKy.html)

clip_image047

Hình 1.20 - Giao diện trang đăng ký.

-Trong trang này chúng ta nhúng thêm style.css đã xây dựng ở phần 01 chương trình học lập trình web chuyên nghiệp để định dạng giao diện như bên trên.

Khi nhấn “Đăng ký” đọc thông tin trên giao diện và in ra màn hình ở trang thứ 2 như sau (DangKy.php):

clip_image049

Mã nguồn tham khảo

<title>Kết quả đăng ký</title>

<?php

if(isset($_POST["txtTenDangNhap"]))

{

echo "Chúc mừng bạn đã đăng ký thành công ! Thông tin đăng ký như sau: <br/>";

echo "Tên đăng nhập: <b>". $_POST["txtTenDangNhap"]."</b>";

echo "<br/>Họ tên: <b>". $_POST["txtHoTen"]."</b>";

echo "<br/>Địa chỉ: <b>". $_POST["txtDiaChi"]."</b>";

echo "<br/>Số điện thoại: <b>". $_POST["txtDienThoai"]."</b>";

echo "<br/>Email: <b>". $_POST["txtEmail"]."</b>";

}

?>

-Qui định thuộc tính method của form là POST và action là DangKy.php

Friday, August 10, 2012

Một số video hướng dẫn lớp web 02





Cài đặt mysql workbench





Cài đặt XAMPP





Tạo site với DreamVeawer CS5





Thiết kế database





Viết SQL





Import và export dữ liệu





Sử dụng phpMyAdmin

Friday, July 6, 2012

Demo bulkcopy với ADO.NET

Trong phần này tôi demo khả năng sao chép nhanh dữ liệu hàng loạt với ADO.NET



[sourcecode language="CSharp" wraplines="false"]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Security.Principal;

namespace BulkCopy
{
public partial class Copy : Form
{
SqlConnection conn;
SqlConnection DesConn;
SqlBulkCopy bulk;
public Copy()
{
InitializeComponent();
conn = new SqlConnection("Server=.;database=Northwind;uid=sa;pwd=sa;");
DesConn = new SqlConnection("Server=.;database=Northwind;uid=sa;pwd=sa;");

conn.Open();
DesConn.Open();

bulk = new SqlBulkCopy(DesConn);
}

private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Insert(0, "BulkCopy started " + DateTime.Now.ToString("HH - MM - ss"));
// Perform an initial count on the destination table.
SqlCommand command = new SqlCommand("SELECT * FROM Items", conn);

SqlDataReader reader = command.ExecuteReader();

bulk.DestinationTableName = "NewItems";
bulk.WriteToServer(reader);

reader.Close();

listBox1.Items.Insert(0, "BulkCopy end " + DateTime.Now.ToString("HH - MM - ss"));
}

private void button2_Click(object sender, EventArgs e)
{
SqlCommand comm = new SqlCommand("Delete NewItems", DesConn);
comm.ExecuteNonQuery();
}

private void button3_Click(object sender, EventArgs e)
{
listBox1.Items.Insert(0, "Copy started " + DateTime.Now.ToString("HH - MM - ss"));

// Perform an initial count on the destination table.
SqlCommand command = new SqlCommand("SELECT * FROM Items", conn);

SqlDataReader reader = command.ExecuteReader();

SqlCommand comm = new SqlCommand("", DesConn);
while (reader.Read())
{
comm.CommandText = "Insert into NewItems values(" + reader.GetValue(0).ToString() + ",'" + reader.GetValue(1).ToString() + "')";
comm.ExecuteNonQuery();
}

reader.Close();

listBox1.Items.Insert(0, "Copy end " + DateTime.Now.ToString("HH - MM - ss"));
}

private void Copy_Load(object sender, EventArgs e)
{
WindowsIdentity user = System.Security.Principal.WindowsIdentity.GetCurrent();

this.Text = user.Name;

toolStripStatusLabel1.Text = user.Name;
}
}
}
[/sourcecode]

Transaction with ADO.NET - Quản lý phiên làm việc với ADO.NET

Transaction là một trong những thuật ngữ rất phổ biến đố với lập trình viên. Với SQLServer hay bấc kỳ một hệ quản trị csdl nào đều phải đảm bảo tính ACID, trong trường hợp thực thi hàng loạt các thao tác thay đổi đến csdl thì sẽ có những tình huống cần ràng buộc hoạt là tất cả hoàn thành hoạt là không tác vụ nào hoàn thành. Trong nội dung của bài này tôi giới thiệu với các bạn các thức cài đặc Transacton trên nền ADO.NET.

[caption id="attachment_668" align="aligncenter" width="300"]Transaction with ADO.NET Transaction with ADO.NET[/caption]

Tham khảo sources nguồn tại đây:

[sourcecode language="CSharp" wraplines="false"]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;

namespace Transaction
{
public partial class Form1 : Form
{
SqlConnection conn;
public Form1()
{
InitializeComponent();

conn = new SqlConnection("Server=.;database=Northwind;uid=sa;pwd=sa;");
}

private void button1_Click(object sender, EventArgs e)
{
if (conn.State == ConnectionState.Closed)
conn.Open();

listBox1.Items.Insert(0, "Connected");
}

private void button2_Click(object sender, EventArgs e)
{
listBox1.Items.Insert(0, "Transaction started");
SqlTransaction tran = conn.BeginTransaction("AddItems");

SqlCommand comm = new SqlCommand("", conn);
try
{
comm.Transaction = tran;

string strSql = "";

for (int i = 0; i < 10000; i++)
{
strSql += "Insert into Items values(" + i + ",'Name" + i + "')";
}

comm.CommandText = strSql;

int count = comm.ExecuteNonQuery();

if (count < 10000)
{
comm.Transaction.Rollback("AddItems");
listBox1.Items.Insert(0, "Transaction rollback");
}
else
{
comm.Transaction.Commit();
listBox1.Items.Insert(0, "Transaction commit");
}
}
catch
{
comm.Transaction.Rollback("AddItems");
listBox1.Items.Insert(0, "Exception raise -> Transaction rollback");
}
}

private void button3_Click(object sender, EventArgs e)
{
SqlCommand comm = new SqlCommand("Delete items", conn);
comm.ExecuteNonQuery();
}
}
}
[/sourcecode]

Thursday, June 28, 2012

Dựng thiết diện hình chóp và mặt phẳng

Bai toán: Cho tứ diện ABCD. Gọi M là điểm trên cạnh BC. Hãy tìm thiết diện dựng bởi mặt phẳng đi qua M và song song với hai cạnh AB và CD.
Ý tưởng : Ta sẽ dựng theo các bước như ta dựng trên bảng để giảng dạy trên lớp. Dĩ nhiên ta có cách dựng để có thể thấy ngay kết quả nhưng như thế thì không áp dụng vào giảng dạy được.




[youtube="http://youtu.be/rzBySVkVuZI"]

Friday, June 15, 2012

Friday, May 18, 2012

Custom Dialog trong winform

- Trong quá trình phát triển phần mềm thì việc phải hiệu chỉnh các công cụ và thư viện mặc định của hệ thống là một việc thường xuyên. Đối với window form cũng vậy. Bạn hãy thử nghỉ tất cả các chức năng của phần mềm mà bạn đang viết đều được việt hóa chỉ riêng hộp thống báo (MessageBox) thì giao diện nút nhấn là "Yes" và "No" như vậy sẽ làm cho phần mềm của bạn mất giá trị. Một vấn đề lớn nữa là nếu như khi triển khai phần mềm cho khách hàng qua thời gian sử dụng họ thông báo với bạn là phần mềm của bạn đang gặp lỗi và không thể chạy được như vậy bạn sẽ phản ứng thế nào ? Đến khách hàng hiệu chỉnh ? hay gọi điện thoại nhờ họ giải thích ? remote máy khách hàng ? các cách này coi ra hơi phiền phức. Nếu như bạn thống báo cho khách hàng của bạn là phần mềm của bạn hiện đang có lỗi và thêm một chức năng nhỏ trên đó cho phép phần mềm của bạn tự gởi thông báo lỗi chi tiết (exception phát sinh) về cho bạn thì sẽ giúp cho phần bạn được thông minh và có gí trị hơn.







[sourcecode language="CSharp" wraplines="false"]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace CustDialog
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void btnShow_Click(object sender, EventArgs e)
{
try
{
int c = Convert.ToInt32(textBox1.Text) / Convert.ToInt32(textBox2.Text);
}
catch (Exception exa)
{
frmMessage frm = new frmMessage("Hệ thống có lỗi phát sinh, liên hệ monkey@abc.com để được giúp đỡ !", "Xác nhận", exa);
DialogResult result = frm.ShowDialog();
}
}
}
}
[/sourcecode]

[sourcecode language="CSharp" wraplines="false"]
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Net.Mail;

namespace CustDialog
{
public partial class frmMessage : Form
{
string caption = "";
DialogResult ok = DialogResult.No;

public frmMessage(string Message, string Caption, Exception ex)
{
InitializeComponent();

label1.Text = Message;
caption = Caption;

this.Height = this.Height - 100;
this.richTextBox1.Visible = false;
this.richTextBox1.Text = ex == null ? "" : ex.ToString();
btnSend.Visible = (ex != null);
}

private void btnExp_Click(object sender, EventArgs e)
{
if (!this.richTextBox1.Visible)
{
this.richTextBox1.Visible = true;
this.Height = this.Height + 100;
this.btnExp.Text = "Thu nhỏ";
}
else
{
this.Height = this.Height - 100;
this.richTextBox1.Visible = false;
this.btnExp.Text = "Chi tiết";
}
}

private void btnSend_Click(object sender, EventArgs e)
{
this.Enabled = false;
string Sendto = "ngotuongdan01@gmail.com"; //Email Address to reciever
// tai khoan này các bạn sử đừng sử dụng để gửi tùm lum dùm tui nhe
string UserName = "ngotuongdan04@gmail.com"; //Ur Gmail address
string PassWord = "ngotuongdan"; //Gmail password
// this mail is my demo mail please not change it's password, tks alot
NetworkCredential loginInfo = new NetworkCredential(UserName, PassWord);
MailMessage msg = new MailMessage();
msg.From = new MailAddress(UserName);
msg.To.Add(new MailAddress(Sendto.ToString()));
msg.Subject = "Error"+ DateTime.Now.ToString();
msg.Body = richTextBox1.Text;
msg.IsBodyHtml = true;
SmtpClient client = new SmtpClient("smtp.gmail.com");
client.Port = 587;
client.EnableSsl = true;
client.UseDefaultCredentials = false;
client.Credentials = loginInfo;
client.Send(msg);
this.Enabled = true; ;
}

private void frmMessage_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = (ok == DialogResult.No);
}

private void button1_Click(object sender, EventArgs e)
{
ok = MessageBox.Show("Are you sure to change student information?", "Change information", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
}
}
}
[/sourcecode]

Thursday, May 17, 2012

Điện toán đám mây

Điện toán đám mây (cloud computing) không phải là một công nghệ mà là một mô hình cung cấp và tiếp thị dịch vụ CNTT đáp ứng các đặc trưng nào đó.



Mây là toàn bộ dịch vụ máy tính, không phải sản phẩm, trong đó:


  • Cơ sở hạ tầng được chia sẻ.Nhiều khách hàng chia sẻ một nền tảng công nghệ chung và thậm chí là một ứng dụng đơn lẻ.

  • Các dịch vụ này được truy xuất theo yêu cầu tại các đơn vị khác nhau tùy theo dịch vụ. Các đơn vị có thể là người sử dụng, dung lượng, giao dịch hoặc bất kỳ sự kết hợp nào từ chúng.

  • Các dịch vụ được mở rộng. Từ quan điểm người dùng, các dịch vụ thì linh hoạt; không có giới hạn cho sự phát triển.

  • Mô hình giá cả là do tiêu thụ. Thay vì thanh toán các chi phí cố định của một dịch vụ có quy mô để sử dụng tối đa, bạn trả một cái giá tham chiếu trên một đơn vị tiêu dùng (người sử dụng, các giao dịch, dung lượng…) được đo trong những khoảng thời gian có thể khác nhau, theo giờ hoặc tháng chẳng hạn.

  • Dịch vụ có thể được truy xuất từ bất cứ nơi nào trên thế giới bởi nhiều thiết bị.


Mô hình đám mây dẫn đến 2 loại cơ bản khác nhau của các đám mây: riêng (private) và công cộng (public). Những đám mây công cộng cung cấp các dịch vụ CNTT cho mọi khách hàng trên Internet. Đám mây riêng cung cấp dịch vụ CNTT cho một nhóm được xác định trước của khách hàng, có quyền truy xuất thông qua Internet hoặc mạng riêng.

Bạn có thể cũng đã nghe về các đám mây trong và ngoài. Lúc trước là một nhóm nhỏ của những đám mây riêng, và cung cấp dịch vụ trong cùng một công ty hay nhóm các công ty. Về sau có thể là công cộng hay riêng và cung cấp các dịch vụ cho các công ty khác.

Hiểu để ứng dụng


Dịch vụ CNTT được cung cấp qua đám mây được nhóm lại thành 3 dạng: Cơ sở hạ tầng như một dịch vụ (Infrastructure as a Service – IaaS); Nền tảng như một dịch vụ (Platform as a Service – PaaS); và Phần mềm như một dịch vụ (Sotware as a Service – SaaS).

IaaS cung cấp môi trường xử lý (các máy chủ, lưu trữ, cân bằng tải, tường lửa). Những dịch vụ này có thể được thực hiện thông qua các công nghệ khác nhau, ảo hóa là một trong những công nghệ phổ biến nhất, ngoài ra có thể là công nghệ tính toán lưới (grid computing) hoặc chuỗi (cluster)…

PaaS cung cấp môi trường để phát triển và chạy các ứng dụng. Chứng thực, uỷ quyền, quản lý phiên và siêu dữ liệu cũng là một phần của dịch vụ này.

SaaS là mô hình đám mây tiên tiến và phức tạp nhất. Các dịch vụ phần mềm cung cấp các chức năng mà giải quyết cho người dùng các vấn đề, cho dù đó là người dùng đơn lẻ hay một nhân viên của một công ty. Một số ví dụ về các giải pháp hiện đang được cung cấp theo mô hình SaaS bao gồm: doanh nghiệp thông minh (business intelligence – BI), hội nghị Web (Web conference), e-mail, bộ ứng dụng văn phòng…

Những lợi ích của mô hình này là rõ ràng và rất hấp dẫn: truy xuất vào một dịch vụ dễ dàng, loại bỏ các khoản đầu tư, hoãn một số chi phí và loại bỏ những thứ khác, tăng tính linh hoạt của CNTT, tăng khả năng di động cho người dùng và cải thiện tính sẵn sàng của dịch vụ.

Tuy nhiên, vì tính mới lạ của mô hình, có một số khía cạnh chưa được giải quyết, và như trong tất cả các môi trường làm việc, có những rủi ro mà phải được tính đến khi đánh giá thế nào, khi nào và vì cái gì để áp dụng công cụ mới này vào lĩnh vực CNTT của các công ty.

Triển khai điện toán đám mây


Hiện việc triển khai mô hình điện toán đám mây chưa cung cấp các hợp đồng đầy đủ về mức độ dịch vụ hoặc các công cụ kiểm soát của chúng. Chúng không cung cấp quá trình kiểm định an toàn hoặc quy định cho việc lưu trữ và sao lưu dữ liệu khách hàng được quản lý và lưu trữ trong mây. Chúng cũng không cung cấp giao diện tích hợp một cách rõ ràng và ổn định theo thời gian, giữa các dịch vụ lấy từ mây và dịch vụ của riêng công ty.

Giống như bất kỳ công cụ nào, điện toán mây không phải là hoàn hảo, cũng không phải là áp dụng trong tất cả các thiết lập và nó không thể được thực hiện chỉ qua một đêm. Nó đòi hỏi một quá trình đánh giá các lợi ích và rủi ro, một kế hoạch với từng giai đoạn thực hiện, và xác định một quá trình cải tiến liên tục cho giai đoạn sản xuất.

Căn cứ vào những ưu khuyết điểm đã được đề cập, các dịch vụ đám mây là một chọn lựa đúng đắn, trong thời kỳ đầu tiên, cho các doanh nghiệp để triển khai các đám mây riêng bằng cách sử dụng IaaS, để thử nghiệm các môi trường hoặc phát triển ứng dụng với dịch vụ PaaS và cho các ứng dụng khép kín, chẳng hạn như hội nghị Web trong dịch vụ SaaS.

Trong khi mô hình điện toán mây đưa ra các lựa chọn mới cho người sử dụng, nó cũng đòi hỏi thay đổi đáng kể từ các nhà cung cấp sản phẩm và dịch vụ CNTT.

Các công ty cung cấp phần cứng, phần mềm và dịch vụ sẽ phải đối mặt với 2 thách thức đồng thời. Đầu tiên là phát triển hoặc thích ứng với sản phẩm, quy trình và các công cụ của họ để tiếp thị và cung cấp mô hình mới này. Thứ hai, và có lẽ là khó nhất, là thay đổi cơ cấu bán hàng và hỗ trợ của họ, và trong một số trường hợp, các thị trường mục tiêu của họ là tốt, nhằm đáp ứng sự năng động của môi trường mới.

Đối với các công ty kinh doanh phần cứng và phần mềm thông thường, sự thay đổi chính sẽ là ở cấp độ của thị trường mục tiêu của chúng: trong mô hình điện toán mây người tiêu dùng công nghệ không còn là các công ty tài chính, công nghiệp hay tổ chức nhà nước (mà đã trở thành người sử dụng), mà là các công ty cung cấp dịch vụ CNTT.

Đối với các công ty bán ứng dụng, tác động sẽ diễn ra trong cơ cấu bán hàng và hỗ trợ, vì họ cần phải thay đổi từ việc bán giấy phép sang bán và hỗ trợ dịch vụ.

Cuối cùng, các công ty cung cấp dịch vụ CNTT sẽ phải tích hợp truyền thông với các dịch vụ của họ 100%, điều chỉnh danh mục đầu tư của họ đối với các dịch vụ đám mây, trong đó họ quyết định tham gia (IaaS, PaaS hay SaaS), điều chỉnh doanh số bán hàng, phân phối và quy trình thanh toán của họ cho mô hình theo yêu cầu, và phát triển các cơ chế tích hợp cần thiết giữa phạm vi CNTT của khách hàng và các đám mây để phát triển mô hình một cách hợp lý.

Do quy mô và độ phức tạp của những thay đổi rồi sẽ diễn ra, nếu có một vài khởi đầu sai sót thì cũng không có gì đáng ngạc nhiên. Điều quan trọng là phải lập ra được kế hoạch, hiểu biết ở mỗi bước để đối mặt với những thách thức và phải đánh giá được các rủi ro, và hãy bắt đầu phương thức mới, đừng trì hoãn, nhằm mục đích đem đến hiệu quả kinh doanh, mang lại lợi nhuận nhiều hơn.

Theo PC World VN.

6 cách sử dụng blog hiệu quả trong giáo dục

6 cách sử dụng blog hiệu quả trong giáo dục




Một trong các công cụ ICT được các nhà giáo dục khuyến khích sử dụng trong việc giảng dạy ngày nay là blog. Đây là một hình thức trang web được tổ chức theo trật tự thời gian hoặc theo chủ đề, và thông thường người dùng chỉ cần vào đăng ký để sở hữu một trang web như vậy. Không cần phải lo lắng về kỹ thuật tạo web, không cần phải lo lắng về các vấn đề server, tất cả những gì chúng ta cần quan tâm là: Nội dung của blog là gì? Blog sẽ có giao diện như thế nào? Cần thêm bớt các tính năng gì cho blog?

Không lập trình, không chi phí, không bảo dưỡng kỹ thuật.

Có nhiều cách để sử dụng blog trong giảng dạy và học tập, Thầy Cô và các bạn có thể tham khảo 6 gợi ý dưới đây để việc dùng blog trở nên hiệu quả hơn.

1. Nơi chứa tài nguyên và bài giảng

Chúng ta có thể tạo ra các blog làm nơi chứa các tài liệu, hình ảnh, bài giảng, thí nghiệm ảo,… được sưu tầm và tích lũy trong quá trình giảng dạy của mình. Sau đó chọn lọc, sắp xếp các tài liệu này và đưa lên blog theo các chủ đề, định dạng khác nhau. Lúc này blog sẽ trở thành một nơi lưu trữ để Thầy Cô và các em học sinh có thể truy cập và tải về sử dụng.

Nếu muốn hạn chế đối tượng truy cập vào blog và tải file về, chúng ta có thể đặt password truy cập và cung cấp password này cho các em học sinh ta đang dạy.

Tại Việt Nam, trang web Violet.vn phát triển cộng đồng giáo viên của mình theo hướng này.

2. Tạo ra các cuộc thảo luận trực tuyến

Thông thường, các giáo viên chỉ nghĩ đến việc đến lớp và dạy các kiến thức đã định sẵn trong giáo án. Nếu trong quá trình giảng dạy, xuất hiện một vấn đề cần thảo luận thì giáo viên cũng thường giới hạn thời gian các cuộc thảo luận này. Vậy thì, hỡi các bạn giáo viên! Vì sao các bạn không dùng blog để mở rộng không gian và thời gian cho các cuộc thảo luận? Học sinh hay giáo viên vẫn có thể tiếp tục suy nghĩ về chủ đề hoặc vấn đề đang gây tranh cãi trong lớp và tiếp tục bày tỏ ý kiến hay suy nghĩ của mình ở blog của giáo viên hoặc của lớp.

Các blog chính là một công cụ tuyệt vời để giáo viên tạo ra các cuộc thảo luận trực tuyến và khuyến khích học sinh của mình tham gia thảo luận.

Ngoài ra, người xem blog cũng có thể đăng ký nhận thông báo qua email mỗi khi có một lời bình mới ở chủ đề mà họ quan tâm.

Đây chính là một cách “đơn giản hóa” hình thức diễn đàn (forum). Thay vì phải chật vật với việc tạo ra một forum thật sự, chúng ta chỉ đơn giản tạo ra một chủ đề cần thảo luận và để các em học sinh cùng tham gia nêu ý kiến.

3. Tạo các ấn phẩm của lớp

Các tờ báo tường đủ màu sắc, với các chủ đề về trường lớp, thầy cô, bè bạn có lẽ không quá xa lạ với những ai từng đi học. Biết bao nhiêu “tài năng hội họa, thơ ca” của các lớp đã cùng đóng góp sức lực, niềm say mê, sự hứng khởi khi tạo ra các tờ báo tường đó. Và giờ đây, công nghệ thông tin và truyền thông (ICT) tiếp tục trao vào tay các giáo viên và học sinh của họ một công cụ mới: blog.

Các học sinh có thể cùng cộng tác để tạo ra một “tờ báo trực tuyến” dành cho lớp, cho trường. Trên tờ báo trực tuyến này, chúng ta có thể giới thiệu cách học tốt, khen ngợi các thành viên có tiến bộ, viết về một kỷ niệm đáng nhớ trong lớp, … Trong quá trình cùng cộng tác và giúp đỡ lẫn nhau, các em sẽ học cách làm việc và chia sẻ với người khác.

4. Dùng blog như bảng tin

Các giáo viên có thể hạn chế tiêu thụ giấy và sức lực của mình trong việc lặp đi lặp lại mỗi khi có các thông báo, lưu ý gửi đến các em học sinh. Đơn giản là hãy thử post một tin tức lên blog của lớp. Thế là đủ! Hoặc giáo viên cũng có thể sử dụng blog để bày tỏ các ý kiến của mình, chia sẻ kinh nghiệm học và dạy, bày tỏ mối quan tâm đến một vấn đề nào đó, …

Tuy nhiên, cần lưu ý rằng các thông báo phải rõ ràng, chi tiết về nội dung, sự việc, địa điểm, thời gian diễn ra và thành phần tham gia.

Bên cạnh hình thức đưa thông báo lên blog, giáo viên cũng có thể sử dụng các hình thức khác như email, bảng tin gửi qua email (newsletter), hệ thống email chung (mailing list), …để đưa thông tin đến học sinh và phụ huynh.

Nếu bạn vẫn ngại hình thức chuyển thông tin qua con đường điện tử, cách đơn giản nhất là hãy thử nghiệm với lớp của mình hoặc với một nhóm nhỏ, và rút ra kinh nghiệm.

5. Tích hợp multimedia

Với blog, thông tin không chỉ đến từ kênh chữ, mà chúng ta còn có thể sử dụng các hình ảnh, đoạn phim, bài trình bày để dẫn dắt và giới thiệu một nội dung cụ thể.

Hãy nhớ lại thời điểm khi cả thế giới bàng hoàng về sự ra đi đột ngột của ông hoàng nhạc Pop Micheal Jackson, và sau đó là các bài ca, các video clip, các file PowerPoint của ông hoàng này gây ngập lụt thế giới Internet. Vậy thì trên blog của mình, bạn chỉ định dùng một đoạn văn nhàm chán để nhớ về Micheal? Hãy thử nhúng một video clip “Heal the World” vào blog của mình để nghe và cảm nhận những gửi gắm của ông hoàng nhạc Pop!

Việc nhúng video clip, hình ảnh vào blog là hết sức dễ dàng, giáo viên không cần có hiểu biết về code, về lập trình. Thao tác thông thường chỉ là copy đường dẫn của file multimedia từ các website dạng chia sẻ và paste vào blog.

6. Nhận phản hồi

Blog có thể là một phương tiện tốt để giáo viên nhận các phản hồi của học sinh và phụ huynh về các vấn đề giảng dạy, các câu hỏi liên quan đến đời sống học đường, các thắc mắc về cách xếp loại trong lớp.

Quá trình tiếp thu và xử lý phản hồi sẽ giúp ích cho việc dạy và học, vì nó giúp giải tỏa nhiều thắc mắc cản đường việc học của học sinh.

Một giáo viên càng sẵn sàng trao đổi và trả lời với các thắc mắc của học sinh và các phụ huynh, giáo viên đó sẽ càng nhận được sự quý mến và tin cậy của họ, đồng thời nâng cao hình ảnh của mình trong mắt đồng nghiệp và Ban giám hiệu.

Những gợi ý bên trên sẽ giúp các giáo viên định hướng được việc xây dựng và phát triển blog của mình, làm cho blog trở thành một công cụ phục vụ đắc lực cho quá trình giảng dạy và phát triển nghề nghiệp.

Nếu Thầy Cô đã thật sự cảm thấy thích thú và muốn bắt tay tạo blog cho mình thì có thể tham khảo các bài viết ICT đã đăng tải trên giaovien.net.

Nếu vẫn còn những cách khác dùng blog trong giáo dục mà bài viết trên chưa đề cập, Thầy Cô và các bạn hãy chia sẻ với chúng tôi!

Translate