Home Blog Page 79

Cài đặt Nginx sử dụng Docker

cài đặt nginx
Cài đặt Nginx sử dụng Docker

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

Trong bài viết trước, mình đã hướng dẫn các bạn cách cài đặt Nginx trên CentOS. Nếu sử dụng Docker thì việc cài đặt Nginx sẽ như thế nào? Trong bài viết này, mình sẽ hướng dẫn cho các bạn nhé!

  10x engineer - cắt giảm chi phí 10 lần
  20 trường hợp sử dụng lệnh Docker cho developer

Xem thêm việc làm IOT Engineering hấp dẫn trên TopDev

Đầu tiên, các bạn cần đi đến trang Docker Hub official build của Nginx https://hub.docker.com/_/nginx, chọn latest version của Nginx, sau đó thì sử dụng Docker command để start một Nginx server lên, ví dụ như sau:

docker run -d -p 80:80 --name web nginx

Nginx mặc định chạy ở port 80 và mình đã mapping với port 80 của máy host (máy chạy Docker). Ở đây, mình cũng đã sử dụng latest tag của Nginx nên mình không cần khai báo version, các bạn có thể chọn version mà mình muốn nhé!

Kết quả:

Lúc này, nếu các bạn đi đến http://localhost/, các bạn sẽ thấy kết quả như sau:

Rất nhanh và đơn giản phải không các bạn?

Bài viết gốc được đăng tải tại huongdanjava.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Interior Designer Là Gì? Cơ Hội Nghề Nghiệp Nào Cho Các Interior Designer?

interior designer là gì
Interior Designer Là Gì? Cơ Hội Nghề Nghiệp Nào Cho Các Interior Designer?

Thiết kế là một công việc xuất hiện ở hầu hết mọi ngành nghề khác nhau. Trong số đó, interior design là một trong những công việc được ví với khả năng “thổi hồn” cho những không gian sống ấn tượng hơn. Vậy Interior designer là gì? Công việc của một nhà thiết kế nội thất hiện tại đang phát triển ra sao và cần làm gì để theo đuổi ngành nghề này? Cùng tìm hiểu thêm với bài viết dưới đây của TopDev nhé!

interior designer là gì
Interior Designer là gì?

Interior Designer là gì?

Đối với dân chuyên ngành thiết kế, câu hỏi interior design là gì chắc chắn không làm khó được mọi người nhưng với những người “ngoại đạo”, đây là một vị trí vẫn còn khá mới mẻ. Nói một cách dễ hiểu nhất, Interior Designer là thiết kế nội thất, nhà thiết kế lúc này sẽ giữ vai trò quyết định trong việc nắm bắt cảm giác không gian và mong muốn của người sinh sống để cho ra những thiết kế phù hợp và ấn tượng nhất.

Đó chính là vai trò và trách nhiệm chính của một nhà thiết kế nội thất. Không chỉ làm toát lên những ưu điểm của không gian sống mà còn phải thể hiện được ý đồ nghệ thuật của chủ nhà. Một interior designer tài năng, có trình độ sẽ cho thấy sự tinh tế và ấn tượng trong từng chi tiết nhỏ nhất của nội thất.

Hiện nay, các interior designer vẫn hoạt động nhiều nhất trong lĩnh vực xây dựng, phục vụ chủ yếu cho công việc thiết kế nội thất gia đình và các không gian văn phòng khác. Ai cũng có mong muốn có thể sống trong một không gian ấm cúng và khiến mình cảm thấy vui vẻ, do đó công việc của các nhà thiết kế nội thất hiện nay được đánh giá rất cao và trở thành thành ngành nghề có xu thế phát triển hơn nữa trong tương lai với mức thu nhập đầy hấp dẫn.

Xem thêm nhiều việc làm Designer lương cao trên TopDev

Cơ hội nghề nghiệp của các Interior Designer

Tại Việt Nam, trước đây ngành thiết kế nội thất vẫn còn khá mới mẻ và không được nhiều người biết đến. Tuy nhiên, ở thời điểm hiện tại, đây là dịch vụ được săn đón hàng đầu với bất cứ ai đang có nhu cầu thiết kế lại không gian sống của mình.

Theo thống kê của Bộ Lao động Hoa Kỳ, từ những năm 2017, mức lương của một Interior Designer đã nằm trong khoảng 51.000 USD/năm. Với những người đã dày dặn kinh nghiệm trong nghề, mức lương cao nhất còn có thể đạt đến 93.000 USD/năm. Ở Việt Nam, không khó để kiếm những vị trí công việc liên quan đến thiết kế nội thất với mức thu nhập cho sinh viên mới ra trường dao động trong khoảng gần 10 triệu đồng.

mức lương interior design
Mức lương của Interior Design hiện đang nằm ở mức khá hấp dẫn trên thị trường

Có nhiều vị trí công việc khác nhau cho các Interior Designer, trong đó có thể kể đến một số vai trò chính:

  • Chuyên viên thiết kế nội thất: Để làm được công việc này, gu thẩm mỹ chắc chắn là yếu tố không thể thiếu với các nhà thiết kế. Dựa vào không gian thực tế, bạn sẽ là người lên ý tưởng, đưa ra các phương án xây dựng hình ảnh ấn tượng và phù hợp nhất với không gian cũng như mong muốn của người sử dụng nó.
  • Chuyên viên thiết kế đồ họa (Graphic Designer): Công việc chính bạn cần đảm nhiệm sẽ liên quan đến việc thiết kế ra những hình ảnh mới, sáng tạo cho phù hợp với nhu cầu người dùng dựa trên các thiết bị cơ bản như phần mềm máy tính. Công việc chủ yếu sẽ liên quan đến việc thiết kế quảng cáo, tạp chí, hình ảnh tuyên truyền,…
  • Chuyên viên thiết kế nội thất công nghiệp: Công việc một interior designer phụ trách chính cho vai trò này là thiết kế không gian cho các sản phẩm được sản xuất ở số lượng lớn như xe ô tô, đồ gia dụng, đồ chơi,… Họ thường làm việc theo nhóm lớn để chịu trách nhiệm chung cho việc thiết kế, và mức lương cho vị trí này cũng khá cao so với mặt bằng chung.
  Design pattern là gì? Tại sao nên sử dụng Design pattern?
  10 kênh Youtube học lập trình không thể bỏ qua dành cho Junior Web Developer / Designer

Một Interior Designer giỏi cần những kỹ năng gì?

Tùy vào vị trí cụ thể bạn làm việc mà yêu cầu cho vị trí đó sẽ được liệt kê cụ thể trong mô tả chi tiết công việc của nhà tuyển dụng. Nhưng về cơ bản, một nhà thiết kế nội thất cần có bằng cử nhân chuyên ngành thiết kế hoặc các chứng chỉ liên quan đến kỹ năng thiết kế để chứng minh được năng lực và trình độ của mình.

kỹ năng của interior designer
Những kỹ năng cần có của Interior Designer

Đối với những vị trí yêu cầu kinh nghiệm thì việc đã từng có kinh nghiệm quản lý dự án, thiết kế dự án và làm việc với các đội ngũ thi công trước đây chắc chắn sẽ giúp ích rất nhiều cho công việc của bạn. Ngoài ra, việc không thể thiếu là một nhà thiết kế nội thất cần thành thạo sử dụng các thiết bị như Illustrator, AutoCAD, SketchUp hoặc phần mềm thiết kế tương tự.

Bên cạnh đó, khả năng sáng tạo không ngừng, giàu trí tưởng tượng và tính thẩm mỹ cao chắc chắn sẽ giúp nhà thiết kế cho ra đời những sản phẩm ấn tượng nhất. Khả năng giao tiếp trôi chảy và diễn đạt thành thạo vấn đề cũng sẽ giúp bạn làm tốt hơn vai trò của mình trong suốt quá trình làm việc với khách hàng và nhân viên.

Đi theo nhu cầu phát triển của xã hội, vai trò của các nhà thiết kế nội thất ngày càng được chú trọng hơn cho một môi trường sống và làm việc thoải mái, thư giãn. Hi vọng bài viết trên đây sẽ phần nào giúp bạn hiểu được khái niệm interior designer là gì cũng như những cơ hội nghề nghiệp của ngành này ở thời điểm hiện tại. Đón đọc thêm nhiều bài viết hấp dẫn khác tại TopDev bạn nhé!

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Sử dụng Hibernate Tool tạo các Hibernate Entity một cách tự động từ các table

hibernate entity
Sử dụng Hibernate Tool tạo các Hibernate Entity một cách tự động từ các table

Bài viết được sự cho phép của tác giả Giang Phan

Trong bài viết trước tôi đã giới thiệu với các bạn các Annotation của Hibernate và cách tạo các Entity từ các table của database. Trong bài viết này, tôi sẽ hướng dẫn các bạn có thể tạo tự động ra các Entity mapping database và Annotation code nhanh chóng bằng việc sử dụng công cụ Hibernate Tool.

Chuẩn bị

Công cụ và môi trường phát triển

  • Java 8
  • Eclipse
  • MySQL
  • JBoss / Hibernate Tools
  Hibernate Batch processing
  Hibernate Interceptor & StatementInspector

Xem thêm các việc làm Entity hấp dẫn trên TopDev

Cơ sở dữ liệu

Chúng ta có mộ hình cơ sở quan hệ các table như sau:

Tạo database và chạy sql sau để tạo các bảng sử dụng trong bài viết này. Chẳng hạn tạo database, gp_cms_system.

Cài đặt Hibernate Tool vào Eclipse

Tìm link download Jboss tool tại đây: https://tools.jboss.org/downloads/

Có 2 cách để cài JBoss Tools vào Eclipse, tương tự như cài các plugin Eclipse khác.

  • Cài đặt từ “Update site”.
  • Cài đặt từ Eclipse Marketplace.

Cài đặt từ “Update site”

Help -> Install New Software …

Tại cửa sổ cài đặt chọn Add :

JBoss tools có nhiều công cụ, chúng ta chỉ cần sử dụng Hibernate nên sẽ tìm và cài đặt các Hibernate item.

Các bạn chọn Next -> chọn Accept terms và Finish.

Cài đặt từ Eclipse Marketplace

Help -> Eclipse Marketplace…

Tại cửa sổ “Eclipse Marketplace…”, cài bạn tìm jboss và chọn Install.

JBoss Tools có rất nhiều công cụ, chúng ta chỉ cần chọn “Hibernate Tools”.

Các bạn chọn Next -> chọn Accept terms và Finish.

Để chắc chắn đã cài đặt thành công, trên menu Eclipse chọn: Window -> Perspective -> Open Perspective -> Other…

Chọn Hibernate -> Open.

Kết nối vào Database thông qua “Database Development”

Trên menu Eclipse chọn: Window -> Perspective -> Open Perspective -> Other…

Tạo mới một connection tới cơ sở dữ liệu trên.

Chọn loại cơ sở dữ liệu: trong bài này tôi sẽ kết nối tới cơ sở dữ liệu MySQL.

Thêm Driver cho database MySQL (trường hợp đã có rồi không cần thêm mới).

Tiếp theo cần add MySQL connector:

Nhập các thông tin để kết nối tới database -> nhấn “Test Connection” để đảm bảo rằng việc kết nối tới database là thành công -> OK

Kiểm tra lại cấu trúc database trên “Data Source Explorer”:

Tạo Maven Project

Tạo maven project và trong file pom.xml khai báo thư viện Hibernate 5, và thư viện JDBC tương ứng cho MySQL. Nội dung file pom.xml như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.gpcoder</groupId>
    <artifactId>HibernateTutorial</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
 
    <name>HibernateTutorial</name>
    <url>http://maven.apache.org</url>
 
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
 
    <dependencies>
 
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
 
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.7.Final</version>
        </dependency>
 
        <!-- MySQL -->
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
 
        <!-- Unit Test -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Cấu hình Hibenate

Mở cửa sổ công cụ Hibernate Tools

Trên menu Eclipse chọn: Window -> Perspective -> Open Perspective -> Other… -> Hibernate

Khởi tạo file Hibernate Configuration

Nhấn phải chuột -> chọn “Add Configuration..” để tạo mới file cấu hình Hibernate.

Nhập các thông tin như sau:

Tại (6), chọn Setup… và chọn tạo mới file hibernate.cfg.xml

Nhập vào tên file “hibernate.cfg.xml”, và đặt nó vào thư mục “src/main/java” của Project.

Nhập các thông tin kết nối tới database hoặc lấy từ thông tin kết nối đã khai báo trước đó.

Chọn “Database dialect” tương ứng với loại Database MySQL.

Nhấn Finish -> một file cấu hình Hibernate được tạo ra trong thư mục src/main/java.

Nội dung file hibernate.cfg.xml như sau:

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/gp_cms_system?serverTimezone=UTC</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    </session-factory>
</hibernate-configuration>

Hibernate Configuration được tạo:

Tạo tự động các Entity mapping & Annation codes

Tiếp theo chúng ta sẽ cấu hình cách để công cụ tạo ra các lớp entity từ việc đọc cấu trúc bảng trong Database.

Tại Hibernate Perspective, chọn Hibernate Code Generation Configurations…

Nhấn chuột phải và chọn New Configuration:

Cấu hình Hibernate Generation:

  • (1) : nhập tên cấu hình.
  • (2) : chọn Hibernate Configuration đã tạo ở trên.
  • (3) : chọn thư mục chứa các Entity được tạo.
  • (4) : package chứa các Entity.
  • (6) : tạo file reveng.xml
  • (6) : check các option để Hibernate khởi tạo quan hệ các Entity, Id.

Tạo file reveng.xml, chọn (5) Setup:

Chọn thư mục chứa file là src/main/java, để tên file mặc định và chọn Next.

Chọn các bảng cần tạo tự động và chọn Finish.

Sau bước này, chúng ta sẽ có một file reveng.xml trong thư mục src/main/java.

Tiếp theo, chọn Tab Exporters và thiết lập tạo tự động các Entity mapping và Annotation code:

  • (1) : Tạo java class sử dụng Java 5 syntax và chuẩn EJP3 Annotation.
  • (2) : Tạo Entity java class và các Annotation.
  • (3) : Tạo các mapping database.

Kết quả sau khi Generate thành công:

Nội dung của một vài class được Generate tự động:

Category.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package com.gpcoder.entities;
// Generated Nov 26, 2019 1:41:36 AM by Hibernate Tools 4.3.5.Final
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
 * Category generated by hbm2java
 */
@Entity
@Table(name = "category", catalog = "gp_cms_system")
public class Category implements java.io.Serializable {
    private long id;
    private String name;
    private Set<Post> posts = new HashSet<Post>(0);
    public Category() {
    }
    public Category(long id) {
        this.id = id;
    }
    public Category(long id, String name, Set<Post> posts) {
        this.id = id;
        this.name = name;
        this.posts = posts;
    }
    @Id
    @Column(name = "id", unique = true, nullable = false)
    public long getId() {
        return this.id;
    }
    public void setId(long id) {
        this.id = id;
    }
    @Column(name = "name")
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "category")
    public Set<Post> getPosts() {
        return this.posts;
    }
    public void setPosts(Set<Post> posts) {
        this.posts = posts;
    }
}

Post.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package com.gpcoder.entities;
// Generated Nov 26, 2019 1:41:36 AM by Hibernate Tools 4.3.5.Final
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
/**
 * Post generated by hbm2java
 */
@Entity
@Table(name = "post", catalog = "gp_cms_system")
public class Post implements java.io.Serializable {
    private long id;
    private Category category;
    private User user;
    private String title;
    private String content;
    public Post() {
    }
    public Post(long id) {
        this.id = id;
    }
    public Post(long id, Category category, User user, String title, String content) {
        this.id = id;
        this.category = category;
        this.user = user;
        this.title = title;
        this.content = content;
    }
    @Id
    @Column(name = "id", unique = true, nullable = false)
    public long getId() {
        return this.id;
    }
    public void setId(long id) {
        this.id = id;
    }
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "category_id")
    public Category getCategory() {
        return this.category;
    }
    public void setCategory(Category category) {
        this.category = category;
    }
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id")
    public User getUser() {
        return this.user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    @Column(name = "title")
    public String getTitle() {
        return this.title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    @Column(name = "content")
    public String getContent() {
        return this.content;
    }
    public void setContent(String content) {
        this.content = content;
    }
}

Tài liệu tham khảo:

Bài viết gốc được đăng tải tại gpcoder.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Cấu hình expiration time cho access token với Spring Authorization Server

expiration time
Cấu hình expiration time cho access token với Spring Authorization Server

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

Một ưu điểm lớn của OAuth2 là có thể cho phép chúng ta giới hạn khoảng thời gian mà một request với access token cụ thể được phép sử dụng resources. Access token sẽ quy định expiration time của nó, cái API resources sẽ dựa vào expiration time này để quyết định có cho phép Client Application tiếp tục truy cập resource hay là không? Sử dụng Spring Authorization Server để implement Authorization Server thì cách cấu hình expiration time cho access token như thế nào? Chúng ta sẽ cùng nhau tìm hiểu trong bài viết này các bạn nhé!

  Bảo mật ứng dụng Java web bởi Spring Security
  Cách sử dụng properties trong tập tin cấu hình của Spring

Xem thêm nhiều việc làm Spring lương cao trên TopDev

Điều đầu tiên các bạn cần biết là, chúng ta sẽ sử dụng class TokenSettings của Spring Authorization Server để cấu hình một số thông tin liên quan đến access token. Hiện tại, các bạn có thể cấu hình expiration time, reuse refresh token, refresh token expiration time, ID token signature algorithm.

Để cấu hình expiration time ở mức system level, apply hết cho tất cả các client trong hệ thống, các bạn có thể định nghĩa một bean của TokenSettings như sau:

@Bean
public TokenSettings tokenSettings() {
// @formatter:off
return TokenSettings.builder()
.accessTokenTimeToLive(Duration.ofMinutes(30L))
.build();
// @formatter:on
}

Sau đó thì trong khai báo của mỗi RegisteredClient, các bạn khai báo thêm thông tin về tokenSettings như sau:

// @formatter:off
RegisteredClient registeredClient = RegisteredClient.withId(UUID.randomUUID().toString())
.clientId("huongdanjava1")
.clientSecret("{noop}123")
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST)
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.tokenSettings(tokenSettings())
.build();
// @formatter:on

Này là mình khai báo RegisteredClient với TokenSettings trong một Java class file, nếu các bạn định nghĩa trong 2 class file khác nhau thì có thể sử dụng @Autowired annotation thì inject bean của TokenSettings vào rồi sử dụng nó trong method tokenSettings() của RegisteredClient.

Nếu các bạn muốn specific expiration time cho riêng mỗi RegisteredClient thì hãy khởi tạo mới và sử dụng đối tượng TokenSettings cho đối tượng RegisteredClient đó nhé.

Chạy ví dụ trong bài viết Hiện thực OAuth Authorization Server sử dụng Spring Authorization Server với cấu hình TokenSettings như trên:

sau đó parse nội dung của access token sử dụng https://jwt.io/, các bạn sẽ thấy thời điểm issue access token là:

và thời gian expire là:

Expiration time mặc định của một access token trong Spring Authorization Server là 5 phút các bạn nhé!

Bài viết gốc được đăng tải tại huongdanjava.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Lập trình web cơ bản với PHP (P2)

lập trình php
Lập trình web cơ bản với PHP (P2)

Bài viết được sự cho phép của smartjob.vn

Lập trình web cơ bản với PHP – Giải thích một số thuật ngữ

Thế nào là lập trình hướng đối tượng?

Để học lập trình web cơ bản với PHP, trước hết nên hiểu việc lập trình hướng đối tượng (OOP) là gì. Với nhiều sinh viên, đó là khái niệm khá trừu tượng, khó hiểu, khiến họ khó nắm bắt được PHP hay các ngôn ngữ khác. Tuy nhiên nếu bạn đã hiểu bản chất của nó thì công việc lập trình của bạn sẽ trở nên đơn giản hơn rất nhiều.

Lập trình hướng đối tượng là phương pháp viết mà cho phép người lập trình nhóm các action tương ứng vào các class. Việc này khiến cho mã lệnh có thể giữ vững nguyên lý DRY – don’t repeat yourself (không lặp lại chính nó) và dễ dàng hơn trong việc bảo trì.

Xem thêm nhiều việc làm PHP lương cao trên TopDev

Nguyên lý DRY có rất nhiều lợi ích, một trong số đó là nếu 1 phần thông tin bị thay đổi thì bạn chỉ cần một thay đổi để cập nhật lại mã lệnh.

Biến và hằng

  1. Biến
  • Là vùng nhớ dữ liệu tạm thời, giá trị của biến có thể thay đổi được
  • Được bắt đầu bằng ký hiệu $, sau đó là một từ hoặc một cụm từ viết liền hay gạch dưới
  • Biến được bắt đầu bằng 1 ký tự hoặc dấu gạch dưới “_”
  • Tên biến chỉ được phép chứa các ký tự từ a đến z, không được bắt đầu bằng một ký tự số, trong biến có thể viết các số từ 0 đến 9 và dầu gạch dưới
  • Tên biến phân biệt chữ hoa và chữ thường

2.  Hằng

  • Hằng là những thứ chúng ta không thay đổi được
  • Cú pháp: define (string ten_hang, gia_tri_cua_hang)
  • Không có dấu $ trước tên
  • Có thể truy cập ở mọi vị trí trong mã lệnh
  • Chỉ được phép gán giá trí duy nhất một lần
  • Thường được viết bằng chữ in để phân biệt với biến

Ngoài ra còn nhiều chú ý khi sử dụng hằng và biến không nằm trong phần lập trình web cơ bản lần này, chúng tôi sẽ giới thiệu và phân tích chuyên sâu trong các mục Blog.

  10 câu nói cực hay về lập trình
  10 PHP Instagram Scripts & Widgets tốt nhất

Objects và Class

Object – Đối tượng là thực thể mang cả tính vật lý và tính logic trong khi đó lớp (class) chỉ là thực thể logic.

Class – Lớp là 1 nhóm các đối tượng có các thuộc tính chung.

Có thể minh họa về lớp và đối tượng như hình dưới đây, các bạn có thể dễ dàng phân biệt hai khái niệm này.

Khi code, chúng ta sử dụng class và object và gọi đó là lập trình hướng đối tượng. Như vậy, chúng ta không nên mất công nghĩ xa xôi về thuật ngữ “lập trình hướng đối tượng”, đó đơn thuần là những việc ta sẽ làm khi code. Loạt bài về lập trình web cơ bản với PHP sẽ tạm dừng tại đây. Các bạn có thể tham khảo thêm tại đây nếu muốn tìm hiểu chuyên sâu về ngôn ngữ này.

Bài viết gốc được đăng tải tại smartjob.vn

Có thể bạn quan tâm:

Xem thêm việc làm IT hấp dẫn trên TopDev

Tạo database table tự động từ Hibernate Entity

hibernate entity
Tạo database table tự động từ Hibernate Entity

Bài viết được sự cho phép của tác giả Giang Phan

Trong bài trước tôi đã hướng dẫn các bạn sử dụng các Annotation và mapping type để tạo các Hibernate Entity cho các table trong database. Giả sử bây giờ chúng ta không có database từ trước, khách hàng chỉ cung cấp source code với các Hibernate Entity. Để chạy được ứng dụng chúng ta cần phải có database để lưu trữ dữ liệu. Chúng ta, có thể tạo database và tạo từng table cũng như các quan hệ của nó một cách thủ công. Tuy nhiên, cách làm này tốn rất nhiều công sức, dễ sai sót và không cần thiết.

  Hibernate Criteria Query Language (HCQL)
  Hibernate Batch processing

Xem thêm các việc làm Entity lương cao trên TopDev

Với Hibernate, nó đã cung cấp một tính năng rất tiện lợi và dễ dàng cấu hình để tạo các table một cách tự động dựa vào các Hibernate Entity. Chúng ta sẽ cùng tìm hiểu trong bài viết này.

Các bước thực hiện khá đơn giản:

  • Tạo các Hibernate Entity với đầy đủ các Annotation và mapping type.
  • Tạo hibernate configuration file.
  • Tạo Hibernate connection class để giao tiếp với database.

Tạo các Hibernate Entity

Mô hình cơ sở quan hệ các table như sau:

Tương ứng với database, chúng ta có các Hibernate Entity:

Role.java

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;


import lombok.Data;


@Data
@Entity
@Table
public class Role {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;


    @Column
    private String name;
    
    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles")
    private Set<User> users;
}

User.java

import java.util.Date;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

import lombok.Data;

@Data
@Entity(name = "User")
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String fullname;

    @Column(nullable = false, length = 255, unique = true)
    private String username;

    @Column(nullable = false)
    private String password;

    @Column(name = "created_at")
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date createdAt;

    @Column(name = "modified_at")
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date modifiedAt;

    @Transient
    private String additionalPropery;
    
    @OneToOne(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL)
    private UserProfile userProfile;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    @OrderBy("title")
    private Set<Post> posts;
    
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "user_roles",
        joinColumns = { @JoinColumn(name = "user_id", nullable = false, updatable = false) },
        inverseJoinColumns = { @JoinColumn(name = "role_id", nullable = false, updatable = false) })
    @OrderBy("name")
    private Set<Role> roles;
}

UserProfile.java

import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

import lombok.Data;

@Data
@Entity
@Table(name = "user_profile")
public class UserProfile {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String address;

    private Integer gender;

    @OneToOne(fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn(name = "user_id", foreignKey = @ForeignKey(name = "fk_user_profile"))
    private User user;
}

Category.java

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;

import lombok.Data;

@Data
@Entity
@Table
public class Category {

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String name;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "category")
    @OrderBy("title")
    private Set<Post> posts;
}

Post.java

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import lombok.Data;

@Data
@Entity
@Table
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String title;

    private Integer content;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false,
        foreignKey = @ForeignKey(name = "fk_post_user"))
    private User user;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "category_id", nullable = false,
        foreignKey = @ForeignKey(name = "fk_post_category"))
    private Category category;
}

Tạo hibernate configuration file

Để tạo một cách tự động chúng ta cần thêm một property hibernate.hbm2ddl.auto trong Hibernate confirugation file.

Cấu hình hbm2ddl có nghĩa là Hibernate mapping để tạo lược đồ DDL (Data Definition Language – ngôn ngữ định nghĩa dữ liệu) một cách tự động.

Cấu hình này có thể có các giá trị sau:

  • create : Nếu giá trị này được sử dụng, Hibernate sẽ xóa tất cả các table và structure. Sau đó, tạo lại các table mới dựa vào Hibernate Entity. Lưu ý khi sử dụng giá trị này, các dữ liệu của chúng ta sẽ bị mất và không thể phục hồi lại được.
  • validate : Nếu giá trị này được sử dụng, Hibernate chỉ validate các table structure ở đó các table và column tồn tại hay không. Nếu table không tồn tại, Hibernate sẽ throw một Exception.
  • update : Nếu giá trị này được sử dụng, Hibernate sẽ kiểm tra table tồn tại hay không. Nếu không tồn tại, table mới sẽ được tạo. Tương tự với column, nếu column không tồn tại, Hibernate sẽ tạo một column mới. Với giá trị update này, các table sẽ không được xóa nên dữ liệu của chúng ta không bị mất.
  • create-drop : Nếu giá trị này được sử dụng, Hibernate sẽ tạo các table structure để thực hiện các thao tác và các table structure sẽ được xóa sau khi các thao tác đã hoàn thành (SessionFactory đã đóng). Giá trị này thích hợp khi viết Unit test cho Hibernate code.

Tạo file hibernate.cfg.xml trong thư mục src\main\resources của project với nội dung như sau:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>
        <!-- Database setting -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/gp_system_auto?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8</property>
        <property name="connection.username">root</property>
        <property name="connection.password"></property>
        
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">4</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Show all executed SQL to console -->
        <property name="show_sql">true</property>
        
        <!-- Automatically validates or exports schema DDL to the database when the SessionFactory is created -->
        <!-- validate, create, update, create-drop -->
        <property name="hibernate.hbm2ddl.auto">create-drop</property>

        <!-- Entity mapping -->
        <mapping class="com.gpcoder.models.User" />
        <mapping class="com.gpcoder.models.Role" />
        <mapping class="com.gpcoder.models.UserProfile" />
        <mapping class="com.gpcoder.models.Category" />
        <mapping class="com.gpcoder.models.Post" />
        
    </session-factory>
</hibernate-configuration>

Tạo Hibernate connection class

HibernateUtils.java

import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;

public class HibernateUtils {

    private static final SessionFactory sessionFactory = buildSessionFactory();

    private HibernateUtils() {
        super();
    }

    private static SessionFactory buildSessionFactory() {
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() //
                .configure() // Load hibernate.cfg.xml from resource folder by default
                .build();
        Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build();
        return metadata.getSessionFactoryBuilder().build();
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }

    public static void close() {
        getSessionFactory().close();
    }
}

Tạo chương trình truy vấn các Entity trên để kiểm tra kết quả:

import org.hibernate.Session;

import com.gpcoder.models.Category;
import com.gpcoder.utils.HibernateUtils;

public class HibernateExample2 {

public static void main(String[] args) {
        
        try (Session session = HibernateUtils.getSessionFactory().openSession();) {
            // Begin a unit of work
            session.beginTransaction();

            // Insert user
            Category cat = new Category();
            cat.setName("cat " + System.currentTimeMillis());
            System.out.println("Cat id = " + session.save(cat));
            
            // Commit the current resource transaction, writing any unflushed changes to the database.
            session.getTransaction().commit();
        }
    }
}

Tạo database gp_system_auto và chạy chương trình trên. Chúng ta có output chương trình như sau

INFO: HHH000115: Hibernate connection pool size: 4 (min=1)
Dec 15, 2019 9:58:11 PM org.hibernate.dialect.Dialect <init>
INFO: HHH000400: Using dialect: org.hibernate.dialect.MySQL5Dialect
Hibernate: drop table if exists Category
Dec 15, 2019 9:58:13 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@22d1886d] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: drop table if exists Post
Hibernate: drop table if exists Role
Hibernate: drop table if exists user
Hibernate: drop table if exists user_profile
Hibernate: drop table if exists user_roles
Hibernate: create table Category (id bigint not null auto_increment, name varchar(255), primary key (id)) engine=MyISAM
Dec 15, 2019 9:58:13 PM org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl getIsolatedConnection
INFO: HHH10001501: Connection obtained from JdbcConnectionAccess [org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess@68ba310d] for (non-JTA) DDL execution was not in auto-commit mode; the Connection 'local transaction' will be committed and the Connection will be set into auto-commit mode.
Hibernate: create table Post (id bigint not null auto_increment, content integer, title varchar(255), category_id bigint not null, user_id bigint not null, primary key (id)) engine=MyISAM
Hibernate: create table Role (id bigint not null auto_increment, name varchar(255), primary key (id)) engine=MyISAM
Hibernate: create table user (id bigint not null auto_increment, created_at datetime, fullname varchar(255), modified_at datetime, password varchar(255) not null, username varchar(255) not null, primary key (id)) engine=MyISAM
Hibernate: create table user_profile (id bigint not null auto_increment, address varchar(255), gender integer, primary key (id)) engine=MyISAM
Hibernate: create table user_roles (user_id bigint not null, role_id bigint not null, primary key (user_id, role_id)) engine=MyISAM
Hibernate: alter table user add constraint UK_sb8bbouer5wak8vyiiy4pf2bx unique (username)
Hibernate: alter table Post add constraint fk_post_category foreign key (category_id) references Category (id)
Hibernate: alter table Post add constraint fk_post_user foreign key (user_id) references user (id)
Hibernate: alter table user_roles add constraint FKbhgxpici80n5kpvs65q90ou14 foreign key (role_id) references Role (id)
Hibernate: alter table user_roles add constraint FK55itppkw3i07do3h7qoclqd4k foreign key (user_id) references user (id)
Hibernate: insert into Category (name) values (?)
Cat id = 1

Như bạn thấy, Hibernate tự generate các câu lệnh tạo table, có ràng buộc và sau đó thực thi các sql cần thiết.

Kiểm tra database, bạn sẽ thấy các table được tạo ra như sau:

Các bạn lưu ý, trong ví trên tôi sử dụng cấu hình hibernate.hbm2ddl.auto=create-drop . Các bạn có thể thay đổi các giá trị khác và chạy thử để kiểm tra kết quả.

Bài viết đến đây là hết. Cám ơn các bạn đã quan tâm và theo dõi.

Bài viết gốc được đăng tải tại gpcoder.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Caching với EhCache

Caching vs EhCache
Caching với EhCache

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

Caching đôi khi là một vấn đề rất quan trọng của một số ứng dụng với số lượng request của người dùng rất nhiều. Nó vừa giải quyết các vấn đề về performance của ứng dụng và giảm thiểu các thao tác I/O liên quan đến ứng dụng. Trong bài viết này, mình giới thiệu với các bạn về EhCache, một open-source về caching được rất nhiều người sử dụng.

  Bộ Đệm - Caching
  Cấu hình Redis Caching để tăng tốc site WordPress của bạn

Đầu tiên, mình sẽ tạo mới một Maven project để làm ví dụ:

với EhCache dependency như sau:

<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.9.6</version>
</dependency

Để làm ví dụ cho bài viết này, mình sẽ sử dụng EhCache để lưu thông tin user và chúng ta có thể retrieve thông tin user từ cache sử dụng ID của user đó.

Mình sẽ tạo mới class để chứa thông tin user:

package com.huongdanjava.ehcache;

public class User {

private Long id;
private String name;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

và class main để chạy ứng dụng có nội dung ban đầu như sau:

package com.huongdanjava.ehcache;

public class Application {

public static void main(String[] args) {

}
}

Đối tượng quản lý cache trong EhCache là đối tượng Cache và để có được đối tượng này, điều đầu tiên các bạn cần phải làm là tạo mới đối tượng CacheManager, sử dụng class CacheManagerBuilder như sau:

CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.build(true);

Ở đây, mình khởi tạo CacheManager mà không có bất kỳ cấu hình thêm nào cả. Các bạn có thể trong lúc khởi tạo CacheManager thì khởi tạo thêm một số Cache mà mình muốn. Mình thì muốn rạch ròi ra nên mình sẽ khởi tạo đối tượng Cache sau.

Bây giờ thì các bạn có thể sử dụng phương thức createCache() của CacheManager để tạo mới đối tượng Cache cho mình. Phương thức createCache() này có 2 phương thức overload với tham số chung đầu tiên của 2 method này là tên của cache. Còn tham số thứ hai thì liên quan đến cấu hình của cache.

<K, V> Cache<K, V> createCache(String alias, CacheConfiguration<K, V> config)

và:

<K, V> Cache<K, V> createCache(String alias, Builder<? extends CacheConfiguration<K, V>> configBuilder);

Các bạn hãy nhớ là, chúng ta sẽ lưu cache bằng key và value, lấy value bằng key. Mỗi cache sẽ có tên, giúp chúng ta có thể khai báo cache nào chúng ta cần lấy thông tin. Khi khởi tạo cache, chúng ta sẽ cần phải khai báo kiểu dữ liệu của key và value trong mỗi cache.

Ví dụ trên của mình, thì mình sẽ lưu cache với key là ID với kiểu dữ liệu là Long, còn Value của mình sẽ kiểu dữ liệu là User như sau;

Cache<Long, User> userCache = cacheManager.createCache("user", CacheConfigurationBuilder
.newCacheConfigurationBuilder(
Long.class, User.class,
ResourcePoolsBuilder.heap(10)));

Đoạn code trên mình sử dụng class CacheConfigurationBuilder để khai báo thông tin cấu hình của cache “user”. Chúng ta sử dụng class ResourcePoolsBuilder với phương thức static heap() để khai báo số lượng thông tin có trong một cache.

Bây giờ thì chúng ta có thể lưu trữ thông tin cache sử dụng phương thức put() như sau:

User user = new User();
user.setId(1L);
user.setName("Khanh");

userCache.put(user.getId(), user);

Sau khi đã có thông tin trong cache thì các bạn cũng có thể lấy thông tin trong cache ra như sau:

Cache<Long, User> userCache1 = cacheManager.getCache("user", Long.class, User.class);
User user1 = userCache1.get(1L);
System.out.println(user1.getName());

Kết quả:

Có thể bạn quan tâm:
Xem thêm Việc làm IT hấp dẫn trên TopDev

Công nghệ nào đã làm thay đổi cả thế giới? Phần #1

công nghệ
Công nghệ nào đã làm thay đổi cả thế giới? Phần #1

Bài viết được sự cho phép của blogchiasekienthuc.com

Thế giới đang thay đổi từng ngày và kéo theo đó là những biến chuyển không ngừng của xã hội, tất nhiên là theo hướng tích cực hơn.

Xuyên suốt trong hơn một phần tư thế kỷ qua, nền văn minh nhân loại đã có những bước tiến rất dài nhờ những công nghệ được tạo ra bởi chính những bộ óc sáng tạo của con người.

Tất nhiên là sẽ có mặt tích cực lẫn tiêu cực, nhưng chúng ta không thể phủ nhận một điều là những công nghệ ấy đã và đang góp phần làm thay đổi cuộc sống hằng ngày của chúng ta. Rất nhiều !

  "Khi công nghệ không chỉ dành cho nam giới" - Lea Trúc, Founder của Women Meet Tech
  1001 câu hỏi của học sinh cuối cấp muốn theo đuổi ngành công nghệ thông tin

Vậy đâu là công nghệ đột phá và có những bước tiến mạnh mẽ nhất trong một thế kỷ qua? Và chúng đã có tác động đến cuộc sống của chúng ta như thế nào? Mời các bạn hãy cùng mình tìm hiểu kỹ hơn ngay trong bài viết lần này nhé !

#1. Internet

nhung-cong-nghe-lam-thay-doi-the-gioi (1)

Nguồn gốc của Internet hiện nay có tiền thân là từ mạng ARPANET, cơ quan quản lý dự án thuộc Bộ quốc phòng Hoa Kỳ ủy quyền thực hiện vào những thập niên 60 của thế khỉ XX.

Về căn bản, Internet được biết đến giống như một hệ thống thông tin toàn cầu, có thể truy cập công cộng được và nó bao gồm các mạng máy tính liên kết lại với nhau.

Cách đây rất nhiều thập kỷ, khi mà Internet không thịnh hành thì mọi thông tin liên lạc, giao tiếp với bên ngoài là một điều gì đó vô cùng khó khăn.

Nhưng các bạn hãy nhìn vào thời điểm hiện tại, Internet đang phát triển một cách thần tốc và là một dịch vụ tuyệt vời để chúng ta có thể dễ dàng tra cứu thông tin, lướt web, mua hàng online, giao tiếp, kết nối với bạn bè gần xa, bất chấp khoảng cách địa lý, xóa nhòa mọi ranh giới …

Không cần nói đâu xa, chỉ cần bạn thuộc thế hệ 8x, 9x thôi là bạn đã thấy được sự khác biệt rõ ràng như thế nào rồi. Khoảng 10 năm về trước, tốc độ mạng như thế nào? để tải được một bộ phim 3 – 4 GB thôi có khi mất cả buổi sáng hoặc nguyên ngày. Còn bây giờ á, nhanh thì chỉ mất vài phút là xong.

Với sự thịnh hành và phát triển thần tốc như vậy thì Internet hiện nay đang là một mạng lưới khủng khiếp nhất trên toàn thế giới, đem đến sự phát triển của nhiều ngành dịch vụ và nó đã dẫn chúng ta đến một kỷ nguyên của thương mại điện tử Internet. Con người sẽ ngày càng phụ thuộc hơn vào Internet trong mọi mặt của cuộc sống.

Bên cạnh những tác động tích cực thì việc Internet phát triển quá mạnh cũng mang lại không ít những tiêu cực cho con người.

Ví dụ như tội phạm mạng hoành hành, nạn đánh cắp thông tin cá nhân, và nếu bạn không biết cách chắt lọc thông tin để xem thì sẽ rất dễ có những suy nghĩ lệch lạc…

#2. WiFi

nhung-cong-nghe-lam-thay-doi-the-gioi (2)

WiFi (Wireless Fidelity) là một phương thức kết nối không dây sử dụng sóng vô tuyến và được triển khai trên hầu hết các thiết bị điện tử thông minh ngày nay.

Vào thời điểm trước những năm 1996 thì máy tính luôn phải phụ thuộc vào những sợi dây cáp tín hiệu để cắm vào những chiếc máy tính thì mới có thể truy cập được Internet.

Chính vì thế, việc WiFi ra đời đã giúp cho việc kết nối Internet được đơn giản hơn, có thể ứng dụng vào được nhiều thiết bị hơn, và có thể nói đây là một bước tiến dài của Internet.

Bằng chứng là hiện nay, chúng ta chẳng cần phải cắm mặt cả tiếng đồng hồ vào chiếc máy tính để truy cập Internet nữa.

Mà thay vào đó, chỉ với những chiếc smartphone nhỏ gọn trong tay thôi là bạn đã có thể kết nối vào mạng Internet thông qua WiFi, 4G, 5G… được rồi, bạn có thể tìm kiếm bất cứ thông tin gì bạn muốn..

#3. Bluetooth

nhung-cong-nghe-lam-thay-doi-the-gioi (3)

Bluetooth có lẽ là một khái niệm đã quá quen thuộc với chúng ta, nhưng dành cho những bạn nào chưa biết thì Bluetooth là một chuẩn công nghệ truyền thông không dây tầm gần giữa các thiết bị điện tử, sử dụng giải tần 2,4 GHz và tốc độ truyền dữ liệu có thể lên đến 1Mb/s.

Bluetooth lần đầu được phát triển bởi một kỹ sư điện tử của Ericcson vào năm 1994 và chính thức được chuẩn hóa, công bố rộng rãi vào ngày 5 tháng 9 năm 1999.

Thuật ngữ Bluetooth được đặt tên theo tên của một vị vua người Đan Mạch (Harald Bluetooth) – vị vua đã mang đạo Tin Lành vào Đan Mạch.

Vào thời điểm ban đầu khi vừa mới được ra mắt thì Bluetooth chủ yếu dùng để giúp điện thoại kết nối với tai nghe không dây là chính, nhưng càng về sau thì công nghệ này càng được đem vào ứng dụng nhiều.

Cụ thể thì ở thời điểm hiện tại, ta có thể bắt gặp Bluetooth trên rất nhiều các thiết bị công nghệ khác nhau như tai nghe, loa di động, đồng hồ thông minh, bàn phím, chuột, bút chỉ slide …

Dù Bluetooth cũng có khá nhiều mặt hạn chế, và phạm vi kết nối không thể được như WiFi nhưng tầm ảnh hưởng và sự tác động của nó đến cuộc sống của chúng ta là không phải bàn cãi.

Nếu bạn muốn xem thêm thông tin về Bluetooh thì có thể tham khảo trên Wikipedia tại đây !

#4. Trí tuệ nhân tạo AI

nhung-cong-nghe-lam-thay-doi-the-gioi (4)

Trí tuệ nhân tạo (Artificial Intelligence) là một ngành thuộc lĩnh vực khoa học máy tính và hiện tại thì nó đang là một trong những ngành vô cùng quan trọng, được rất nhiều công ty/ tập đoàn công nghệ chú trọng đến.

Trong một thời đại số, khi mà máy móc đang ngày một chiếm ưu thế thì công nghệ AI lại càng phát triển mạnh mẽ hơn nữa. Và minh chứng cho điều đó là việc AI đang được ứng dụng trong thực tế ngày một nhiều, rất nhiều những sản phẩm AI ra đời..

Hiện nay, AI đã được đem vào các lĩnh vực như kinh doanh, giáo dục, tài chính, giao thông vận tải, sản xuất, bảo mật, điện thoại thông minh,…

Tuy vậy nhưng AI cũng mang đến rất nhiều mặt tiêu cực, quan ngại nhất chính là việc nó cướp đi việc làm của những người lao động chân tay, làm gia tăng tỷ lệ thất nghiệp trên toàn cầu..

Không chỉ dừng lại ở đó, một số nhà khoa học còn lo ngại rằng khi AI đã vượt quá tầm kiểm soát của con người thì sẽ dẫn đến rất nhiều những hậu quả khôn lường, như sự bùng nổ của máy móc và kinh khủng nhất là kịch bản ngày tận thế – Robot thống trị nhân loại.

#5. Bitcoin

nhung-cong-nghe-lam-thay-doi-the-gioi (5)

Bitcoin là một loại tiền mã hóa, đồng tiền số… được phát triển bởi Satoshi Nakamoto. Bitcoin được ra mắt vào năm 2009, nhưng đến tận hơn 5 năm sau thì cả thế giới mới chú ý đến sự tồn tại của nó.

Về căn bản thì Bitcoin có cách hoạt động khác hoàn toàn so với các đơn vị tiền tệ khác trên thế giới như USD, bảng Anh, VNĐ, … và cũng chẳng có một ngân hàng trung ương nào quản lý nó cả (vì nó là tiền ảo mà ^^).

Bitcoin đã khiến cho cả thế giới phải định hình lại khái niệm của một loại tiền tệ không thể cầm trên tay, mà nó chỉ thể hiện thông qua những con số.

Nó là sự hợp nhất giữa rất nhiều lĩnh vực và yếu tố khác nhau: như tài chính, công nghệ, tiền tệ, toán học và thậm chí là cả xã hội học.

Trong vòng 4 năm trở lại đây thì Bitcoin đang nổi lên như cồn trên các mạng xã hội và điều đó đã vô tình khiến nó bị những kẻ xấu lợi dụng, trở thành chiêu trò lừa đảo của nhiều đối tượng nhằm chiếm đoạt tài sản của những người nhẹ dạ cả tin.

(Nếu không tin thì bạn cứ thử tra cứu trên Google mà xem, sẽ có vô số kết quả về những vụ lừa đảo gây chấn động từ cơn sốt Bitcoin)

Dù cho Bitcoin không hề xấu nhưng chính những chiêu trò lừa đảo với lời lẽ ngon ngọt của kẻ xấu đã khiến không ít người phải ôm hận, chính vì vậy hãy thực sự hãy tỉnh táo trước khi đầu tư vào Bitcoin và các đồng tiên mã hóa.

Okay, trên đây là 5 công nghệ đã làm thay đổi cả thế giới, ở phần tiếp theo thì mình sẽ tiếp tục chia sẻ đến bạn 5 công nghệ còn lại.

CTV: Trần Quang Minh – Bài viết gốc tại blogchiasekienthuc.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Hibernate reverse engineering – Customize code generation sử dụng custom strategy class

hibernate reverse engineering
Hibernate reverse engineering – Customize code generation sử dụng custom strategy class

Bài viết được sự cho phép của tác giả Giang Phan

Trong bài viết trước tôi đã giới thiệu với các bạn sử dụng tính năng Reverse Engineering của Hibernate Tool để Generate code domain model classes, annotated EJB3 entity, Hibernate mapping files một cách tự động. Có một số trường hợp, chúng ta cần customize code generation chẳng hạn database được thiết kế có prefix “gp_” cho tất cả table. Tuy nhiên, trong code chúng ta không muốn có prefix này, ví dụ gp_user thì cần generate class là User. Để giải quyết vấn đề này, ta có thể tạo một Custom Strategy Class để tùy chỉnh việc tạo các tên class được generate.

  Hibernate Criteria Query Language (HCQL)
  Hibernate Batch processing

Giới thiệu ReverseEngineeringStrategy

Bên cạnh việc sử dụng XML trong file hibernate.reveng.xml, chúng cũng có thể tùy chỉnh việc generate bằng mã Java. Điều này có thể được thực hiện bằng cách tạo một lớp Java implements ReverseEngineeringStrategy hoặc extends DelegatingReverseEngineeringStrargetyclass. Cả hai đều nằm trong package org.hibernate.cfg.reveng.

Có rất nhiều phương thức hỗ trợ chúng ta custom việc generate code:

Một số phương thức thường được sử dụng:

  • excludeTable() : xác định có cần generate table này hay không.
  • excludeColumn() : xác định có exclude column khỏi class được generate hay không.
  • tableToClassName()  : xác định table name sang class name.
  • columnToPropertyName() : xác định tên column sang tên property.

Khởi tạo project

Tạo maven project và khai báo các dependency sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-tools</artifactId>
    <version>5.4.10.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.4.7.Final</version>
</dependency>

Tạo database gp_hibernate_demo2 có 2 bảng như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
CREATE TABLE `gp_user` (
  `id` bigint(20) NOT NULL,
  `email` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  `created_by` bigint(20) DEFAULT NULL,
  `modified_at` datetime DEFAULT NULL,
  `modified_by` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `sys_migration` (
  `id` bigint(20) NOT NULL,
  `table` varchar(255) DEFAULT NULL,
  `version` varchar(255) DEFAULT NULL,
  `run_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Tạo class custom reverse engineering strategy

Thông thường chúng ta sẽ extends từ DelegatingReverseEngineeringStrargety để chỉ thực hiện override các phương thức cần thiết.

CustomReverseEngineeringStrategy.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
package com.gpcoder.reveng;
import java.util.Arrays;
import java.util.List;
import org.hibernate.cfg.reveng.DelegatingReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.ReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.TableIdentifier;
public class CustomReverseEngineeringStrategy extends DelegatingReverseEngineeringStrategy {
    private static final List<String> EXCLUDE_COLUMNS = Arrays.asList(
        "created_by",
        "created_at",
        "modified_at",
        "modified_by"
    );
    public CustomReverseEngineeringStrategy(ReverseEngineeringStrategy delegate) {
        super(delegate);
    }
    @Override
    public boolean excludeTable(TableIdentifier table) {
        if (table.getName().startsWith("sys_")) {
            return true;
        }
        return super.excludeTable(table);
    }
    @Override
    public boolean excludeColumn(TableIdentifier identifier, String columnName) {
        return EXCLUDE_COLUMNS.contains(columnName);
    }
    @Override
    public String tableToClassName(TableIdentifier tableIdentifier) {
        final String defaultClassName = super.tableToClassName(tableIdentifier);
        return defaultClassName.replace("Gp", "");
    }
}

Trong class trên tôi override các phương thức:

  • excludeTable() : không generate các table có prefix “sys_”.
  • excludeColumn() : loại bỏ các column created_by, created_at, modified_at, modified_by khỏi class được generate.
  • tableToClassName()  : bỏ các prefix “gp_” khỏi class name được generate.

Sử dụng class custom reverse engineering strategy

Cấu hình Hiberante

Các bạn tham khảo lại bài viết trước “Sử dụng Hibernate Tool tạo các Hibernate Entity một cách tự động từ các table“.

Tạo tự động các Entity mapping & Annation codes

Tại Hibernate Perspective, chọn Hibernate Code Generation Configurations…

Nhập các thông tin như sau: 

Tạo file reveng.xml, chọn Setup và chọn các bảng cần tạo tự động:

Tiếp theo, chọn Tab Exporters và thiết lập tạo tự động các Entity mapping và Annotation code:

Chọn Run, chúng ta có kết quả sau:

Như bạn thấy kết quả như chúng ta mong muốn.

Tài liệu tham khảo:

Bài viết gốc được đăng tải tại gpcoder.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Giới thiệu về Spring Session với Spring Session JDBC

spring session
Giới thiệu về Spring Session với Spring Session JDBC

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

Spring Session là một module của Spring framework giúp chúng ta có thể quản lý session của user khi sử dụng web của chúng ta bằng một hệ thống lưu trữ khác thay vì quản lý session sử dụng server runtime. Hệ thống lưu trữ khác này có thể là một database system hoặc MongoDB hoặc Redis hoặc Hazelcast. Việc sử dụng Spring Session giúp chúng ta có thể giải quyết các vấn đề liên quan đến session trong deploy ứng dụng sử dụng load balancer, hay các giới hạn của HTTP session của server. Trong bài viết này, mình sẽ hướng dẫn các bạn cách sử dụng Spring Session để lưu thông tin session vào một database nào đó các bạn nhé!

  Cách sử dụng properties trong tập tin cấu hình của Spring
  Cài đặt Spring Boot CLI

Để làm ví dụ cho bài viết này, mình sẽ tạo mới một Spring Boot application với Spring Security, Spring Web và PostgreSQL JDBC Driver để store thông tin session như sau:

Kết quả:

Các bạn cần add Spring Session JDBC manually vào tập tin pom.xml:

<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>

Các bạn không cần declare version của Spring Session JDBC, nó đã được manage bởi Spring Boot Parent.

Để chạy ứng dụng này lên, các bạn cần cấu hình thông tin Datasource trong tập tin application.properties vì chúng ta đã khai báo sử dụng Spring Data JPA:

spring.datasource.url=jdbc:postgresql://localhost:5432/spring_session_example
spring.datasource.username=khanh
spring.datasource.password=1

Nếu lúc này chạy ứng dụng, các bạn có thể đăng nhập ứng dụng với thông tin user mặc định của Spring Security là “user” và mật khẩu được in ra trong console log của IDE.

Thông tin về session của user sẽ được lưu trong HTTP session của server các bạn nhé!

Bây giờ, chúng ta sẽ cấu hình Spring Session JDBC để chuyển phần thông tin session này vào database nha các bạn!

Như mình đã nói, Spring Session hỗ trợ nhiều hệ thống lưu trữ khác nhau, trong bài viết này, chúng ta đang sử dụng database system. Để khai báo điều này, các bạn hãy mở tập tin application.properties và khai báo như sau:

spring.session.store-type=jdbc

Sẽ có một số table được Spring Session tạo ra mặc định để lưu trữ thông tin session. Tên của các table này là SPRING_SESSION để chứa thông tin user session và SPRING_SESSION_ATTRIBUTES để chứa thông tin chi tiết của từng session. Các bạn có thể mở file spring-session-jdbc jar file để xem định nghĩa của những table này:

Để khởi tạo các table này tự động, các bạn có thể thêm một property để làm điều này như sau:

spring.session.jdbc.initialize-schema=always

Chạy ứng dụng và kiểm tra database, các bạn sẽ thấy kết quả như sau:
Giờ thì chỉ cần đi đến ứng dụng sử dụng http://localhost:8080, các bạn sẽ thấy 2 table này generate những record như sau:

spring_session

spring_session_attributes:

Đây là thông tin về session mà chúng ta vừa request tới ứng dụng đó các bạn. Nếu bây giờ, các bạn login vào ứng dụng bằng thông tin mặc định của Spring Security, các bạn sẽ thấy data trong table spring_session như sau:

và:

Principal name lúc này đã được cập nhập là tên user mà chúng ta đã sử dụng để đăng nhập ứng dụng.

Các bạn có thể thay tên của table mặc định này bằng cách sử dụng property:

spring.session.jdbc.initialize-schema=always

với user_session là tên table chính chứa thông tin user session, tương đương với table mặc định spring_session.

Một session sẽ có thời gian timeout nếu user không còn hoạt động trên session đó nữa. Mặc định thì Spring Session cấu hình thời gian timeout này là 30 phút. Các bạn có thể thay đổi cấu hình này bằng cách sử dụng property:

spring.session.timeout=180

Sau khoảng thời gian này, session trong table trên sẽ bị xoá đi các bạn nhé!

Các hoạt động của Spring Session

Nếu các bạn muốn biết cách hoạt động của Spring Session thì hãy mở class SessionRepositoryFilter. Class filter này có nhiệm vụ chặn tất cả các request tới application và thay thế HttpServletRequest and HttpServletResponse mặc định của HTTP servlet bằng những class custom là SessionRepositoryRequestWrapper và SessionRepositoryResponseWrapper trong phương thức doFilterInternal().

SessionRepositoryRequestWrapper sẽ thực hiện việc commitSession() với mục đích insert thông tin về session vào database.

Đọc code thêm các bạn nhé!

Bài viết gốc được đăng tải tại huongdanjava.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Hướng dẫn 2 cách hạ cấp từ Windows 11 xuống Windows 10

windows
Hướng dẫn 2 cách hạ cấp từ Windows 11 xuống Windows 10

Bài viết được sự cho phép của blogchiasekienthuc.com

Vâng, nếu như bạn đã thực hiện nâng cấp thành công từ Windows 10 lên Windows 11 thông qua chương trình Windows Insider Preview (người dùng nội bộ) rồi  thì xin chúc mừng bạn. Bạn là một trong những người được trải nghiệm Windows 11 khá sớm đấy !

Thế nhưng, nếu bạn không hài lòng với phiên bản Windows 11 hiện tại thì bạn hoàn toàn có thể hạ cấp nó về phiên bản Windows 10 trước đó một cách dễ dàng.

Mình xin nhắc lại là cách này chỉ áp dụng cho những máy tính đã nâng cấp từ Windows 10 lên Windows 11 thôi nhé, còn nếu như trước đó bạn thực hiện cài đặt mới Windows 11 thì chịu nha

  10 điều bạn có thể làm với Linux mà bạn không thể làm với Windows
  40 phím tắt dành cho người dùng Windows

Mặc dù hệ điều hành Windows 11 có rất nhiều cải tiến mới và đáng để sử dụng. Tuy nhiên, do đang trong quá trình hoàn thiện nên vẫn còn khá nhiều lỗi nhỏ tồn đọng.

Vậy nên, nếu bạn dùng nó để trải nghiệm thì OK, không có vấn đề gì để nói ở đây cả. Thế nhưng nếu bạn sử dụng để làm việc thì sẽ hơi khó chịu một chút.

Chính vì thế, nếu bạn chưa thực sự hài lòng với phiên bản Windows 11 hiện tại thì bạn hoàn toàn có thể thực hiện hạ cấp Windows 11 về lại Windows 10 một cách dễ dàng.

I. Làm thế nào để hạ cấp Windows 11 về lại Windows 10?

Và tất nhiên rồi, trong bài hướng dẫn này mình sẽ chia sẻ với các bạn 2 cách để làm việc này. Mình sẽ hướng dẫn một cách chi tiết nhất để các bạn dễ hình dung nhất có thể.

Lưu ý: Cách 1 thì tuy đơn giản nhưng bạn chỉ áp dụng được trong vòng 10 ngày đầu, tính từ lúc bạn thực hiện nâng cấp từ Windows 10 lên Windows 11. Bởi vì Windows 11 chỉ lưu lại file backup OS cũ trong vòng 10 ngày mà thôi, đến ngày 11 thì file này đã tự động bị xóa rồi.

Còn trong trường hợp bạn đã sử dụng Windows 11 quá 10 ngày rồi thì bắt buộc bạn phải  áp dụng cách số 2 nhé.

Cách #1: Sử dụng tính năng Recovery trên Windows 11 để hạ cấp xuống Windows 10 

NOTE: Theo Microsoft thì cách làm này sẽ không bị mất dữ liệu trên ổ C (ổ hệ điều hành bao gồm Desktop, thư mục Download, Picture, Video, Music…) nhưng nếu có gì quan trọng thì bạn hãy copy sang phân vùng ổ D, E… cho chắc cờ nhé.

+ Bước 1: Bạn nhấn Windows + I để truy cập vào Windows Settings. Hoặc là bạn nhấn vào nút Start => sau đó chọn Settings như hình bên dưới.

ha-cap-windows-11-xuong-windows-10 (1)

+ Bước 2: Tiếp theo, bạn chọn System để truy cập vào phần thiết lập hệ thống.

ha-cap-windows-11-xuong-windows-10 (2)

+ Bước 3: Tiếp tục chọn tính năng Recovery.

Với chức năng Recovery này thì ngoài việc có thể hạ cấp Windows 11 xuống Windows 10 ra (Go back), bạn còn có thể thực hiện Reset Windows 11 hoặc truy cập vào Advaced Startup nữa.

ha-cap-windows-11-xuong-windows-10 (3)

+ Bước 4: Trong phần Recovery options sẽ có các lựa chọn như sau:

  • Reset this PC: Khôi phục lại Windows 11 về trạng thái như mới.
  • Previous verision of Windows: Hạ cấp về phiên bản Windows trước đó.
  • Advanced startup: Khởi động tùy chỉnh.. cũng giống trên Windows 10 thôi, bạn có thể tìm hiểu thêm tại đây !

=> Bạn nhấn vào nút Go back trong phần Previous version of Windows. Nếu nút Go back không sáng lên, tức là bạn không bấm vào được thì có nghĩa là bạn không thể hạ cấp được theo cách này. Bạn chuyển sang cách số 2 bên dưới nhé !

ha-cap-windows-11-xuong-windows-10 (4)

+ Bước 5: Cửa sổ Why are you going back? xuất hiện. Đại lại Windows muốn hỏi bạn Tại sao bạn muốn quay lại?

Bạn chọn lý do tùy ý => sau đó bấm Next để tiếp tục. Thực chất thì đây là một vài bước khảo sát của Microsoft để họ cải thiện mà thôi.

ha-cap-windows-11-xuong-windows-10 (5)

+ Bước 6: Bước này Windows sẽ hỏi bạn có muốn kiểm tra các bản cập nhật hay không. Bạn nhấn vào nút No, thank để từ chối. Bước này là Microsoft đang níu kéo đấy

ha-cap-windows-11-xuong-windows-10 (6)

+ Bước 7: Một thông báo xuất hiện để cảnh báo cho bạn biết rằng:

Bạn sẽ mất tất cả các thay đổi cài đặt và bạn sẽ phải thực hiện cài đặt lại các ứng dụng. Nếu bạn OK thì nhấn Next để đi tiếp.

ha-cap-windows-11-xuong-windows-10 (7)

+ Bước 8: Lúc này hộp thoại Don’t get locked out? (Không bị khóa) sẽ xuất hiện với nội dung:

If you used a password to sign in to your previous build, make sure you know it.

Google Dịch: Nếu bạn đã sử dụng mật khẩu để đăng nhập vào bản dựng trước của mình, hãy đảm bảo rằng bạn biết (nhớ) mật khẩu đó.

ha-cap-windows-11-xuong-windows-10 (10)

+ Bước 9: Cuối cùng, bạn hãy bấm vào nút Go back to earlier build. Lúc này máy tính của bạn sẽ khởi động lại và bắt đầu quá trình khôi phục lại phiên bản Windows trước đó.

ha-cap-windows-11-xuong-windows-10 (11)

VÀ…. ngồi đợi cho đến khi hoàn thành thôi ^^

Cách #2: Hạ cấp Windows 11 xuống Windows 10 với công cụ MediaCreationTool

Công cụ này do chính Microsoft cung cấp để phục vụ người dùng nên bạn khỏi cần lăn tăn gì về mức độ an toàn nhé.

Cách làm này thực chất không khác việc cài lại Windows 11 là mấy, và dữ liệu trên ổ hệ điều hành (thường là ổ C) chắc chắn bị mất nhé các bạn, nên có gì quan trọng thì copy sang ổ dữ liệu trước. Ví dụ như ổ D, E chẳng hạn..

Và để các bạn khỏi lo lắng thì mình cũng khẳng định luôn là sẽ không ảnh hưởng đến dữ liệu của các ổ khác nhé.

+ Bước 1: Bạn truy cập vào liên kết này để tải về công cụ MediaCreationTool trước đã.

ha-cap-windows-11-xuong-windows-10 (12)

Sau đó, bạn kéo xuống phần Create Windows 10 installation media => và nhấn vào nút Download tool now để tải về công cụ MediaCreationTool

ha-cap-windows-11-xuong-windows-10 (13)

+ Bước 2: Sau khi tải về ta sẽ có được file MediaCreationTool.exe => bạn nhấn đúp chuột vào để chạy file.

ha-cap-windows-11-xuong-windows-10 (14)

+ Bước 3: Bạn nhấn vào nút Accept để chấp nhận điều khoản sử dụng của Microsoft.

ha-cap-windows-11-xuong-windows-10 (15)

+ Bước 4: Cửa sổ What do you want to do? (Bạn muốn làm gì?) xuất hiện:

=> Bạn tích vào tùy chọn Upgrade this PC now => sau đó bấm Next để tiếp tục.

ha-cap-windows-11-xuong-windows-10 (16)

+ Bước 5: Lúc này công cụ MediaCreationTool sẽ thực hiện tải về các tệp Windows 10 cần thiết. Quá trình này có thể mất vài phút nhé các bạn.

ha-cap-windows-11-xuong-windows-10 (17)

+ Bước 6: Hộp thoại Choose What to Keep (Chọn những gì để giữ) sẽ xuất hiện. Bạn hãy tích chọn Nothing (Không có gì) => và nhấn Next.

Tùy chọn này sẽ xóa tệp đã tải xuống, cũng như các ứng dụng đã cài. Những thiết lập và cài đặt cũng sẽ bị khôi phục về trạng thái như mới.

ha-cap-windows-11-xuong-windows-10 (18)

+ Bước 7: Hộp thoại tiếp theo là Ready to install (Sẵn sàng cài đặt) => bạn nhấn vào nút Install để bắt đầu.

ha-cap-windows-11-xuong-windows-10 (19)

Vâng, lúc này quá trình cài đặt Windows 10 sẽ bắt đầu và đồng thời Windows 11 cũng bị gỡ bỏ. Cách này tuy lâu nhưng sẽ giúp hệ thống sạch sẽ hơn, hiệu suất hoạt động cao hơn…

ha-cap-windows-11-xuong-windows-10 (20)

II. Lời Kết

Vâng, như vậy là mình đã chia sẻ với các bạn 2 cách để hạ cấp Windows 11 về Windows 10 rất chi tiết rồi nhé, hay nói cách khác là quay trở lại Windows 10 sau khi đã nâng cấp lên Windows 11 đó các bạn.

Và mình cũng lưu ý luôn với các bạn là cho dù làm theo cách nào đi chăng nữa thì sẽ có rủi ro bị lỗi (mặc dù tỷ lệ này rất thấp). Vậy nên, bạn cũng cần chuẩn bị tâm lý để cài lại Windows 10 nếu chẳng may quá trình hạ cấp bị lỗi nhé !

Hi vọng là bài viết này sẽ hữu ích với bạn, chúc các bạn thành công !

Kiên NguyễnBài viết gốc tại blogchiasekienthuc.com

URL là gì? Tại sao URL quan trọng trong SEO?

URL là gì?
URL là gì?

Bài viết được sự cho phép của tác giả Kien Dang Chung

Trong các sách báo về lập trình web nói riêng và công nghệ thông tin nói chung, chúng ta gặp rất nhiều các từ viết tắt như URL, URI, URN, URC… và thường gặp nhất là URL, có thể bạn hiểu mang máng URL là đường dẫn đến trang web nhưng không biết chính xác URL là gì, nó có các thành phần cấu tạo lên như thế nào… Sau bài viết, bạn sẽ hiểu chính xác các khái niệm cơ bản về hệ thống các website này.

URL là gì?

URL là viết tắt của cụm từ Uniform Resource Locator (còn được gọi là địa chỉ web) được sử dụng để định vị và truy cập đến các tài nguyên trên Internet. Mỗi tài nguyên (trang web, hình ảnh, video, file, document,…) đều có 1 URL duy nhất để dẫn đến nó.

Khi bạn mở một trình duyệt và gõ vào một địa chỉ trang web ví dụ https://topdev.vn thì đây chính là một URL.

Ví dụ khi nhập URL https://topdev.vn/blog/url-la-gi/ vào thanh tìm kiếm, bạn sẽ được dẫn đến bài viết này. Tương tự, khi bạn có địa chỉ URL của một bài viết nào đó, bạn sẽ truy cập trực tiếp đến bài viết đó mà không cần thao tác để điều hướng.

URL này cũng có thể đưa vào các nội dung trang web để liên kết. URL được định nghĩa lần đầu vào năm 1994 bởi nhà vật lý Tim Berners-Lee trong tài liệu RFC 1738, ông cũng là người đề xuất và phác thảo ra ngôn ngữ HTML. Bên cạnh đó một nhóm kỹ sư khác của IETF – Lực lượng quản lý kỹ thuật mạng Internet cũng có những hợp tác đưa ra các đề xuất về URL.

Phân loại URL

  • URL tĩnh (Static URL): thường có đuôi .html, đây là loại URL mà không thể thay đổi sau khi được tạo ra. URL tĩnh được đánh giá là thân thiện hơn với các công cụ tìm kiếm.
  • URL động (Dynamic URL): là đường dẫn có thể thay đổi dựa trên các tham số hoặc yêu cầu của người dùng, nó thường được dùng cho các web có phần mềm mã nguồn mở.

>> Xem thêm: URI là gì?

Thành phần cấu tạo URL

Thành phần cấu tạo URL

Cấu tạo của một URL như sau:

URL = scheme:[//authority]path[?query][#fragment]

Trong đó:

  • scheme: chính là giao thức mạng sử dụng để truyền dẫn dữ liệu, các giao thức phổ biến mà chúng ta biết là http, https, ftp, mailto, irc…, phân cách giao thức với phần còn lại bằng ký tự :.
  • authority là phần tổ hợp bao gồm các phần nhỏ hơn
    authority = [userinfo@]domain[:port]
    • userinfo: Thông tin người dùng bao gồm tên đăng nhập và mật khẩu, chỉ sử dụng với các URL được bảo mật cần đăng nhập.
    • domain: tên miền của website là ánh xạ 1 – 1 từ một tên có thể nhớ sang địa chỉ IP của máy chủ web nơi chứa nội dung trang web.
    • port: Số cổng sử dụng bởi giao thức trên máy chủ.
  • path: Đường dẫn đến nội dung trang web, đường dẫn này là đường dẫn trong nội bộ website, phân cách giữa thư mục cha và thư mục con bởi dấu gạch chéo (/).
  • query: là chuỗi truy vấn, chứa các thông tin theo cặp tên/giá trị được gửi đến máy chủ web, mỗi cặp này cách nhau bởi dấu &.
  • fragment: là các chỉ mục con của nội dung, được bắt đầu với dấu #.

Trong thực tế, các URL có thể không cần phải chứa đầy đủ các thành phần như trên, chúng ta cùng xem một số ví dụ:

Ví dụ 1: https://allaravel.com/tutorials/lap-trinh/khoa-hoc-html-tu-co-ban-den-nang-cao/ Chúng ta có các thành phần như sau:

  • scheme: Giao thức mạng ở đây là https – Giao thức truyền tải siêu văn bản bảo mật, nó là phiên bản của HTTP với dữ liệu truyền dẫn được mã hóa.
  • domain: Tên miền allaravel.com là tên có thể nhớ được thay vì nhớ địa chỉ IP của máy chủ chứa nội dung trang allaravel.com là 45.32.23.201.
  • port: Ở đây tuy không xuất hiện thông tin về cổng dịch vụ do mặc định HTTPS sử dụng cổng 443, nếu máy chủ hoạt động ở cổng khác thì thông tin về cổng dịch vụ cần có URL mới hoạt động được.
  • path: /tutorials/lap-trinh/khoa-hoc-html-tu-co-ban-den-nang-cao/ là đường dẫn của bài viết Khóa học HTML từ cơ bản đến nâng cao.

Ví dụ 2: https://allaravel.com/?s=vuejs+tutorial&paged=2 Các thành phần trong ví dụ này tương tự với ví dụ 1 chỉ khác ở phần chuỗi truy vấn thông tin s=vuejs+tutorial&paged=2. Dấu ? là ký tự đánh dấu sự bắt đầu của chuỗi truy vấn thông tin, chuỗi này bao gồm 2 cặp dữ liệu:

  • s=vuejs+tutorial: s là viết tắt của search, do lập trình viên quy định, ý nghĩa là  từ khóa tìm kiếm “vuejs tutorial”
  • paged=2: lấy các kết quả ở trang thứ 2

Ví dụ 3: https://firebird@allaravel.com:12345678@member.allaravel.com/member Trong ví dụ này chúng ta có thêm thành phần userinfo:

  • username: firebird@allaravel.com
  • password: 12345678
  • domain: member.allaravel.com
  • path: member
  cURL là gì? Cách sử dụng Curl

Cách URL hoạt động

Khi người dùng nhập một URL vào thanh địa chỉ của trình duyệt hoặc nhấp vào một liên kết, trình duyệt sẽ gửi yêu cầu đến máy chủ web được chỉ định bởi tên miền trong URL. Máy chủ sẽ phản hồi bằng cách cung cấp tài nguyên được yêu cầu, chẳng hạn như trang HTML, hình ảnh, hoặc dữ liệu khác.

Cách URL hoạt động

Nguồn ảnh: semrush.com

Quá trình này bao gồm các bước sau:

  1. Trình duyệt gửi yêu cầu đến máy chủ DNS (Domain Name System) để dịch tên miền thành địa chỉ IP.
  2. Máy chủ web nhận yêu cầu và xác định tài nguyên cần truy cập dựa trên đường dẫn và tham số truy vấn.
  3. Máy chủ gửi phản hồi lại trình duyệt, thường là trang HTML.
  4. Trình duyệt hiển thị trang web cho người dùng.

Tầm quan trọng của URL trong SEO

URL đóng vai trò quan trọng trong việc tối ưu hóa công cụ tìm kiếm (SEO) và trải nghiệm người dùng. URL tốt có thể cải thiện thứ hạng của trang web trên các công cụ tìm kiếm và giúp người dùng dễ dàng điều hướng trên trang web.

Cấu trúc URL rõ ràng và dễ hiểu

Công cụ tìm kiếm như Google ưu tiên các URL rõ ràng, ngắn gọn, và có từ khóa liên quan đến nội dung của trang. Việc tạo ra các URL dễ hiểu và thân thiện với người dùng giúp cải thiện trải nghiệm duyệt web và dễ dàng thu hút lưu lượng truy cập từ các công cụ tìm kiếm.

  • URL thân thiện: URL nên mô tả chính xác nội dung của trang, không chứa ký tự lạ, và sử dụng dấu gạch nối để ngăn cách từ.
    https://www.example.com/blog/seo-la-gi
  • Sử dụng từ khóa: Tích hợp từ khóa vào URL giúp công cụ tìm kiếm hiểu nội dung của trang và xếp hạng tốt hơn cho các truy vấn liên quan.

Tối ưu hóa trải nghiệm người dùng

URL dễ đọc và dễ nhớ không chỉ cải thiện SEO mà còn làm tăng sự tin tưởng của người dùng. Khi nhìn vào một URL ngắn gọn và mô tả đúng nội dung, người dùng có nhiều khả năng nhấp vào liên kết hơn và dễ nhớ địa chỉ trang web của bạn hơn.

Sử dụng HTTPS để bảo mật

Công cụ tìm kiếm ưu tiên các trang web sử dụng HTTPS thay vì HTTP. Các trang web có HTTPS được coi là an toàn hơn, điều này không chỉ cải thiện thứ hạng SEO mà còn tăng độ tin cậy cho trang web đối với người dùng.

Quản lý URL động

Nếu trang web của bạn sử dụng các tham số động trong URL, hãy cố gắng giữ cho chúng ngắn gọn và tránh sử dụng quá nhiều tham số. URL động có thể gây khó khăn cho công cụ tìm kiếm trong việc thu thập dữ liệu và ảnh hưởng đến hiệu suất SEO của trang.

Tránh URL trùng lặp

Công cụ tìm kiếm có thể coi URL trùng lặp là nội dung trùng lặp, dẫn đến việc giảm thứ hạng của trang web. Hãy đảm bảo rằng mỗi URL trong trang web của bạn là duy nhất và đại diện cho một nội dung cụ thể.

URL là một phần không thể thiếu trong việc định vị tài nguyên trên internet và có vai trò quan trọng trong chiến lược SEO. Việc hiểu rõ URL và tối ưu hóa cấu trúc của nó sẽ giúp cải thiện trải nghiệm người dùng, tăng khả năng xuất hiện trên công cụ tìm kiếm và nâng cao thứ hạng trang web của bạn. Hãy đảm bảo rằng các URL của bạn ngắn gọn, rõ ràng, và có từ khóa phù hợp để đạt được hiệu quả SEO tối đa.

Nguồn tham khảo: allaravel.com

Xem thêm Việc làm IT hấp dẫn trên TopDev

Sử dụng Hibernate Tools tạo các Entity và DAO class

hibernate tools
Sử dụng Hibernate Tools tạo các Entity và DAO class

Bài viết được sự cho phép của tác giả Giang Phan

Trong bài viết trước, tôi đã hướng dẫn các bạn sử dụng Hibernate Tool tạo các Hibernate Entity một cách tự động từ các table. Trong bài này, tôi sẽ hướng dẫn các bạn cách custom template generate các Entity để sử dụng Lombok cho các getter và setter và tạo các Data Access Object (DAO) class một cách tự động sử dụng Hibernate Tools.

  Hibernate Criteria Query Language (HCQL)
  Hibernate là gì? Sao phải dùng nó thay JDBC?

Custom template generate các Hibernate Entity để sử dụng Lombok cho getter và setter

Tạo project và khai báo thư viện cần thiết

Tạo maven project và khai báo các dependency sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.10</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-tools</artifactId>
    <version>5.4.10.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>5.4.7.Final</version>
</dependency>
<!-- MySQL -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.17</version>
</dependency>

Sử dụng lại database ở bài viết trước: “Hibernate reverse engineering – Customize code generation sử dụng custom strategy class“.

Custom template

Tìm đến thư mục chứa gói jar của thư viện hibernate-tools. Trong ví dụ này, tôi sử dụng hibernate-tools-5.4.10.Final.jar, giải nén thư mục này, chúng ta có thư mục pojo chứa các template cho generate code Entity (POJO):

Hibernate tools sử dụng Freemarker templates để generate Entity (POJO) class. Nội dung các file template này như sau:

  • Pojo.ftl : đây là file template chính để generate Entity, nó include các file template khác để tạo thành file Entity.java hoàn chỉnh.
  • Ejb3TypeDeclaration.ftl : khai báo các Annotation chẳng hạn @Entity, @Table.
  • PojoTypeDeclaration.ftl : khai báo class modifier, class name, extend class hoặc implement interface.
  • PojoFields.ftl : khai báo các field tương ứng với table trong dabatable.
  • PojoConstructors.ftl : khai báo constructor.
  • PojoPropertyAccessors.ftl : khai báo các getter và setter.
  • PojoToString.ftl : khai báo override phương thức toString().
  • PojoEqualsHashcode.ftl : khai báo override phương thức hashcode() và equals().
  • PojoInterfacePropertyAccessors.ftl : khai báo các getter và setter cho interface.
  • PojoExtraClassCode.ftl : khai báo các class code khác.

Thư viện Lombok hỗ trợ các Annotation giúp code của POJO class ngắn gọn hơn. Chúng ta sẽ sử dụng Annotation @Data để thay thế cho constructor, getter, setter, toString(), hashcode(), equals() được generate bởi các template mặc định của Hibernate tools.

Mở file Pojo.ftl và bỏ các include không cần dùng, các bạn có thể delete các file tương ứng.

Tiếp theo mở file Ejb3TypeDeclaration.ftl và thêm khai báo @Data của Lombok.

Mặc định, Hibernate sử dụng JPA Annotation ở method, chúng ta muốn chuyển sang field thì cần thực hiện như sau:

  • Tạo file template mới Ejb3FieldGetAnnotation.ftl
  • Copy toàn nội dung file template Ejb3PropertyGetAnnotation.ftl cho Ejb3FieldGetAnnotation.ftl
  • Đổi các variable property sang field.

Mở file PojoFields.ftl và thêm khai báo:

  • Thêm static final serialVersionUID field mặc định, để tránh warning cho class Entity.
  • Include template file khai báo các JPA Annotation.

Mở file PojoTypeDeclaration.ftl và thêm java doc cho class. Chẳng hạn, thêm @author gpcoder.

Sử dụng Hibernate Tools tạo các Hibernate Entity

Chép thư mục pojo đã custom template ở trên vào thư mục resource của project.

Tại Hibernate Perspective, chọn Hibernate Code Generation Configurations…

Thêm cấu hình mới với các thông tin như sau:

Lưu ý: chỉ chọn thư mục resource, không chọn thư mục pojo. Mặc định hibernate sẽ sử các template của thư mục pojo trong thư mục resource được khai báo.

Chọn tab Exporter và mục Domain code (.java)

Chọn Run, chúng ta có kết quả như sau:

Như bạn thấy, các Annotation Lombok, javadoc đã được include trong file java, các JPA Annotation đã được đánh dấu ở field, không còn các method getter, setter, toString, hashcode, equals hay constructor.

Tạo các Data Access Object (DAO) class

Trong ứng dụng java, chúng ta thường thao tác với database thông qua DAO (Data Access Object) để thực hiện các câu truy vấn dữ liệu. Mỗi bảng nên có một class riêng để thực hiện truy vấn này. Tương tự như Entity, chúng ta có thể tạo ra các class DAO này một cách tự động.

Chẳng hạn, ta có một class GenericDAO như sau:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package com.gpcoder.dao;
import java.util.List;
public class GenericDAO<T> {
    public T findById(Long id) {
        return null;
    }
    public List<T> findAll() {
        return null;
    }
    public Long save(T t) {
        return 1L;
    }
    public void update(T t) {
        
    }
    
    public boolean delete(Long id) {
        return true;
    }
}

Chúng ta mong muốn, mỗi Entity sẽ có một class DAO kế thừa từ class GenericDAO này.

Để làm được điều này, chúng ta thực hiện như sau:

  • Tạo file template cho class DAO.
  • Sử dụng Hibernate Tools để generate class DAO dựa trên template đã được định nghĩa.

Tạo file template

Tạo file dao-template/dao.ftl trong thư mục resource của project.

Sử dụng Hibernate Tools để generate class DAO

Tại Hibernate Perspective, chọn Hibernate Code Generation Configurations…

Thêm cấu hình mới với các thông tin như sau:

Chúng ta có kết quả như sau:

Bài viết gốc được đăng tải tại gpcoder.com
Có thể bạn quan tâm:
Xem thêm Việc làm IT hấp dẫn trên TopDev

Giới thiệu về Micronaut

micronaut
Giới thiệu về Micronaut

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

Mình đã giới thiệu với các bạn về Quarkus, một framework của Java giúp chúng ta có thể xây dựng các ứng dụng Java Cloud Native, giảm thời gian chạy ứng dụng và giảm memory footprint sử dụng để chạy ứng dụng. Micronaut cũng là một trong những framework cho phép chúng ta làm điều này. Với sự kết hợp với GraalVM, Micronaut có thể giúp chúng ta build các native image và chạy trên các Cloud provider với các container. Trong bài viết này, mình sẽ giới thiệu với các bạn tổng quan về Micronaut các bạn nhé!

  Building Microservices Application - Phần 3: Xác thực API bằng Oauth 2.0
  Cài đặt Visual Studio: Công cụ lập trình mạnh mẽ của Microsoft

Tạo mới project

Tương tự như Spring hay Quarkus, Micronaut cũng cung cấp cho chúng ta một công cụ để generate project với Micronaut một cách dễ dàng. Đó là Micronaut Launch ở địa chỉ: https://micronaut.io/launch/.

Có nhiều Application Type mà Micronaut hỗ trợ, nhưng để đơn giản cho ví dụ của bài viết này, mình sẽ tạo mới một ứng dụng web với Micronaut, do đó mình sẽ chọn Application Type là Micronaut Application.

Tương tự như Spring Initializr, chúng ta có thể xem trước project sẽ generate như thế nào, bao gồm những dependency gì?

Để thêm dependencies hay features sẽ sử dụng cho ứng dụng, các bạn click chọn Features:

Có rất nhiều framework, libraries được Micronaut hỗ trợ. Có cả hỗ trợ Spring framework nữa đó các bạn!

Nhưng vì mình chỉ tạo một ứng dụng web cơ bản, nên mình sẽ không cần chọn features gì cả! Mặc định thì Micronaut đã hỗ trợ rồi.

Mình sẽ cấu hình project như sau:

sau đó thì nhấn Generate để download project, rồi import vào IntelliJ.

Kết quả như sau:

Chạy ứng dụng

Mặc định thì Micronaut sử dụng Netty server để chạy ứng dụng. Lúc này, nếu các bạn mở class Application và chạy nó, xong truy cập tới http://localhost:8080/, các bạn sẽ thấy kết quả như sau:

Đây là vì chúng ta chưa định nghĩa bất kỳ một request nào cho ứng dụng của chúng ta đó các bạn.

Các bạn có thể định nghĩa một request “/hello” với Micronaut như sau:

package com.huongdanjava;

import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;

@Controller
public class HelloController {

@Get("/")
public String hello() {
return "Hello World from Huong Dan Java";
}
}

Như các bạn thấy, Micronaut cũng có những annotation của riêng nó hỗ trợ cho việc xây dựng các web application, tương tự như Spring framework nên nếu bạn nào đã quen với Spring framework rồi thì làm việc với Micronaut cũng dễ.
Kết quả khi mình chạy lại ứng dụng rồi request tới http://localhost:8080/, như sau:

Nếu các bạn nhìn Console của IntelliJ thì sẽ thấy thời gian start ứng dụng như sau:

/Library/Java/JavaVirtualMachines/jdk-16.0.1.jdk/Contents/Home/bin/java -javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=52646:/Applications/IntelliJ IDEA CE.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/khanh/Downloads/micronaut-example/target/classes:/Users/khanh/.m2/repository/io/micronaut/micronaut-inject/3.0.0/micronaut-inject-3.0.0.jar:/Users/khanh/.m2/repository/org/slf4j/slf4j-api/1.7.29/slf4j-api-1.7.29.jar:/Users/khanh/.m2/repository/jakarta/inject/jakarta.inject-api/2.0.0/jakarta.inject-api-2.0.0.jar:/Users/khanh/.m2/repository/jakarta/annotation/jakarta.annotation-api/2.0.0/jakarta.annotation-api-2.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-core/3.0.0/micronaut-core-3.0.0.jar:/Users/khanh/.m2/repository/org/yaml/snakeyaml/1.29/snakeyaml-1.29.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-validation/3.0.0/micronaut-validation-3.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-core-reactive/3.0.0/micronaut-core-reactive-3.0.0.jar:/Users/khanh/.m2/repository/org/reactivestreams/reactive-streams/1.0.3/reactive-streams-1.0.3.jar:/Users/khanh/.m2/repository/javax/validation/validation-api/2.0.1.Final/validation-api-2.0.1.Final.jar:/Users/khanh/.m2/repository/io/projectreactor/reactor-core/3.4.8/reactor-core-3.4.8.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-http-client/3.0.0/micronaut-http-client-3.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-http-client-core/3.0.0/micronaut-http-client-core-3.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-websocket/3.0.0/micronaut-websocket-3.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-http-netty/3.0.0/micronaut-http-netty-3.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-buffer-netty/3.0.0/micronaut-buffer-netty-3.0.0.jar:/Users/khanh/.m2/repository/io/netty/netty-handler/4.1.67.Final/netty-handler-4.1.67.Final.jar:/Users/khanh/.m2/repository/io/netty/netty-resolver/4.1.67.Final/netty-resolver-4.1.67.Final.jar:/Users/khanh/.m2/repository/io/netty/netty-codec-http2/4.1.67.Final/netty-codec-http2-4.1.67.Final.jar:/Users/khanh/.m2/repository/io/netty/netty-handler-proxy/4.1.67.Final/netty-handler-proxy-4.1.67.Final.jar:/Users/khanh/.m2/repository/io/netty/netty-common/4.1.67.Final/netty-common-4.1.67.Final.jar:/Users/khanh/.m2/repository/io/netty/netty-buffer/4.1.67.Final/netty-buffer-4.1.67.Final.jar:/Users/khanh/.m2/repository/io/netty/netty-transport/4.1.67.Final/netty-transport-4.1.67.Final.jar:/Users/khanh/.m2/repository/io/netty/netty-codec/4.1.67.Final/netty-codec-4.1.67.Final.jar:/Users/khanh/.m2/repository/io/netty/netty-codec-socks/4.1.67.Final/netty-codec-socks-4.1.67.Final.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-http-server-netty/3.0.0/micronaut-http-server-netty-3.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-http-server/3.0.0/micronaut-http-server-3.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-router/3.0.0/micronaut-router-3.0.0.jar:/Users/khanh/.m2/repository/io/netty/netty-codec-http/4.1.67.Final/netty-codec-http-4.1.67.Final.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-runtime/3.0.0/micronaut-runtime-3.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-http/3.0.0/micronaut-http-3.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-aop/3.0.0/micronaut-aop-3.0.0.jar:/Users/khanh/.m2/repository/io/micronaut/micronaut-context/3.0.0/micronaut-context-3.0.0.jar:/Users/khanh/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.12.4/jackson-databind-2.12.4.jar:/Users/khanh/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.12.4/jackson-annotations-2.12.4.jar:/Users/khanh/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.12.4/jackson-core-2.12.4.jar:/Users/khanh/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jdk8/2.12.4/jackson-datatype-jdk8-2.12.4.jar:/Users/khanh/.m2/repository/com/fasterxml/jackson/datatype/jackson-datatype-jsr310/2.12.4/jackson-datatype-jsr310-2.12.4.jar:/Users/khanh/.m2/repository/javax/annotation/javax.annotation-api/1.3.2/javax.annotation-api-1.3.2.jar:/Users/khanh/.m2/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar:/Users/khanh/.m2/repository/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar com.huongdanjava.Application
__ __ _ _ 
| \/ (_) ___ _ __ ___ _ __ __ _ _ _| |_ 
| |\/| | |/ __| '__/ _ \| '_ \ / _` | | | | __|
| | | | | (__| | | (_) | | | | (_| | |_| | |_ 
|_| |_|_|\___|_| \___/|_| |_|\__,_|\__,_|\__|
Micronaut (v3.0.0)

11:26:54.579 [main] INFO io.micronaut.runtime.Micronaut - Startup completed in 1348ms. Server Running: http://localhost:8080

Bây giờ, chúng ta thử build native image với ứng dụng này rồi chạy xem thời gian start như thế nào các bạn nhé!
Các bạn hãy mở Terminal hoặc Console và đi đến thư mục project, sau đó thì chạy command sau:

mvn package -Dpackaging=native-image

Lưu ý là các bạn cần cài đặt native-image component sử dụng GraalVM và phải set biến môi trường JAVA_HOME trỏ đến thư mục cài đặt Java của GraalVM.

Với version hiện tại của Micronaut thì đang bị lỗi NoClassDefFoundError:

các bạn cần thêm dependency javax.inject vào tập tin pom.xml:

<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>

Sau khi build thành công thì các bạn hãy vào thư mục target, rồi chạy ứng dụng lên với câu lệnh như sau:

./micronaut-example

Kết quả như sau:

14ms, quá xuất sắc phải không các bạn? Gần như tức thì 😀

Bài viết gốc được đăng tải tại huongdanjava.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Tại sao KHÔNG NÊN DÙNG FILE GHOST chia sẻ trên mạng?

file ghost
Tại sao KHÔNG NÊN DÙNG FILE GHOST chia sẻ trên mạng?

Bài viết được sự cho phép của blogchiasekienthuc.com

Có lẽ, ai sử dụng máy tính chắc cũng đã ít nhất một lần sử dụng file ghost được chia sẻ trên mạng để cài lại máy tính của mình rồi đúng không.

Đơn giản bởi vì file Ghost rất tiện lợi, nhanh chóng và dễ dàng tìm kiếm được ở trên mạng.

  5 loại profile của các Product Manager là gì?
  10 trình quản lý file hàng đầu trong JavaScript

Nhưng cũng có không ít người người khuyên rằng không nên sử dụng file Ghost để cài lại máy. Vậy lý do là gì? và nó có thực sự chính xác không?

NOTE: Admin đã có một bài viết so sánh Ghost với cài lại Windows rồi, một bài viết rất hay mà các bạn nên đọc.

Và trong bài viết này mình sẽ sử dụng thuật ngữ là Ghost nhé, mặc dù về lý thuyết thì có thể nó không đúng, mà chính xác hơn phải là file BACKUP hoặc file IMAGE mới đúng. Bởi hiện nay có rất nhiều phần mềm hỗ trợ tạo file BACKUP chứ không riêng gì Onekey Ghost hay Norton Ghost nữa..

Những chúng ta đã quá quen thuộc với thuật ngữ Ghost rồi và khi nói thì ai cũng hiểu. Vậy nên chúng ta sẽ thống nhất dùng thuật ngữ Ghost trong bài viết này ha.

co-nen-dung-file-ghost-khong (1)

#1. Ưu điểm của Ghost là gì?

Nhanh và tiện lợi là những gì có thể nói về Ghost:

Nhanh: Nếu rành về máy tính thì bạn chỉ cần chưa tới 5 phút để tìm ra file Ghost ưng ý (bỏ qua chuyện tải về).

Và bạn cũng chỉ mất tầm 7 tới 10 phút cho quá trình bung file Ghost (khi mà ổ cứng SSD lên ngôi như hiện nay), hơn nữa trong lúc bung file Ghost thì gần như bạn không cần bất kì một thao tác gì thêm => bạn có thể xử lý được nhiều máy cùng một lúc.

Tiện lợi: Thông thường, những file Ghost được chia sẻ hiện nay có đến 90% là file ghost đa cấu hình, tức là những file ghost này đã được tích hợp sẵn driver và một vài phần mềm cần thiết khác.

Tất nhiên, nếu muốn thì bạn cũng có thể tìm những bản ghost chưa cài đặt bất kì một ứng dụng nào, mới tinh như lúc vừa cài Windows xong.

Tức là nhiều lắm thì bạn chỉ mất 15 – 20 phút cho một lần cài lại máy với phương pháp Ghost này thôi là cơ bản đã có những gì bạn cần rồi. Điều này khó có thể làm được nếu cài lại Windows bằng cách thông thường, tốn gấp đôi thời gian là ít.

#2. Những nguy hiểm tiềm tàng khi sử dụng bản GHOST trên mạng

co-nen-dung-file-ghost-khong (2)

Như các bạn đã biết, bản thân file ghost thực tế là do một cá nhân (chiếm đa số), hay một nhóm nào đó làm ra.

Tất nhiên là sẽ có những cá nhân tốt bụng, tâm huyết và muốn thực sự cống hiến cho cộng đồng mà không có bất kỳ vụ lợi gì.

Hoặc cũng có những cá nhân tạo file ghost ra để thúc đẩy trang web của họ, giúp trang web phát triển mạnh mẽ hơn… rồi từ đó kiếm tiền theo một cách khác.

Những người kể trên thì OK, quá tốt rồi. Không có gì phải bàn cãi gì thêm..

Thế nhưng ở đời đâu phải ai cũng tốt như thế, lòng người khó đoán lắm các bạn ạ. Cứ nhìn những gì cô Phương Hằng bóc mẽ trong thời gian gần đây là bạn sẽ thấy, rất nhiều người mà trước đây bạn tin tưởng tuyệt đối thì hóa ra lại không tốt đẹp như bạn nghĩ..

Bởi vậy mới nói, khó đoán nhất là lòng người.

Trở lại với vấn đề chính của bài viết, ngoài những người tạo file Ghost với mục đích “chia sẻ từ tâm” ra thì cũng có không ít những người làm vì vụ lợi, làm vì mục đích xấu.

Thực sự thì không có một cơ sở, hay thông tin nào có thể đảm bảo rằng file ghost mà bạn tải về có thực sự sạch sẽ hay không. Không ai kiểm chứng cả !

Bởi đa số các file ghost đều được tùy chỉnh khá sâu vào hệ thống để giảm dung lượng file GHOST.

Hơn nữa, họ cũng tích hợp khá nhiều phần mềm bản quyền (đã được bẻ khóa) vào file GHOST. Mà bẻ khóa thì phải làm gì? Vâng, cờ ráck chứ còn gì nữa.

Mà việc bẻ khóa không thể đảm bảo được là nó an toàn tuyệt đối được, vậy nên một lần nữa, file Ghost lại có nguy cơ dính virus, keylogger (kể cả là người làm ghost không có ý đồ đi chăng nữa).

Vậy nên, việc tìm và tải những file ghost của người có uy tín là điều rất quan trọng. Mà chữ UY TÍN ở đây thì cũng khó nói lắm 🙂

#3. Không tương thích hoàn toàn với phần cứng

co-nen-dung-file-ghost-khong (3)

Vì là driver của các bộ cài tự động, thực chất đây là một bộ cài với tổng hợp rất nhiều driver phổ biến cho các thiết bị phần cứng khác nhau nên nó chỉ dừng lại ở mức hoạt động được, chứ hiệu suất của phần cứng không đạt được sức mạnh tối đa.

Tuy nhiên, nếu là bản ghost Windows 10 hay các phiên bản mới hơn thì tình trạng này sẽ đỡ hơn, vì bản thân Windows 10 đã khá đầy đủ driver rồi. Và các driver cũng được tự động cập nhật qua những lần bạn update sau này.

Vấn đề hiệu suất giảm khi sử dụng phương pháp Ghost được rất nhiều người công nhận, nó không thể hoạt động với hiệu năng như khi chúng ta cài Win được.

Chính vì lý do đó mà đôi khi, mặc dù bạn sử dụng card đồ họa thế hệ mới, hay mainboard đời mới nhưng khi chơi game, khi sử dụng các tác vụ nặng, hay thậm chí là cả những lúc bình thường… đôi khi sẽ xảy ra tình trạng giật, lag nhẹ..

#4. Vậy tóm lại là có nên sử dụng file ghost được chia sẻ trên mạng hay không?

Cái này thì tùy thuộc vào cá nhân bạn. Nhưng cách tối ưu nhất mà mình khuyên bạn là nên tự tạo ra một file Ghost cho riêng mình.

Tức là ban đầu bạn hãy cài một bản Win sạch sẽ, cài driver, phần mềm đầy đủ theo nhu cầu sử dụng của bạn => sau đó thực hiện backup lại để sử dụng về sau này. Đây là phương án mình nghĩ là ổn áp nhất hiện tại.

cach-su-dung-dlc-boot-5

NHƯNG, nếu bạn không am hiểu nhiều về máy tính, không rành cách tạo file ghost hay cài đặt các phần mềm cần thiết cho máy tính thì việc sử dụng các file ghost được chia sẻ trên mạng là một sự lựa chọn hợp lý. Tất nhiên bạn phải tìm được nguồn tải uy tín.

Còn nếu bạn là người rành rọt, muốn làm chủ hoàn toàn máy tính của bạn và để máy tính hoạt động với hiệu năng ổn nhất thì bạn nên tự cài Win nhé.

#5. Lời Kết

Vâng, trên đây là những lý do mà một số người khuyên bạn không nên sử dụng file ghost được chia sẻ trên mạng, còn thực tế thì tùy thuộc vào nhu cầu cũng như khả năng của mỗi người để đưa ra những quyết định hợp lý riêng.

Hi vọng là bài viết này sẽ hữu ích với bạn. Hãy chia sẻ quan điểm của bạn về việc sử dụng file ghost được chia sẻ ở trên mạng ở bên dưới phần commet để a/e thảo luận thêm nhé !

CTV: Lê Đinh Hoàng Vũ – Bài viết gốc tại blogchiasekienthuc.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Hibernate Query Language (HQL)

Hibernate Query Language
Hibernate Query Language (HQL)

Bài viết được sự cho phép của tác giả Giang Phan

Hibernate cung cấp một vài cách để thao tác dữ liệu với database như Hibernate Query Language (HQL), Hibernate Criteria Queries, Native Queries, … Trong bài viết này, tôi sẽ giới thiệu với các bạn Hibernate Query Language (HQL), trong các bài viết tiếp theo chúng ta sẽ lần lượt tìm hiểu các cách còn lại.

  Hibernate Cache

Giới thiệu Hibernate Query Language (HQL)

Hibernate Query Language (HQL) là một ngôn ngữ truy vấn hướng đối tượng (OOP), tương tự như SQL (Structured Query Language) nhưng thay vì làm việc trên các bảng và cột, HQL làm việc với các đối tượng persistent và các thuộc tính của chúng. Các truy vấn HQL được  đổi bởi Hibernate thành các truy vấn SQL thông thường, lần lượt thực hiện các công việc trên cơ sở dữ liệu. Nhờ vậy mà nó là một ngôn ngữ truy vấn độc lập cơ sở dữ liệu, không phụ thuộc vào bất kỳ database nào.

Mặc dù, ta có thể sử dụng các câu lệnh SQL trực tiếp với Hibernate bằng cách sử dụng Native SQL. Nhưng chúng ta nên sử dụng HQL bất cứ khi nào có thể để tránh sự phức tạp về tính linh hoạt của cơ sở dữ liệu và tận dụng chiến lược generation và caching của Hibernate.

HQL sử dụng các từ khoá của SQL như FROM và WHERE, … nên chúng ta sẽ dễ dàng tìm hiểu HQL nếu đã có kiến thức về SQL.

Đặc điểm của HQL

Case Sensitivity: HQL không phân biệt hoa thường, ngoại trừ các thuộc tính như tên class, thuộc tính, tên biến có phân biệt chữ hoa chữ thường. Chẳng hạn: SeLeCTSELECTselect là như nhau. Tuy nhiên, com.gpcoder.entities.User và com.gpcoder.entities.USER là khác nhau.

HQL From: mệnh đề From trong HQL có ý nghĩa tương đương với SQL, chúng ta cũng có thể đặt alias cho nó. Chẳng hạn: From User u, là tương đương với SELECT * From User as u.

HQL Join: HQL hỗ trợ tất cả loại join trong SQL như INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN.

Aggregate Function: hỗ trợ rất nhiều aggregate function như count(*), count(distinct x), min(), max(), avg() and sum().

Expressions: chúng ta có thể sử dụng các biểu thức so sánh, tính toán trong HQL như: arithmetic expressions (+, -, *, /), omparison operators (=, >=, <=, <>, !=, like), omparison operators (=, >=, <=, <>, !=, like), …

Ngoài ra, HQL còn hỗ trợ:

  • Order by, group by, having, Sub-query, … tương tự như SQL.
  • DM (Ngôn ngữ Thao tác Dữ liệu – Data Manipulation Language): INSERT, UPDATE và DELETE là các câu lệnh DML.
  • DDL (Ngôn ngữ Định nghĩa Dữ liệu – Data Definition Language): CREATE, ALTER, DROP, RENAME là các câu lệnh DDL.
  • Thực thi store procedure.

Ví dụ sử dụng HQL

Cơ sở dữ liệu

Chúng ta sẽ sử dụng lại database ở các bài viết trước.

Tạo các Entity và các mapping

Các Entity tương ứng:

Role.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table
public class Role {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column
    private String name;
    
    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "roles")
    private Set<User> users;
}

User.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import java.util.Date;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;
import lombok.Data;
@Data
@Entity(name = "User")
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column
    private String fullname;
    @Column(nullable = false, length = 255, unique = true)
    private String username;
    @Column(nullable = false)
    private String password;
    @Column(name = "created_at")
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date createdAt;
    @Column(name = "modified_at")
    @Temporal(value = TemporalType.TIMESTAMP)
    private Date modifiedAt;
    @Transient
    private String additionalPropery;
    
    @OneToOne(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL)
    private UserProfile userProfile;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    @OrderBy("title")
    private Set<Post> posts;
    
    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "user_roles",
        joinColumns = { @JoinColumn(name = "user_id", nullable = false, updatable = false) },
        inverseJoinColumns = { @JoinColumn(name = "role_id", nullable = false, updatable = false) })
    @OrderBy("name")
    private Set<Role> roles;
}

UserProfile.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table(name = "user_profile")
public class UserProfile {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String address;
    private Integer gender;
    @OneToOne(fetch = FetchType.LAZY)
    @PrimaryKeyJoinColumn(name = "user_id", foreignKey = @ForeignKey(name = "fk_user_profile"))
    private User user;
}

Category.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table
public class Category {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column
    private String name;
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "category")
    @OrderBy("title")
    private Set<Post> posts;
}

Post.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ForeignKey;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import lombok.Data;
@Data
@Entity
@Table
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String title;
    private Integer content;
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false,
        foreignKey = @ForeignKey(name = "fk_post_user"))
    private User user;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "category_id", nullable = false,
        foreignKey = @ForeignKey(name = "fk_post_category"))
    private Category category;
}

Hibernate Configuration XML

Tạo file hibernate.cfg.xml  và đặt nó trong thư mục src\main\resources

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- Database setting -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://192.168.64.2:3306/gp_system?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8</property>
        <property name="connection.username">admin</property>
        <property name="connection.password">1234567</property>
        
        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">4</property>
        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>
        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
        <!-- Show all executed SQL to console -->
        <property name="show_sql">true</property>
        <!-- Entity mapping -->
        <mapping class="com.gpcoder.entities.User" />
        <mapping class="com.gpcoder.entities.Role" />
        <mapping class="com.gpcoder.entities.UserProfile" />
        <mapping class="com.gpcoder.entities.Category" />
        <mapping class="com.gpcoder.entities.Post" />
        
    </session-factory>
</hibernate-configuration>

Tạo đối tượng SessionFactory

HibernateUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.gpcoder.utils;
 
import org.hibernate.SessionFactory;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.service.ServiceRegistry;
 
public class HibernateUtils {
 
    private static final SessionFactory sessionFactory = buildSessionFactory();
 
    private HibernateUtils() {
        super();
    }
 
    private static SessionFactory buildSessionFactory() {
        ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() //
                .configure() // Load hibernate.cfg.xml from resource folder by default
                .build();
        Metadata metadata = new MetadataSources(serviceRegistry).getMetadataBuilder().build();
        return metadata.getSessionFactoryBuilder().build();
    }
 
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
 
    public static void close() {
        getSessionFactory().close();
    }
}

Để thao tác với cơ sở dữ liệu, chúng ta cần tạo 1 đối tượng session:

1
2
3
4
5
6
7
8
try (Session session = HibernateUtils.getSessionFactory().openSession();) {
    // Begin a unit of work
    session.beginTransaction();
    // HQL
    session.getTransaction().commit();
}

Ví dụ mệnh đề FROM

Lấy danh sách User:

1
2
String hql = "FROM User";
List<User> users = session.createQuery(hql, User.class).list();

Lấy 1 user theo id là 1

1
2
String hql = "FROM User AS u WHERE u.id = :id";
User user = session.createQuery(hql, User.class).setParameter("id", 1L).uniqueResult();

Lưu ý: từ khoá AS là tuỳ chọn, chúng ta có thể không sử dụng AS để đặt alias.

Ví dụ mệnh đề SELECT

Nếu không có mệnh đề SELECT, HQL sẽ lấy tất cả các field của Entity. Chúng ta có thể giới hạn số lượng cột cần lấy sử dụng mệnh đề SELECT.

Ví dụ lấy username của 1 user

1
2
String hql = "SELECT u.username FROM User u WHERE u.id = :id";
String username = session.createQuery(hql, String.class).setParameter("id", 1L).uniqueResult();

Ví dụ mệnh đề WHERE

Tương tự như SQL, nếu bạn muốn giới hạn các đối tượng cụ thể được trả về từ cơ sở dữ liệu, ta sử dụng mệnh đề WHERE.

Ví dụ: lấy danh sách user được tạo trong tháng hiện tại:

1
2
String hql = "FROM User u WHERE month(u.createdAt) = month(sysdate())";
List<User> users = session.createQuery(hql, User.class).list();

Ví dụ mệnh đề ORDER BY

Để sắp xếp kết quả truy vấn HQL, ta sẽ sử dụng mệnh đề ORDER BY. Có thể sắp xếp các kết quả theo bất kỳ thuộc tính nào trên các đối tượng trong tập kết quả hoặc tăng dần (ASC) hoặc giảm dần (DESC).

Ví dụ: lấy danh sách user được tạo trong tháng hiện tại và sắp xếp ngảy tạo giảm dần, username tăng dần.

1
2
String hql = "FROM User u WHERE month(u.createdAt) = month(sysdate()) ORDER BY u.createdAt DESC, u.username ASC";
List<User> users = session.createQuery(hql, User.class).list();

Ví dụ mệnh đề GROUP BY

Mệnh đề này cho phép HQL lấy thông tin từ cơ sở dữ liệu và phân nhóm chúng dựa trên giá trị của thuộc tính.

Ví dụ đếm số lượng user được tạo theo mỗi tháng của năm hiện tại.

1
2
String hql = "SELECT month(createdAt) AS month, COUNT(id) AS numberOfUser FROM User WHERE year(createdAt) = year(sysdate()) GROUP BY month(createdAt) HAVING COUNT(id) > 3";
List<Object[]> result = session.createQuery(hql).list();

Ví dụ mệnh đề UPDATE

Mệnh đề UPDATE có thể được sử dụng để cập nhật một hoặc nhiều thuộc tính của một hoặc nhiều đối tượng.
Chúng ta sử dụng phương thức executeUpdate() để thực hiện các câu lệnh HQL UPDATE hoặc DELETE.

Ví dụ: update thông tin fullname và password của user có id là 1.

1
2
3
4
5
6
String hql = "UPDATE User SET fullname = :fullname, password = :password WHERE id = :id";
Query query = session.createQuery(hql);
query.setParameter("fullname", "GP CODER");
query.setParameter("password", "gpcoder.com");
query.setParameter("id", 1L);
int affectedRows = query.executeUpdate();

Ví dụ mệnh đề DELETE

Mệnh đề DELETE được sử dụng để xóa một hoặc nhiều đối tượng.

Ví dụ: xoá tất cả user được tạo trong tháng 2.

1
2
3
4
String hql = "DELETE FROM User WHERE month(createdAt) = :month";
Query query = session.createQuery(hql);
query.setParameter("month", 2);
int affectedRows = query.executeUpdate();

Ví dụ mệnh đề INSERT INTO

Mệnh đề INSERT INTO nơi mà các bản ghi có thể được insert từ một đối tượng này sang một đối tượng khác.

Ví dụ: copy tất cả user đang có và insert vào bảng user với user có prefix là “copyOf”.

1
2
3
String hql = "INSERT INTO User(fullname, username, password, createdAt, modifiedAt) SELECT fullname, CONCAT('copyOf', username) , password, sysdate(), sysdate() FROM User";
Query query = session.createQuery(hql);
int affectedRows = query.executeUpdate();

Ví dụ về phân trang

Có hai phương thức của giao tiếp Query cho việc phân trang:

  • setFirstResult(int startPosition)  : xác định hàng đầu tiên trong tập kết quả cần lấy, bắt đầu với hàng 0.
  • setMaxResults(int maxResult) : xác định số lượng hàngcần lấy.

Ví dụ: lấy 10 user bắt đầu từ user có thứ tự thứ 5.

1
2
3
4
5
String hql = "FROM User ORDER BY ";
Query query = session.createQuery(hql, User.class);
query.setFirstResult(5);
query.setMaxResults(10);
List<User> users = query.list();

Ví dụ về JOIN

HQL hỗ trợ các loại JOIN tương tự như SQL.

Ví dụ: lấy thông tin user và user profile. Do thông tin profile có thể có hoặc không, nên chúng ta sẽ sử dụng LEFT JOIN.

1
2
String hql = "FROM User u LEFT JOIN u.userProfile p WHERE u.id = :id";
List<Object[]> users = session.createQuery(hql).setParameter("id", 15L).list();

Trên đây là một số giới thiệu cơ bản về HQL, các bạn có thể tham khao thêm ở các link tham khảo bên dưới.

Tài liệu tham khảo:

Bài viết gốc được đăng tải tại gpcoder.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Chuyện gì xảy ra khi ta Throw Exceptions?

throw exceptions
Chuyện gì xảy ra khi ta Throw Exceptions?

Bài viết được sự cho phép của tác giả Kiên Nguyễn

1. Java Exceptions, bắt đầu nha

HỠI NHỮNG NGƯỜI ANH EM ĐỒNG MÔN!. EXCEPTIONS có gì mà khó.

ĐM, ai đồng môn với mày?. Tụi tao biết mày học môn phái gì mà đồng.

Ô, thế không phải à, thôi thì những bạn coder thân mến. Đã là lập trình viên thì thường xuyên phải đụng chạm tới Exceptions, cũng không thể tránh khỏi code có Exception (Ếch – xép – sần).

Java Exceptions

Làm việc đã lâu, nhưng mấy ai trong số anh em chúng ta hiểu tường tận về throw, catch exceptions. Cụ thể mọi việc đã được quỷ JVM thực hiện như thế nào?. Không thể mang tiếng làm việc thường xuyên mà không hiểu bản chất được.

  Phân biệt debounce và throttle
  Exception là gì? Tổng quan về Exception trong Java

Xem thêm tuyển lập trình viên Full Stack lương cao trên TopDev

Hiểu được bản chất sẽ luôn giúp chúng ta có cái nhìn tổng quan, khả năng ghi nhớ và ứng dụng tuyệt vời.

Vì vậy, Hỡi những người anh em, HÃY KÌM NÉN SỰ HÀO HỨNG. Ta sẽ cùng tìm hiểu ngay đây:

2. Đầu tiên, exceptions là gì?

SỢ?. SỢ chưa bao giờ có trong đầu của bố. Code exception ầm ầm, đưa cái định nghĩa đây!.

Có ngay, có ngay:

Exceptions are events that occur during the execution of programs that disrupt the normal flow of instructions (e.g. divide by zero, array access out of bound, etc.).

Exceptions là sự kiện xảy ra trong quá trình thực thi chương trình, phá vỡ luồng thực thi thông thường (như là chia cho 0, truy cập vị trí ngoài giới hạn của mảng).

Vậy chính ra exceptions không có gì là ghê ghớm, nhưng handle exceptions như thế nào?. Có bao nhiêu loại exceptions?. Câu trả lời sẽ có ngay sau đây:

3. Những kiểu bắt Exception

Dựa vào hình 7.8. Exceptions được chia thành 3 loại:

  1. Checked Exception
  2. Runtimes Exception
  3. Errors

Cả 3 class này đều extends từ class Java.Lang.Throwable.

3.1 Runtime exception

Là kiểu exception được throw trong quá trình thực thi của JVM. Một số loại thường gặp là:

  1. ArithmeticException : Exception xảy ra liên quan tới các điều kiện số học. Ví dụ chia cho 0 (divide by zero)
  2. ArrayIndexOutOfBoundsException : Truy cập tới chỉ mục ngoài mảng. Ví dụ như số âm hoặc địa chỉ lớn hơn hoặc bằng đọ dài mảng.
  3. ClassCastException : Xảy ra khi cố gắng cast một object sang một subclass mà object này lại không phải là thể hiện (instance) của lớp đó
  4. IllegalArgumentException : Khi method nhận đối số (argument) sai hoặc không hợp lệ (illegal or inappropriate argument).
  5. NullPointerException :
  6. NumberFormatException : Xảy ra khi convert kiểu string sang numeric, nhưng string lại không có format đúng. Ví dụ: int num=Integer.parseInt (“XYZ”);

3.1 Checked Exception

  1. IOException : Exception xảy ra liên quan tới các điều kiện số học. Ví dụ chia cho 0 (divide by zero)
  2. FileNotFoundException : Truy cập tới chỉ mục ngoài mảng. Ví dụ như số âm hoặc địa chỉ lớn hơn hoặc bằng đọ dài mảng.

4. Chuyện gì xảy ra khi ta Thrown Exception?

4.1 Method Call Stack

Cùng xem xét đoạn chương trình sau:

// For fun:
// This is comment
public class MethodCallStackDemo {
public static void main(String[] args) {
System.out.println("Enter main()");
methodA();
System.out.println("Exit main()");
}

public static void methodA() {
System.out.println("Enter methodA()");
methodB();
System.out.println("Exit methodA()");
}

public static void methodB() {
System.out.println("Enter methodB()");
methodC();
System.out.println("Exit methodB()");
}

public static void methodC() {
System.out.println("Enter methodC()");
System.out.println("Exit methodC()");
}
}
// Output chương trình sẽ là:
Enter main()
Enter methodA()
Enter methodB()
Enter methodC()
Exit methodC()
Exit methodB()
Exit methodA()
Exit main()

Qua ví dụ trên, để hiểu cách thức hoạt động của Call Stack, hãy hinh dung một chương trình chúng ta viết sẽ bao gồm nhiều method (A,B,C,Z,…), tất cả những thứ này sẽ được quản lý bằng ngăn xếp (Call Stack).

Nhắc tới là nhớ ngay StackOverflow, may mắn thay câu hỏi nào đặt trước sẽ được trả lời khi có người rảnh vào trả lời, chứ không phải là trả lời theo kiểu LIFO như CallStack.

Các bước tiến hành sẽ là:

  1. JVM gọimain().
  2. main() được đẩy vào stack, trước khi gọi methodA().
  3. methodA() đẩy vào stack, trước khi gọi methodB().
  4. methodB() đẩy vào stack, trước khi gọi methodC().
  5. methodC() hoàn thành.
  6. methodB() đẩy ra khỏi stack – hoàn thành.
  7. methodA() đẩy ra khỏi stack – hoàn thành.
  8. main() đẩy ra khỏi stack – hoàn thành. Kết thúc chương trình.
Java quản lý exceptions bằng stack, truy xuất và gọi theo cơ chế LIFO (Last In First Out)

4.2 Exception & Call Stack

When an exceptions occurs inside a Java method, the method creates an Exceptions object and passes the Exceptions object to the JVM (in Java term, the method “throw” an Exception). The Exceptions object contains the type of the exceptions, and the state of the program when the exceptionsoccurs. The JVM is responsible for finding an exception handler to process the Exception object. It searches backward through the call stack until it finds a matching exception handler for that particular class of Exceptions object (in Java term, it is called “catch” the Exceptions). If the JVM cannot find a matching exception handler in all the methods in the call stack, it terminates the program.

Khi exceptions xảy ra trong một phương thức Java, phương thức đó sẽ tạo ra một object Exceptions và mang đối tượng đó tới JVM (thuật ngữ Java gọi là throw). Đối tượng này sẽ chứa kiểu của exceptions, trạng thái của chương trình khi exceptions xuất hiện. JVM lúc này sẽ làm việc để phản hồi để tìm đối tượng có thể xử lí được exceptions object này. Bằng cách tìm kiếm trong stack cho tới khi tìm ra được đối tượng có thể xử lí được exceptions (thuật ngữ Java gọi là catch). Nếu JVM không tìm kiếm được phương thức nào có thể handler được exceptions, nó sẽ kết thúc chương trình.

JVM sẽ tìm kiếm ngược trong stack để tìm kiếm method handler exception

methodD() sẽ throws ra FrogCeption, JVM sẽ tìm ngược trong stack để tìm ra phương thức handler được FrogCeption -> tìm ra methodA(). Một lưu ý nhỏ là 2 method B và C sẽ phải throws FrogCeption

4.3 Ví dụ cụ thể

Ví dụ không dành cho người quá trong sáng:

// Ví dụ cho người hiểu sâu về nền công nghiệp không khói.
public class Porn {
public static void main(String args[]) {
pornName(); 
}
public static void pornName() {
name();
}
}
public static void name() {
// ĐM, hẳn là class students - cosplay luôn à ba?
String[] students = {"**la Takizawa", "**ika Momotani"};
System.out.println(students[5]);
}

Trường hợp này, method pornName() cố gắng gọi method name(). Tuy nhiên, array chỉ có size là 2, nên sẽ có ArrayIndexOutOf- BoundsException lúc chạy.

Class Throwable lúc này đưa tất cả những thứ có liên quan (hàm gọi, vị trí dòng gọi, …) vào stack. Như cái logo của stackoverflow ấy. Sau đó ném ra:

// Ví dụ cho người hiểu sâu về nền công nghiệp không khói.
Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsException: 5
// Lỗi ở thằng name()
at Porn.name(Porn.java:13)
// Do name() gọi qua pornName()
at Porn.pornName(Porn.java:7)
// Do pornName() gọi qua main()
at Porn.main(Porn.java:4)

Lưu ý là khi lấy data từ stack thì theo thứ tự LIFO (Last In First Out). Thằng main() vào trước tiên, nên nó ra sau cùng, cu name() thì vào sau cùng, ra trước tiên.

Depending on the complexity of your code, a stack trace can range from a few lines to hundreds of lines of code. A stack trace works with handled and unhandled exceptions.

Tùy thuộc độ phức tạp mà khi ae chúng ta code, stack có thể chưa tới một hoặc vài trăm dòng mã (nghe lạnh cả lưng). Stack trace làm việc với cả exceptions handle và unhandle.

Hiểu cái thằng Stack này cũng giống như cách OS (Operator System) hoạt động.

  1. Main() được goi -> đẩy nó vào stack.
  2. Main() gọi thằng pornName() -> đẩy thêm cu này vào stack.
  3. pornName() gọi name() -> ném luôn name() vào stack.
  4. name() chạy exceptions, vì nó không handle -> đẩy tới thằng gọi nó (pornName())
  5. Quỷ pornName() này cũng không handle -> tới ông nội gọi nó (main())

Done, thằng JVM bắn cảnh bảo đỏ -> Lôi toàn bộ trong stack ra (nhắc lại là LIFO – đm, nhắc miết).

Ngoài lề tí xíu, nếu chưa biết **la Takizawa thì anh em đồng râm có thể vào đây để xem qua cho biết.

5. Không handle là thế – giờ dùng try-catch-finally thì sao?

Đầu tiên, để đùng dược phải hiểu nó là gì?.

Try – cố – cố cái gì?.
Cố đấm ăn xôi. Không. Cố execute cái đoạn code các bác viết trong đó thôi.

Catch – bắt – bắt cái gì?
Bắt ngoại lệ – chỉ định bắt cái gì thì bắt cái đó.

Finally thì không hỏi cùn nữa
Có cố hay bắt thì cũng thực hiện.

6. Hiểu hết rồi, thử sức thôi!

Ngon lành cành đào rồi, cùng làm thử vài câu trắc nghiệm:

// Ví dụ cho người hiểu sâu về nền công nghiệp không khói.
Exception in thread "main"
java.lang.ArrayIndexOutOfBoundsException: 5
// Lỗi ở thằng name()
at Porn.name(Porn.java:13)
// Do name() gọi qua pornName()
at Porn.pornName(Porn.java:7)
// Do pornName() gọi qua main()
at Porn.main(Porn.java:4)
  1. ArrayIndexOutofBoundsException
  2. FileNotFoundException
  3. StackOverflowException
public class Test 
{ 
public static void main(String[] args) 
{ 
try
{ 
System.out.printf("1"); 
int sum = 9 / 0; 
System.out.printf("2"); 
} 
catch(ArithmeticException e) 
{ 
System.out.printf("3"); 
} 
catch(Exception e) 
{ 
System.out.printf("4"); 
} 
finally
{ 
System.out.printf("5"); 
} 
} 
}
  1. 1325
  2. 1345
  3. 1342
  4. 135
public class Test 
{ 
private void m1() 
{ 
m2(); 
System.out.printf("1"); 
} 
private void m2() 
{ 
m3(); 
System.out.printf("2"); 
} 
private void m3() 
{ 
System.out.printf("3"); 
try
{ 
int sum = 4/0; 
System.out.printf("4"); 
} 
catch(ArithmeticException e) 
{ 
System.out.printf("5"); 
} 


System.out.printf("7"); 
} 
public static void main(String[] args) 
{ 
Test obj = new Test(); 
obj.m1(); 
} 
}
  1. 35721
  2. 54721
  3. 3521
  4. 35

7. Tổng kết

  • Exception cho thấy là đoạn chương trình có gì đó không như mong muốn xảy ra (something unexpected happened).

Bài viết gốc được đăng tải tại kieblog.vn

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Giới thiệu về Quarkus

quarkus
Giới thiệu về Quarkus

Bài viết được sự cho phép của tác giả Nguyễn Hữu Khanh

Ngày nay, việc phát triển và deploy các ứng dụng lên Cloud không còn là chuyện quá xa lạ. Chúng ta không cần phải lo lắng nhiều về cơ sở hạ tầng để deploy ứng dụng, mọi thứ Cloud Providers đã setup sẵn, chỉ cần tập trung phát triển ứng dụng mà thôi.

Xu hướng của deploy ứng dụng trên Cloud là làm sao có thể adapt được việc scalable, nói nôm na là chúng ta có thể deploy ứng dụng load balancer, có thể handle một số lượng lớn các request từ người dùng tại cùng một thời điểm. Để làm được điều này, deployment strategy của chúng ta phải đáp ứng được việc số lượng instance của application có thể tăng giảm dựa vào traffic tới application và đồng thời, khi start instance mới để handle request người dùng, thời gian start nhanh nhất có thể.

  "Ở Việt Nam, cơ hội để thực sự làm về Trí tuệ nhân tạo còn quá ít, trong khi những thứ mang hình thù và dáng dấp AI thì quá nhiều"
  10 Kỹ năng quan trọng cần có của Front-end để tìm công việc dễ dàng hơn

Đối với các script language như JavaScript, PHP, hay Python thì khi start một instance mới của ứng dụng, gần như chúng có thể handle request từ người dùng liền. Thế nhưng với Java, các ứng dụng cần thời gian start mới có thể handle request được.

Hiểu được những hạn chế đó, có nhiều framework, library mới của Java được giới thiệu để giải quyết ít nhiều vấn đề start time này, hướng tới giúp chúng ta có thể phát triển các ứng dụng Cloud Native với Java. Một trong số đó có Quarkus, một Supersonic Subatomic Java, tối ưu hoá để có thể chạy các ứng dụng Java sử dụng các container trên môi trường Cloud.

Trong bài viết này, mình sẽ giới thiệu với các bạn tổng quan về cách up và running một ứng dụng Java sử dụng Quarkus để xem, thời gian chạy lên một ứng dụng với Quarkus mất bao lâu các bạn nhé!

Tạo mới Quarkus project

Tương tự như Spring framework với Spring Initializr https://start.spring.io/, Quarkus cũng có một công cụ giúp chúng ta có thể tạo mới nhanh một Quarkus project tại https://code.quarkus.io/.

Các bạn có thể tạo mới nhanh một ứng dụng Jakarta EE chạy với Quarkus sử dụng trang này.

Ví dụ mình tạo mới một ứng dụng Jakarta EE MVC bằng cách khai báo sử dụng RESTEasy JAX-RS, một implementation của Jakarta EE Java API for RESTful Web Services, như sau:

Nhấn Generate your application:

và download project về máy nhé các bạn.

Kết quả mở project trong IntelliJ:

Mặc định như các bạn thấy, nếu các bạn chọn sử dụng RESTEasy JAX-RS trong project của mình, Quarkus Code sẽ generate một class GreetingResource định nghĩa endpoint “/hello” sử dụng JAX-RS:

package com.huongdanjava;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "Hello RESTEasy";
}
}

Chạy ứng dụng

Các bạn có thể chạy ứng dụng này lên sử dụng ở development mode sử dụng quarkus-maven-plugin được khai báo sẵn với generated project, bằng cách chạy Maven command như sau:

compile quarkus:dev

Mở trình duyệt và đi đến địa chỉ http://localhost:8080/, các bạn sẽ thấy kết quả như sau:

Mở Console của IntellJ, các bạn sẽ thấy những dòng log sau:

Listening for transport dt_socket at address: 5005
Press [h] for more options>
Tests paused
Press [r] to resume testing, [h] for more options>
Press [r] to resume testing, [o] Toggle test output, [h] for more options>
__ ____ __ _____ ___ __ ____ ______ 
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \ 
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/ 
2021-09-05 07:00:35,633 INFO [io.quarkus] (Quarkus Main Thread) quarkus-jakartaee-mvc 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.2.1.Final) started in 2.791s. Listening on: http://localhost:8080
2021-09-05 07:00:35,653 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2021-09-05 07:00:35,654 INFO [io.quarkus] (Quarkus Main Thread) Installed features: [cdi, resteasy, smallrye-context-propagation]

Ở dòng 10 của đoạn log trên, nếu các bạn để ý thì thời gian start của ứng dụng ví dụ này là 2.791s. Điều này là bình thường, không có gì quá ngạc nhiên phải không các bạn?

Nhưng nếu bây giờ các bạn chạy ứng dụng này bằng command line, với tập tin JAR, bằng cách: mở Terminal trên macOS hoặc Linux hoặc Console trên Window, đi đến thư mục project, chạy command:

mvn clean package

sau đó thì vào thư mục tartget/quarkus-app, chạy câu lệnh:

java -jar quarkus-run.jar

các bạn sẽ thấy kết quả như sau:

Như các bạn thấy, thời gian start ứng dụng bây giờ còn ít hơn cả một nửa lúc chúng ta chạy ở development mode trong IntelliJ, chỉ còn 0.779s.

Nếu các bạn build ứng dụng này với profile native sử dụng GraalVM với native-image component, với command:

mvn package -Dnative

thì các bạn có thể chạy trực tiếp ứng dụng sử dụng tập tin quarkus-jakartaee-mvc-1.0.0-SNAPSHOT-runner trong thư mục target của project.

Thời gian start ứng dụng sẽ làm các bạn kinh ngạc như sau:

Nhanh lắm các bạn, chỉ cần nhấn execute command là ứng dụng start liền. Như các bạn thấy, chỉ mất 0.014s là ứng dụng ví dụ của chúng ta đã up và running rồi. Đây cũng chính là thời gian mà ứng dụng có thể up và running trên môi trường Cloud đó các bạn.

Quá ổn phải không các bạn?

Bài viết gốc được đăng tải tại huongdanjava.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Xu Hướng Chuyển Động & Cơ Hội Tìm Việc Làm Sau Dịch

tìm việc làm sau dịch
Xu Hướng Chuyển Động & Cơ Hội Tìm Việc Làm Sau Dịch

Đợt bùng phát dịch Covid-19 lần thứ tư tại Việt Nam đã gây ra những tổn thương không nhỏ cho các doanh nghiệp cũng như tình hình phát triển kinh tế của cả nước. Do ảnh hưởng của dịch, hàng loạt công ty, nhà máy, xí nghiệp phải đóng cửa, hệ lụy kéo theo là hàng triệu lao động lâm vào tình cảnh mất việc, không có thu nhập. Các chính sách về việc cân nhắc mở cửa và cho hoạt động lại doanh nghiệp đang được xem xét. Vậy cơ hội tìm việc làm sau dịch của người lao động sẽ diễn ra theo xu hướng như thế nào?

tìm việc làm sau dịch

Khó khăn chung của người lao động trong bối cảnh dịch bệnh phức tạp

Trong Hội nghị trực tuyến sơ kết công tác lao động, báo cáo của Tổng cục thống kê cho thấy đến hết quý II năm nay, cả nước có trên 12,8 triệu người trên 15 tuổi bị ảnh hưởng tiêu cực bởi đại dịch. Trong số đó, có khoảng 75% số lượng lao động ở nông thôn bị ảnh hưởng so với người lao động ở khu vực thành thị. Số lao động thất nghiệp lên đến hơn 1,2 triệu người, và đa phần là các lao động trẻ. Đây có thể xem là khoảng thời gian cực kỳ khó khăn và tạo ra nhiều ảnh hưởng xấu đến đời sống của người dân.

Nắm bắt và hiểu rõ những khó khăn này cũng như có thể hỗ trợ người lao động trong bối cảnh mới, Chính phủ đã có chính sách hỗ trợ khoảng 4.500 tỷ đồng đào tạo và đào tạo lại cho lao động, góp phần nâng cao kỹ năng cho người lao động. Đây được xem là cơ hội hấp dẫn để những người lao động trẻ còn thiếu tay nghề, các đối tượng “dễ bị tổn thương” do tác động bên ngoài có thể nâng cao kỹ năng và kiến thức chuyên môn, tạo cơ hội tìm việc làm sau dịch dễ dàng hơn.

Xem thêm nhiều việc làm IoT Development hấp dẫn trên TopDev

Xu hướng và cơ hội tìm việc làm sau dịch

Bên cạnh những hỗ trợ tích cực từ phía nhà nước, xu hướng công việc cũng như những cơ hội việc làm nào sau dịch sẽ cần người lao động nhất? Hành vi tiêu dùng, nhu cầu xã hội, phương thức hoạt động doanh nghiệp,… sẽ là những yếu tố có tác động mạnh nhất đến cơ hội việc làm sau đại dịch.

Nhóm ngành Y tế – sức khỏe

Trong suốt 2 năm diễn ra dịch bệnh, tầm quan trọng của ngành Y tế đã liên tục được nhấn mạnh và lực lượng lao động trong nhóm ngành này sẽ vẫn tiếp tục là trụ cột trong tương lai. Việc tập trung phát triển nhân lực cho nhóm ngành Y tế sẽ giúp đất nước có được nguồn lực quan trọng cho việc chiến thắng và vượt qua đại dịch.

y tế sức khỏe

Đặc biệt, các nhóm lao động như y sĩ, dược sĩ, dịch tễ học,… sẽ là nhóm đối tượng có cơ hội việc làm rất cao. Lĩnh vực y tế sẽ rất cần tăng cao lực lượng lao động để phục vụ cho việc khám và điều trị, nghiên cứu cũng như ứng dụng các giải pháp y khoa tiên tiến trên thế giới để phục vụ cho việc chăm sóc bệnh nhân.

  5 điều NÊN và KHÔNG NÊN khi review tăng lương mà lập trình viên nào cũng nên biết!
  TOP 4 Công Việc Có Thu Nhập Hấp Dẫn Trong Tương Lai

Nhóm ngành khoa học – công nghệ

Ảnh hưởng của dịch càng cho thấy sức tác động của công nghệ thông tin và khoa học lên đời sống hàng ngày của chúng ta. Các giao dịch thương mại điện tử phát triển mạnh từ khi dịch xảy ra đã cho thấy việc số hóa các nền tảng dịch vụ trong tương lai sẽ trở thành yêu cầu tất yếu. Sự tiện lợi mà công nghệ mang đến cho con người đã giúp cho nhu cầu nhân lực trong ngành này ngày một tăng cao.

khoa học công nghệ
Khoa học công nghệ là xu thế tất yếu của thời đại

Sự “sống sót” của các doanh nghiệp công nghệ thông tin trong dịch bệnh là chứng minh rõ ràng nhất cho điều này. Cơ hội việc làm sau dịch với nhóm ngành này cả trước, trong và sau dịch chắc chắn sẽ vẫn còn đầy hấp dẫn. Các công ty và doanh nghiệp cần nguồn lao động có trình độ cao để có thể tiếp tục duy trì, triển khai những nền tảng công nghệ tiên tiến và đáp ứng xu hướng thời đại.

Nhóm ngành giao thông vận tải

Việc mua bán hàng trực tuyến gia tăng cũng kéo theo nhu cầu nhân lực trong ngành vận chuyển hàng hóa và logistics tăng nhanh hơn hẳn. Nhân lực tăng cao để đảm bảo và quản lý hơn chuỗi cung ứng hàng hóa và việc lưu trữ, vận chuyển có thể đáp ứng được nhu cầu cực lớn từ phía người tiêu dùng.

giao thông vận tải
Giao thông vận tải trở thành xu thế mới

Bên cạnh những nhóm ngành được đánh giá có cơ hội việc làm sau dịch tăng cao thì cũng có một số ngành nghề mà yêu cầu nhân sự sẽ giảm so với trước khi dịch bệnh xảy ra. Theo đó, ngành bán lẻ truyền thống, dịch vụ ẩm thực, dịch vụ du lịch và các công việc hỗ trợ văn phòng sẽ trở thành một trong những ngành không cần nhân lực quá lớn.

Xu hướng luôn thay đổi khi công nghệ mới ra đời, dịch bệnh là một trong những yếu tố tác động để những biến chuyển đó diễn ra nhanh hơn. Việc nắm bắt được xu hướng tuyển dụng với những ngành nghề đang hot sẽ giúp bạn trau dồi được kỹ năng chuyên môn của mình tốt hơn, hoặc có thể thay đổi và tìm hướng đi tốt nhất cho mình. Đón đọc thêm nhiều bài viết hấp dẫn khác tại TopDev bạn nhé!


Tuyển Dụng Nhân Tài IT Cùng TopDev
Đăng ký nhận ưu đãi & tư vấn về các giải pháp Tuyển dụng IT & Xây dựng Thương hiệu tuyển dụng ngay!
Hotline: 028.6273.3496 – Email: contact@topdev.vn
Dịch vụ: https://topdev.vn/page/products

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev

Cách sửa lỗi Taskbar không hoạt động trên máy tính Windows

sửa lỗi taskbar
Cách sửa lỗi Taskbar không hoạt động trên máy tính Windows

Bài viết được sự cho phép của blogchiasekienthuc.com

Taskbar là một thành phần không thể thiếu trên hệ điều hành Windows, đây là nơi hiển thị các icon rất quen thuộc như nút START, Windows Search, File Explorer, đồng hồ hệ thống….

Và khi sử dụng máy tính Windows thì chúng ta sẽ thường xuyên phải sử dụng đến thanh Taskbar này. Vậy sẽ ra sao nếu như thanh Taskbar này bị lỗi nhỉ?

  40 phím tắt dành cho người dùng Windows
  6 cách mở Services Management Console trên Windows 10

Tất nhiên rồi, mọi thao tác đều rất khó khăn, bạn không thể click vào được bất cứ icon nào trên thanh Taskbar, hay thậm chí là thanh Taskbar này còn bị mất luôn.

Chính vì thế, trong bài viết này mình sẽ tổng hợp lại những cách sửa lỗi trên thanh Taskbar này một các hiệu quả và an toàn nhất.

NOTE: Nếu bạn là người cẩn thận thì bạn nên thực hiện sao lưu Windows 10 với System Image để nếu có lỗi thì có thể phục hồi lại được trạng thái như hiện tại bất cứ lúc nào. Và bạn cũng yên tâm để làm theo hơn !

#1. Khởi động lại File Explorer [Reset File Explorer]

+ Bước 1: Ta nhấn tổ hợp phím CTRL + SHIFT + ESC để mở Task Manager lên.

cach-sua-loi-taskbar-tren-windows-10 (1)

+ Bước 2: Bạn chọn tab Processes => sau đó tìm đến và chọn tiến trình Windows Explorer => rồi bấm Restart để khởi động lại Explorer.

Hoặc bạn cũng có thể bấm chuột phải vào tiến trình đó rồi chọn Restart cũng được nhé.

cach-sua-loi-taskbar-tren-windows-10 (2)

+ Bước 3: Đợi một lát để File Explorer khởi động lại => sau đó, nếu thành công thì thanh Taskbar sẽ xuất hiện trở lại.

Ngoài cách bên trên ra thì còn rất nhiều các để Restart lại File Explorer, bạn có thể tham khảo thêm trong bài viết: 6 cách khởi động lại File Explorer trên Windows 11/ 10/ 8/ 7

#2. Quét virus cho máy tính

cach-sua-loi-taskbar-tren-windows-10 (1)

Đôi khi Taskbar của bạn bị lỗi là do virus có trong máy tính phá hoại. Hãy dành một chút thời gian của bạn để quét virus cho máy tính của bạn, không chỉ giúp sủa lỗi trên mà còn tránh những hiểm họa nặng nề hơn ở phía sau.

Nếu bạn dùng các phần mềm diệt virus bên thứ 3 như KIS, BIT, AVAST… thì những phần mềm diệt virus này sẽ tự động quét máy tính liên tục rồi.

Đối với máy tính sử dụng Windows 10, Windows 11 mà chỉ sử dụng công cụ Windows Defender thì bạn có thể tham khảo thêm bài viết này: Diệt Malware trên Windows 10 với Windows Defender Scan Offline

#3. Sử dụng tính năng Troubleshooter để Fix lỗi

Trên blog của chúng ta thì Admin và các bạn CTV đã chia sẻ về công cụ Fix lỗi này rất nhiều rồi. Microsoft cung cấp cho người dùng chúng ta một bộ công cụ để Fix lỗi trong quá trình sử dụng.

Vậy nên, không có lý do gì để không sử dụng chúng cả. Bạn có thể tham khảo các công cụ đó trong bài viết này: 6 công cụ hỗ trợ sửa lỗi trên Windows 10 do Microsoft cung cấp

+ Bước 1: Vào Settings sau đó theo đường dẫn sau: Update & Security => chọn tab Troubleshoot

cach-sua-loi-taskbar-tren-windows-10 (6)

+ Bước 2: Bạn chọn tiếp Additional troubleshooters để truy cập vào danh sách các công cụ Fix lỗi của Microsoft.

cach-sua-loi-taskbar-tren-windows-10 (7)

+ Bước 3: Bạn chọn Windows Store Apps.

cach-sua-loi-taskbar-tren-windows-10 (8)

+ Bước 4: Bây giờ bạn chỉ việc đợi cho Windows sửa lỗi mà thôi!

cach-sua-loi-taskbar-tren-windows-10 (9)

#4. Sử dụng lệnh DISM trong Windows Powershell

+ Bước 1: Bạn hãy mở PowerShell ở quyền Admin bằng cách nhấn tổ hợp phím Windows + X => sau đó chọn Windows PowerShell (Admin)

Hoặc bạn cũng có thể nhấn tổ hợp Windows + S để mở Windows Search => sau đó tìm kiếm với từ khóa PowerShell để mở công cụ dòng lệnh này lên nhé.

cach-sua-loi-taskbar-tren-windows-10 (10)

+ Bước 2: Bạn copy và paste lệnh sau vào cửa sổ dòng lệnh => sau đó nhấn Enter:

dism.exe /Online /Cleanup-image /Restorehealth

cach-sua-loi-taskbar-tren-windows-10 (11)

+ Bước 3: Cuối cùng, bạn nhấn Enter và chờ đợi. Sau đó bạn hãy khởi động lại máy tính và kiểm tra lại xem thanh Taskbar đã hoạt động ổn định trở lại chưa nhé.

#5. Sử dụng lệnh sfc /scannow

Lệnh này sửa được rất nhiều lỗi chứ không riêng gì Taskbar. Cách thực hiện thì cũng không có gì khó khăn cả.

+ Bước 1: Bạn vào Windows PowerShell với quyền Admin.

cach-sua-loi-taskbar-tren-windows-10 (10)

+ Bước 2: Bạn copy và paste lệnh sau vào cửa sổ dòng lệnh => sau đó nhấn Enter:

sfc /scannow

cach-sua-loi-taskbar-tren-windows-10 (12)

+ Bước 3: Bấm Enter vào chờ đợi. Cuối cùng bạn hãy khởi động lại máy tính và kiểm tra thanh Taskbar xem đã hoạt động lại chưa.

#6. Re-register cho Taskbar

+ Bước 1: Bạn mở Windows PowerShell với quyền Admin. Xem phần #4 bên trên nếu bạn chưa biết cách làm nhé.

cach-sua-loi-taskbar-tren-windows-10 (3)

+ Bước 2: Bạn hãy copy lại lệnh bên dưới và paste vào cửa sổ dòng lệnh => và nhấn Enter để chạy lệnh.

Get-AppXPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register “$($_.InstallLocation)\AppXManifest.xml”}

cach-sua-loi-taskbar-tren-windows-10 (4)

+ Bước 3: Chạy lệnh hoàn tất, bạn có thể thử xem thanh Taskbar đã hoạt động trở lại chưa, hoặc có thể bạn sẽ phải khởi động lại máy tính để xem kết quả đấy.

cach-sua-loi-taskbar-tren-windows-10 (5)

#7. Tạo một tài khoản mới

Một cách khác nữa để xử lí lỗi trên là tạo một tài khoản Admin mới. Mọi chức năng và kể cả Taskbar sẽ hoạt động rất tốt ở tài khoản mới này.

Chỉ có điều là hơi phiền phức là bạn phải chuyển dữ liệu hoặc phần mềm của bạn ra tài khoản mới. Sau đó bạn chỉ việc xóa tài khoản cũ mà thôi.

cach-sua-loi-taskbar-tren-windows-10 (13)

Về cách làm thì bạn có thể tham khảo trong bài viết này nhé: Hướng dẫn tạo User mới trên Windows XP/ 7/ 8/ 10 nhanh nhất

#8. Gỡ bản update hoặc cập nhật Windows lên phiên bản mới nhất

Nếu như trước đó máy tính bạn vẫn hoạt động trơn tru, chỉ sau khi thực hiện nâng cấp một số thành phần nào đó trên Windows mới bị hiện tượng như vậy thì bạn biết cần phải làm gì rồi đấy.

Hãy gỡ bỏ hoặc hoàn nguyên những thiết lập mà bạn đã thay đổi trước đó.

Thực hiện: Bạn nhấn tổ hợp phím Windows + I để truy cập vào Windows Settings => sau đó chọn Update & Security => chọn View update history như hình bên dưới.

sua-loi-thanh-taskbar-win-10

Sau đó thực hiện gỡ bản cài đặt bằng cách nhấn vào Uninstall update nhé.

sua-loi-thanh-taskbar-win-10-1

Còn ngược lại, nếu như máy tính của bạn đang dùng mà tự nhiên bị lỗi thì bạn cũng nên cân nhắc việc nâng cấp Windows lên phiên bản mới nhất nhé.

Cá nhân mình thì mình thường xuyên cập nhật lên phiên bản mới sau 2 tuần ra mắt. Chả tội gì mà không dùng bản cập nhật cả 🙂

#9. Reset lại Windows 10

Nếu tất cả các cách khác đều thất bại, lỗi thanh Taskbar vẫn còn đó thì bạn sẽ phải reset lại Windows hoặc cài đặt lại Windows thôi.

Về cơ bản thì sau khi Reset thì Windows sẽ trở lại như mới. Nhưng tất nhiên, trước khi làm việc này thì bạn hãy copy tất cả dữ liệu trên ổ hệ điều hành – thường là ổ C (bao gồm Desktop, thư mục Download, Music, Video…) sang phân vùng ổ D, E.. nhé.

cach-sua-loi-taskbar-tren-windows-10 (14)

#10. Lời kết

OK, như vậy là mình đã hướng dẫn xong cho các bạn cách để sửa lỗi Taskbar trên hệ điều hành Windows 10 rồi nhé.

Bài hướng dẫn này mình thực hiện trên Windows 10 nhưng bạn hoàn toàn có thể áp dụng được với các hệ điều hành khác như Windows 7, Windows 8 và kể cả là Windows 11 mới nhất.

Chúc các bạn thành công, và đừng quên comment lại cách fix lỗi mà bạn đã áp dụng thành công nhé. Cho mọi người chút niềm tin đi nào các bạn >.<

CTV: Hoàng Tuấn – Bài viết gốc tại blogchiasekienthuc.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev