Cách dùng Statement, PrepareStatement và CallableStatement trong Java

Leave a Comment

JDBC Statement trong java: Statement, PrepareStatement và CallableStatement


So sánh Statement với PreparedStatement và CallableStatement trong JDBC Java

Nếu bạn chưa biết JDBC là gì tham thảo bài viết này trước nhé!
JDBC Statement trong java dùng để làm gì?
jdbc
Khi một kết nối được thiết lập, chúng ta có thể tương tác với cơ sở dữ liệu. JDBC Statement, PreparedStatement và CallableStatement định nghĩa những phương thức và thuộc tính, cho phép chúng ta thực thi câu lệnh SQL và nhận dữ liệu từ cơ sở dữ liệu của bạn, trong đó:


  • Statement  –  Sử dụng để thực hiện các câu truy vấn SQL tĩnh, không có tham số.

  • PreparedStatement – Sử dụng để thực hiện các  câu truy vấn SQL động hoặc có tham số.

  • CallableStatement – Sử dụng để thực thi các stored procedures.

Statement


Statement được sử dụng để thực thi các câu lệnh SQL tĩnh, chúng ta không thể truyền tham số vào câu SQL trong thời gian runtime.

Statement có hiệu năng (performance) kém hơn  PrepareStatement và CallableStatement .

Statement thường được sử dụng trong trường hợp câu lệnh SQL chỉ chạy 1 lần, ví dụ sử dụng để thực thi các câu SQL định nghĩa cơ sở dữ liệu – DDL (Data Denifition Language) như CREATE, ALTER, DROP…

Ví dụ Statement:


String sql = "CREATE TABLE user_info (" +
" id int(11) NOT NULL AUTO_INCREMENT," +
" name varchar(45) DEFAULT NULL," +
" email varchar(100) DEFAULT NULL," +
" address varchar(255) DEFAULT NULL," +
" date_of_birth datetime DEFAULT NULL," +
" PRIMARY KEY (id)" +
")";
Connection con = connectionUtils.getConnection();
Statement stmt = con.createStatement();
stmt.execute(sql);

Lưu ý:


  • boolean execute (String SQL): Trả về giá trị true nếu thực thi thành công câu lệnh SQL; ngược lại sẽ trả về giá trị false. Sử dụng phương thức này để thực thi các câu lệnh SQL DDL như tạo cơ sở dữ liệu, tạo bảng, …

  • int executeUpdate (String SQL): Trả về số dòng bị tác động khi thực thi các câu lệnh như INSERT, UPDATE hoặc DELETE.

  • ResultSet executeQuery (String SQL): Trả về một đối tượng ResultSet khi bạn thực thi câu lệnh SELECT.

PreparedStatement


PreparedStatement được sử dụng để thực thi các câu truy vấn SQL động hoặc có tham số.

PreparedStatement thừa kế từ Statement nhưng nó cho phép truyền các tham số vào câu SQL trong thời gian run time.

PreparedStatement được khuyên sử dụng trong trường hợp câu SQL được sử dụng nhiều lần.

Ví dụ câu lệnh INSERT được dùng lại nhiều lần để insert 1 danh sách user vào database.


List<User> listUser = new ArrayList<User>();
listUser.add(new User(1, "Messi", "Argentina"));
listUser.add(new User(2, "Ronaldo", "Brazil"));
listUser.add(new User(3, "Rooney", "England"));
String sql = "INSERT INTO user_info (id, name, address) VALUES (?, ?, ?);";
PreparedStatement pstmt = con.prepareStatement(sql);
for (User user : listUser)
pstmt.setInt(1, user.getId());
pstmt.setString(2, user.getName());
pstmt.setString(3, user.getAddress());
pstmt.execute();






CallableStatement


CallableStatement được sử dụng để thực thi stored procedures.

CallableStatement được thừa kế từ PreparedStatement và có hiệu năng cao hơn PreparedStatement.

Với CallableStatement, chúng ta có thể truyền 3 loại tham số vào stored procedures là IN (truyền giá trị vào stored procedures), OUT (lấy kết quả trả về từ stored procedures), IN OUT (thực thi cả IN và OUT).






Ví dụ mình tạo một stored procedures thực hiện lấy user theo id:


CREATE PROCEDURE getUserById(IN idUser int)
BEGIN
SELECT * FROM user_info WHERE id = idUser;
END

Bây giờ mình sẽ sử dụng CallableStatement để gọi câu stored procedures bên trên:

Truyền id = 1 vào stored procedures getUserById và trả kết quả về ResultSet


String sql = "CALL getUserById(?);";
CallableStatement cs = con.prepareCall(sql);
cs.setInt(1, 1);
cs.executeQuery();
ResultSet rs = cs.getResultSet();
while (rs.next())
System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getString(3));

Xong. Trên đây là Cách dùng Statement, PrepareStatement và CallableStatement trong JDBC Java có ví dụ đơn giản nhất!



Học hành, Lập trình
Java, Lập trình
Xem Tiếp

JDBC là gì ? Tìm hiểu về JDBC trong Java

Leave a Comment

JDBC là gì ? Tìm hiểu về JDBC trong Java và Cách kết nối java với mysql bằng JDBC


JDBC là gì?


jdbc
JDBC (Java Database Connectivity) là một API tiêu chuẩn dùng để kết nối các chương trình viết bởi Java với các loại cơ sở dữ liệu quan hệ (MySQL, MS SQL, Postgre SQL, Oracle, DB2…).

JDBC chỉ là một tập các interface, các định nghĩa, thông báo lỗi, đặc tả chứ không phải là thư viện. Với mỗi hệ quản trị cơ sở dữ liệu ta sẽ có một cài đặt JDBC riêng cho nó, ví dụ JDBC cho MySQL, JDBC cho MS SQL …


Các thành phần của JDBC


DriverManager: Dùng để quản lý danh sách các Driver (database drivers).
Driver: Dùng để liên kết các kết nối tới cơ sở dữ liệu, dùng để liên kết các liên lạc với cơ sở dữ liệu, điều khiển các liên lạc với database.
Connection: Biểu thị kết nối tới cơ sở dữ liệu. Dùng để tạo ra Statement, PreparedStatement và CallableStatement.
Statement, PreparedStatement, CallableStatement: Chứa lệnh SQL gửi tới cơ sở dữ liệu để thực thi.
ResultSet – biểu diễn một tập kết quả trong cơ sở dữ liệu tạo ra bởi việc sử dụng một câu lệnh SQL là SELECT.
SQLException – một lớp xử lý lỗi ngoại lệ chứa các lỗi truy cập cơ sở dữ liệu.


Java kết nối với database dựa trên nguyên tắc nào?


Java sử dụng JDBC để làm việc với các cơ sở dữ liệu.

jdbc


Ví dụ bạn làm việc với cơ sở dữ liệu Oracle từ Java bạn cần phải có Driver (Đó là class điều khiển việc kết nối với loại cơ sở dữ liệu bạn muốn). Trong JDBC API chúng ta có java.sql.Driver, nó chỉ là một interface, và nó có sẵn trong JDK. Như vậy bạn phải download thư viện Driver ứng với loại Database mà bạn mong muốn.
  • Chẳng hạn với Oracle thì class thi hành Interface java.sql.Driver đó là: oracle.jdbc.driver.OracleDriver

java.sql.DriverManager là một class trong JDBC API. Nó làm nhiệm vụ quản lý các Driver.


Code ví dụ Kết nối java với mysql bằng JDBC


Mình sẽ lấy ví dụ ở stackjava. Tạo cơ sở dữ liệu demo-jdbc và table user_info như hình dưới
jdbc-1
Bây giờ mình sẽ viết 1 chương trình Java kết nối tới database demo-jdbc và hiển thị các thông tin của table user_info

Để kết nối với MySQL bằng Java chúng ta cần download jdbc tương ứng cho MySQL

Các bạn có thể download thư viện jdbc cho MySQL tại đây mysql-connector-java-6.0.6.jar

Hoặc sử dụng maven:


<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>


Ở đây mình sử dụng thư viện mysql-connector-java-6.0.6.jar và copy nó vào project

jdbc-2 jdbc-3
jdbc-4
File Demo.java


package stackjava.com.demomysqljdbc.demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo
public static void main(String[] args) throws ClassNotFoundException, SQLException
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/demo-jdbc", "root", "admin1234");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM user_info");
ResultSetMetaData rsmd = rs.getMetaData();
System.out.println("Total columns: " + rsmd.getColumnCount());
for (int i = 1; i <= rsmd.getColumnCount(); i++)
System.out.println(
"Column " + i + " [name: " + rsmd.getColumnName(i) + " - type: " + rsmd.getColumnTypeName(i) + "]");

System.out.println("--------------------");
while (rs.next())
System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getString(3));
con.close();


Giải thích chút nhé:


  • Class.forName dùng để chỉ dẫn cho Java biết sẽ kết nối tới loại database nào. Class.forName(“com.mysql.jdbc.Driver”) dùng để kết nối tới database MySQL

  • DriverManager.getConnection(“jdbc:mysql://localhost:3306/demo-jdbc”, “root”, “admin1234”): tạo một connection tới database có url =jdbc:mysql://localhost:3306/demo-jdbc với username = “root” và password  = “admin1234”

  • ResultSetMetaData sẽ đặt meta data cho ResultSet, ở đây ResultSet lấy từ câu SQL “SELECT * FROM user_info” nên nó sẽ gồm tất cả các column trong table user_info. Nếu bạn chuyển câu SQL thành “SELECT id, name FROM user_info” thì ResultSetMetaData sẽ chỉ có 2 column id, name này thôi.

Kết quả:
jdbc-5
Một số lưu ý:


  • Từ bản mysql-connector-java-6.0.6.jar bắt đầu chuyển class com.mysql.jdbc.Driver  sang com.mysql.cj.jdbc.Driver, nếu bạn vẫn dùng class cũ thì nó sẽ thông báo warning chứ không ảnh hưởng gì.

Nên xem: CÁCH DÙNG STATEMENT, PREPARESTATEMENT VÀ CALLABLESTATEMENT TRONG JAVA


Download code ví dụ Kết nối java với mysql bằng JDBC tại đây



Học hành, Lập trình
Java, Lập trình
Xem Tiếp

Hướng dẫn phân trang trong Thymeleaf và Spring Boot

Leave a Comment


Pagination in Spring Boot and Thymeleaf


pagingspringboot (1)


Hướng dẫn phân trang trong Thymeleaf và Spring Boot


Tiếp tục bài viết Lập trình Spring Boot CRUD đơn giản MyEmployee nếu bạn chưa xem bài đó vui lòng xem nó trước khi tiếp tục bài này nhé. Mình sẽ hướng dẫn các bạn cách phân trang trong Thymeleaf và Spring Boot dùng PlacedListHolder.

PlacedListHolder giúp chúng ta phân trang theo danh sách List<Object>. Để hiểu rõ về PlacedListHolder hơn chúng ta sẽ tìm hiểu tiếp phía dưới.
Lưu ý: Bài này tiếp tục bài viết Lập trình Spring Boot CRUD đơn giản MyEmployee nếu bạn chưa xem bài đó vui lòng xem nó và tải source code về làm tiếp bài này nhé!

Không dài dòng nữa tiến hành vào phần chính hướng dẫn phân trang cho project Spring Framework dùng PagedListHolder.

Cấu trúc các file sẽ chỉnh sửa trong project Employee:


pagingspringboot (2)


1. Yêu cầu: Phân trang cho bảng danh sách Employee này.


pagingspringboot (1)


2. Thêm phương thức phân trang vào class EmployeeController:


Để thuận tiện sau này chúng ta thêm getMapping(“/”) cho trang chủ:


@GetMapping("/")
public String home()
return "redirect:/employee";

Dưới đây là trang danh sách Employee


@GetMapping("/employee")
public String index(Model model,HttpServletRequest request
,RedirectAttributes redirect)
request.getSession().setAttribute("employeelist", null);
if(model.asMap().get("success") != null)
redirect.addFlashAttribute("success",model.asMap().get("success").toString());
return "redirect:/employee/page/1";

Chúng ta cần HttpServletRequest để tạo session employeelist. Đồng thời khởi tạo session này là null.

Dòng 6,7 mình sẽ giải thích cuối bài. Hiện tại bạn có thể bỏ qua nó.


3. Phương thức phân trang showEmployeePage:


Thêm phương thức showEmployeePage vào EmployeeController


@GetMapping("/employee/page/pageNumber")
public String showEmployeePage(HttpServletRequest request,
@PathVariable int pageNumber, Model model)
PagedListHolder<?> pages = (PagedListHolder<?>) request.getSession().getAttribute("employeelist");
int pagesize = 3;
List<Employee> list =(List<Employee>) employeeService.findAll();
System.out.println(list.size());
if (pages == null)
pages = new PagedListHolder<>(list);
pages.setPageSize(pagesize);
else
final int goToPage = pageNumber - 1;
if (goToPage <= pages.getPageCount() && goToPage >= 0)
pages.setPage(goToPage);


request.getSession().setAttribute("employeelist", pages);
int current = pages.getPage() + 1;
int begin = Math.max(1, current - list.size());
int end = Math.min(begin + 5, pages.getPageCount());
int totalPageCount = pages.getPageCount();
String baseUrl = "/employee/page/";
model.addAttribute("beginIndex", begin);
model.addAttribute("endIndex", end);
model.addAttribute("currentIndex", current);
model.addAttribute("totalPageCount", totalPageCount);
model.addAttribute("baseUrl", baseUrl);
model.addAttribute("employees", pages);
return "list";

và tương tự cho hàm search


@GetMapping("/employee/search/pageNumber")
public String search(@RequestParam("s") String s, Model model, HttpServletRequest request,
@PathVariable int pageNumber)
if (s.equals(""))
return "redirect:/employee";

List<Employee> list = employeeService.search(s);
if (list == null)
return "redirect:/employee";

PagedListHolder<?> pages = (PagedListHolder<?>) request.getSession().getAttribute("employeelist");
int pagesize = 3;
pages = new PagedListHolder<>(list);
pages.setPageSize(pagesize);
final int goToPage = pageNumber - 1;
if (goToPage <= pages.getPageCount() && goToPage >= 0)
pages.setPage(goToPage);

request.getSession().setAttribute("employeelist", pages);
int current = pages.getPage() + 1;
int begin = Math.max(1, current - list.size());
int end = Math.min(begin + 5, pages.getPageCount());
int totalPageCount = pages.getPageCount();
String baseUrl = "/employee/page/";
model.addAttribute("beginIndex", begin);
model.addAttribute("endIndex", end);
model.addAttribute("currentIndex", current);
model.addAttribute("totalPageCount", totalPageCount);
model.addAttribute("baseUrl", baseUrl);
model.addAttribute("employees", pages);
return "list";

Quá trình xử lý của hàm Controller như sau:

Khi chúng ta truy cập vào trang chủ /employee sẽ khởi tạo mới session Employee List là null. Đồng thời nó sẽ chuyển hướng tới trang đầu tiên của danh sách Employee chẳng hạn như: /employee/page/1. Chúng ta sẽ refresh session Employee List nếu chưa khởi tạo, bằng không nó sẽ trả về Page mà người dùng đã truy cập trước đó.

Sau đó sẽ ép session đó sang đối tượng PagedListHolder.(dòng 4)

Nếu đối tượng PagedListHolder là null thì khởi tạo và thiết lập Page Size. Tức là 1 trang bạn muốn hiện bao nhiêu object.(dòng 8)

Thiết lập trang mà chúng ta muốn hiện lên View dựa trên /employee/page/pageNumber (dòng 17)

Thiết lập các thông số cho Pagination, sau đó dùng Model Attributes để đưa sang View Thymeleaf.(Dòng 18 – 31)
Nếu bạn thấy vẫn khó hiểu, không sao mình sẽ hướng dẫn từng bước trong video phía dưới.


4. Phân trang Thymeleaf file list.html


Nội dung file list.html sau khi thêm phân trang như sau:


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="layout :: head"></head>
<body>
<nav th:replace="layout :: header"></nav>
<div class="container main-content list">
<div th:if="$success"
class="row alert alert-success alert-dismissible">
<button type="button" class="close" data-dismiss="alert"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<span th:text="$success"></span>
</div>
<div class="row">
<a th:href="@/employee/create" class="btn btn-success pull-left">
<span class="glyphicon glyphicon-plus"></span> Add new employee
</a>
<form class="form-inline pull-right" action="#"
th:action="@/employee/search/1" method="GET">
<div class="form-group">
<input type="text" class="form-control" name="s"
placeholder="Type employee name..." />
</div>
<button type="submit" class="btn btn-primary">Search</button>
</form>
</div>
<th:block th:if="$#lists.isEmpty(employees.pageList)">
<h3>No employee</h3>
</th:block>
<th:block th:unless="$#lists.isEmpty(employees.pageList)">
<nav class="row justify-content-center wow fadeIn"
data-wow-delay="0.2s">
<div class="row">
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>No</th>
<th>Name</th>
<th>Phone</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<tr th:each="contact,iterStat : $employees.pageList">
<td th:text="$iterStat.count"></td>
<td th:text="$contact.name"></td>
<td th:text="$contact.phone"></td>
<td><a th:href="@/employee/id/edit(id=$contact.id)"><span
class="glyphicon glyphicon-pencil"></span></a></td>
<td><a th:href="@/employee/id/delete(id=$contact.id)"><span
class="glyphicon glyphicon-trash"></span></a></td>
</tr>
</tbody>
</table>
</div>
<ul class="pagination">
<li
th:class="$currentIndex == 1? 'page-item disabled' : 'page-item'">
<a class="page-link" th:href="@/employee">First</a>
</li>
<li
th:class="$currentIndex == 1? 'page-item disabled': 'page-item' ">
<a class="page-link" aria-label="Previous"
th:href="@"
title='Go to previous page'><span aria-hidden="true">«</span>
<span class="sr-only">Previous</span></a>
</li>
<li th:each="item : $#numbers.sequence(beginIndex,endIndex)"
th:class="$item == currentIndex ? 'page-item active' :'page-item' ">
<a class="page-link" th:href="@"> <span
th:text='$item'>1</span>
</a>
</li>
<li
th:class="$currentIndex == totalPageCount? 'page-item disabled': 'page-item'">
<a class="page-link" aria-label="Next"
th:href="@$baseUrl$currentIndex + 1" title='Go to next page'><span
aria-hidden="true">»</span> <span class="sr-only">Next</span></a>
</li>
<li
th:class="$currentIndex == totalPageCount? 'page-item disabled':'page-item'">
<a class="page-link" th:href="@">Last</a>
</li>
</ul>
</nav>
</th:block>
</div>
<!-- /.container -->
<footer th:replace="layout :: footer"></footer>
</body>
</html>

Dòng 29. Chúng ta dùng employees.pageList thay vì employess do đối tượng PagedListHolder.

Dòng 60-88. Phần phân trang thymeleaf. Lưu ý th:href=“@/employee“  (dòng 63)

Cú pháp nối chuỗi trong thymeleaf:
@
Chỉnh sửa phần thông báo addFlashAttribute:


@GetMapping("/employee")
public String index(Model model,HttpServletRequest request
,RedirectAttributes redirect)
request.getSession().setAttribute("employeelist", null);
if(model.asMap().get("success") != null)
redirect.addFlashAttribute("success",model.asMap().get("success").toString());
return "redirect:/employee/page/1";

Như bài trước, khi phương thức save hay delete gọi addFlashAttribute thì nó sẽ thông báo ra cho trang redirect (/employee) về là hãy truyền thông điệp gì đó. Nhưng bây ở đây phương thức /employee chỉ là trung gian nên mình phải chuyển thêm 1 lần addFlashAttribute qua trang /employee/page/pageNumber

Đoạn code model.asMap().get("success")để lấy giá trị của đối tượng FlashAttribute.


5. Video Hướng dẫn phân trang trong Thymeleaf và Spring Boot: (video chưa update code mới nhé, nên chỉ hoạt động trên mysql 5.6)




6. Download source code updated 2019




Hibernate Framework, Học hành, Lập trình, Spring Framework
Java, Lập trình
Xem Tiếp

Cài đặt WinRar trên Linux (Ubuntu, Mint) với Terminal đơn giản

Leave a Comment


Install WinRAR In Ubuntu (Linux) with Terminal In One Step


Cài đặt WinRar trên Linux (Ubuntu, Mint) với Terminal đơn giản


WinRAR chắc chắn là một trong những công cụ nén nổi tiếng nhất. Nhiều trang web tải tệp lên máy chủ của họ bằng cách nén chúng trong tệp RAR để tiết kiệm băng thông và không gian. WinRAR là một công cụ được tạo ra để tạo và giải nén các tệp RAR.

Bạn có thể cài đặt WinRAR trên Ubuntu hay Mint (Linux) với chỉ một câu lệnh. Cách sử dụng của nó trong Ubuntu rất giống với Windows. Bạn có thể dễ dàng nén và giải nén các tệp và thư mục trong Ubuntu bằng WinRAR.

Mở Terminal và nhập lệnh dưới để cài đặt WinRar cho Linux:


sudo aptitude update && sudo aptitude install rar unrar


Cách dùng WinRar trên Ubuntu (Linux):


Sau khi cài đặt hãy nhấp chuột phải vào file rar và chọn Extra Here để giải nén file đó.
rar

Để nén thư mục hay 1 file, đơn là bạn nhấn chuột phải vào thư mục đó hay file đó và chọn Create Archive hay Compress. Sau đó hãy thiết lập các chức năng mà bạn muốn. Cuối cùng nhấn Create để tạo file nén.
rar2


Install WinRAR In Ubuntu (Linux) Via Terminal In One Step



Linux, Nén
Thủ thuật
Xem Tiếp

Hướng dẫn quay màn hình có âm thanh với VLC trên Linux

Leave a Comment

https://shareeverythings.com/wp-content/uploads/2019/12/27279759538_ae15d1ae7c_n.jpg

VLC screen recording with audio in Linux


Hướng dẫn quay màn hình có âm thanh với VLC trên Linux


Bạn bị lỗi quay màn hình với VLC trên linux? Bạn quay màn hình được nhưng không có âm thanh, Làm thế nào để giải quyết?

Trước khi giải quyết vấn đề, chúng ta sẽ tìm hiểu về VLC cho bạn nào chưa biết!

Hướng dẫn quay màn hình có âm thanh với VLC media player. VLC media player (thường gọi tắt là VLC) là một media player và streaming media server mã nguồn mở di động cao và đa nền tảng được viết bởi VideoLAN project. Chi tiết thêm ở đây.
VLC không chỉ là phần mềm chơi nhạc, phim mà nó còn có thể:


  • Chuyển định dạng file

  • Phát nội dung số qua mạng nội bộ (stream) hoặc qua Internet

  • Ghi lại video quay màn hình máy tính

  • Điều chỉnh quá trình phát nội dung từ xa thông qua trình duyệt

  • Xem video YouTube

  • Xem Podcast

  • Nghe radio trên Internet

  • Chơi video dưới dạng ký tự ASCII …

Cài đặt VLC media player trên linux(ubuntu, linux mint):


Mở Terminate và nhập:


sudo apt update

sudo apt install vlc


Hướng dẫn quay màn hình có âm thanh với VLC trên Linux


Để tránh lỗi quay màn hình được nhưng không có âm thanh. Các bạn làm theo từng bước như các hình ảnh dưới đây (VLC trên Linux Mint):

Kiểm tra thiết lập âm thanh của hệ thống hoạt động bình thường.
vlcsnap-2018-04-01-14h56m51s715_qlamxmaster

VLC screen recording with audio in Linuxvlcsnap-2018-04-01-14h56m22s644_qlamxmaster
vlcsnap-2018-04-01-14h56m31s992_qlamxmaster

Bắt đầu chạy VLC media player.
vlcsnap-2018-04-01-14h57m09s550_qlamxmastervlcsnap-2018-04-01-14h57m20s451_qlamxmaster

Thay đổi Frame rate (FPS) nên chỉnh từ 15 đến 30 FPS
vlcsnap-2018-04-01-14h57m47s200_qlamxmaster

Mở rộng Show More Options. Nếu bạn bỏ qua bước này thì sẽ bị lỗi không ghi được âm thanh khi quay màn hình với VLC.
vlcsnap-2018-04-01-14h58m00s313_qlamxmaster
vlcsnap-2018-04-01-14h58m13s300_qlamxmaster

Tại Extra media Nhập alsa://vlcsnap-2018-04-01-14h58m24s897_qlamxmastervlcsnap-2018-04-01-14h58m32s434_qlamxmaster

Bạn có thể thiết lập Project để thay đổi định dạng video xuất ra.vlcsnap-2018-04-01-14h59m05s528_qlamxmastervlcsnap-2018-04-01-14h59m16s294_qlamxmaster

Xong rồi! Nhấn nút Start để bắt đầu quay màn hình với VLC. Khi bạn muốn dừng quay thì nhấn nút Stop trên thanh playback của VLC nhé!vlcsnap-2018-04-01-14h59m24s386_qlamxmaster

Mình đã Hướng dẫn quay màn hình có âm thanh với VLC trên Linux. Trong quá trình thực hiện bạn gặp khó khăn gì thì hãy bình luận bên dưới nhé!



Linux, Phần mềm, Quay phim màn hình
Thủ thuật
Xem Tiếp

Hướng dẫn tích hợp Ckfinder vào Ckeditor trong Spring Boot Java

Leave a Comment


Cách tích hợp Ckfinder vào Ckeditor trong project Spring Boot Java


Trong bài viết này mình sẽ hướng dẫn tích hợp Ckfinder và Ckeditor trong project Spring Boot Java. Mình sẽ dùng Ckfinder 2 do Ckfinder 3 chỉ hỗ trợ cho PHP và ASP.NET mà không hỗ trợ cho Java.
CkfinderJava (1)

Đối với với những web developer việc ứng dụng các WYSIWYG editor vào việc quản trị nội dung cho website dường như là điều bắt buộc. Người dùng có thể dễ dàng cập nhật và định dạng nội dung theo ý muốn một cách dễ dàng như dùng MS Word.
Hiện tại có rất nhiều WYSIWYG editor được các nhà phát triển website sử dụng xem tại đây. Top 10 Jquery HTML5 WYSIWYG Plugins Editor


Giới thiệu Ckeditor


CKEditor (còn gọi là FCKeditor) là một trình soạn thảo mã nguồn mở theo kiểu WYSIWYG (tay làm – mắt thấy) của CKSource.
CkfinderJava (7)

Cũng giống các trình soạn thảo dành cho web khác, CKEditor sử dụng JavaScript là nền tảng, riêng việc tương tác với server thì CKEditor sử dụng các ngôn ngữ phổ biến sau: ASP, ASP.NET, ColdFusion, Java, JavaScript, Perl, PHP và Python.

CKEditor tương thích với hầu hết các trình duyệt Internet, gồm có: Internet Explorer 6.0+ (Windows), Firefox 2.0+, Safari3.0+, Google Chrome (Windows), Opera 9.50+…


Giới thiệu Ckfinder


CKfinder là 1 trình quản lý file, nó cho phép chúng ta quản lý file, folder trên server bao gồm phân quyền sử dụng, upload file từ client. Hiện tại nếu bạn chỉ sử dụng CKEditor thì chức năng upload ảnh từ client và chèn vào bài viết không sử dụng được

.CkfinderJava (11)


Hướng dẫn tích hợp Ckfinder vào Ckeditor trong Spring Boot Java


Vào phần chính nào, hầu hết đa số trên mạng có rất nhiều hướng dẫn tích hợp Ckfinder vào Ckeditor trên PHP, ASP.NET. Thậm chí là Java nhưng hầu như chỉ hướng dẫn tích hợp Ckfinder cho Java web JSP hay Spring Framework với web.xml. Ngay cả document của trang chủ Ckfinder cũng chỉ hướng dẫn theo dạng web.xml. Vì thế mình quyết định viết bài Hướng dẫn tích hợp Ckfinder vào Ckeditor trong Spring Boot Java.
Các công nghệ sử dụng:


  • Spring Boot + Thymeleaf

Công cụ yêu cầu:


  • Ckfinder 2

  • Ckeditor 3

  • Eclipse + Plugin spring suite tool

Quá trình làm gồm các bước cụ thể dưới đây! Để chi tiết bạn nên xem video cuối bài !


Tải thư viện Ckfinder và Ckeditor cần thiết


Download Ckfinder java
Download Ckeditor
CkfinderJava (10)Cấu trúc thư mục


Tạo Spring Boot project


Eclipse bạn đã cài đặt Plugin spring suite tool. File > New > Spring Starter Project.
CkfinderJava (5)

Next, sau đó chọn Thymeleaf và Web. Sau đó chọn Finish.


Tích hợp thư viện vào Spring Boot project (pom, static, lib)


Sau khi tải 2 thư viện phía trên về, bạn hãy giải nén ra. Copy 2 folder cần thiết vào thư mục static trong project spring boot:


  • ckeditor trong ckeditor_4.8.0_basic

  • ckfinder trong ckfinder_java_2.6.2.1\ckfinder\_source\CKFinder for Java\WebApp\src\main\webapp

Copy file file config.xml trong ckfinder_java_2.6.2.1\ckfinder\_source\CKFinder for Java\WebApp\src\main\webapp\WEB-INF và thư mục static.

Đồng thời bạn tạo thư mục uploadmedia trong thư mục static.

Sau đó bạn import CKFinderJava-2.6.2.1.war vào eclipse và lấy 1 số thư viện jar sau:
CkfinderJava (6)

Sau đó bỏ vào thư mục lib nằm ở ngoài project.

Sau đó copy lib vào spring boot project.

File pom.xml


<?xml version="1.0" encoding="UTF-8"?>
<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.qlam</groupId>
<artifactId>ckspringbootqlam</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ckspringbootqlam</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--CKFinder start -->
<dependency>
<groupId>com.ckeditor</groupId>
<artifactId>ckeditor-java-core</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>com.finder</groupId>
<artifactId>fileeditor</artifactId>
<version>2.6.2.1</version>
<scope>system</scope>
<systemPath>$basedir/lib/CKFinderPlugin-FileEditor-2.6.2.1.jar</systemPath>
</dependency>
<dependency>
<groupId>com.finder</groupId>
<artifactId>imgresize</artifactId>
<version>2.6.2.1</version>
<scope>system</scope>
<systemPath>$basedir/lib/CKFinderPlugin-ImageResize-2.6.2.1.jar</systemPath>
</dependency>
<dependency>
<groupId>com.finder</groupId>
<artifactId>watermark</artifactId>
<version>2.6.2.1</version>
<scope>system</scope>
<systemPath>$basedir/lib/CKFinderPlugin-Watermark-2.6.2.1.jar</systemPath>
</dependency>
<dependency>
<groupId>com.finder</groupId>
<artifactId>ckfinder</artifactId>
<version>2.6.2.1</version>
<scope>system</scope>
<systemPath>$basedir/lib/CKFinder-2.6.2.1.jar</systemPath>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
<scope>system</scope>
<systemPath>$basedir/lib/thumbnailator-0.4.8.jar</systemPath>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<!--CKFinder end -->
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

Tạo class Cấu hình project


Tạo package com.qlam.demo.config

Trong này sẽ có 3 file dùng để cấu hình như sau:

File CKFinderConfig.java dùng để đọc file ckfinder.xml


package com.qlam.demo.config;
import com.ckfinder.connector.configuration.Configuration;
import com.ckfinder.connector.configuration.Events;
import com.ckfinder.connector.utils.PathUtils;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.servlet.ServletConfig;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Scanner;
public class CKFinderConfig extends Configuration
public CKFinderConfig(ServletConfig servletConfig)
super(servletConfig);

@Override
public void init() throws Exception
DefaultResourceLoader loader = new DefaultResourceLoader();
Resource resource = loader.getResource(this.xmlFilePath);
Class<?> clazz = getClass().getSuperclass();
Field field = clazz.getDeclaredField("lastCfgModificationDate");
Method method = clazz.getDeclaredMethod("clearConfiguration");
method.setAccessible(true);
method.invoke(this);
field.setAccessible(true);
field.set(this, System.currentTimeMillis());
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(resource.getInputStream());
doc.normalize();
Node node = doc.getFirstChild();
if (node != null)
NodeList nodeList = node.getChildNodes();
//Duyet qua .xml
for (int i = 0; i < nodeList.getLength(); ++i)
Node childNode = nodeList.item(i);
if (childNode.getNodeName().equals("enabled"))
this.enabled = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue();
if (childNode.getNodeName().equals("baseDir"))
if (servletConf.getInitParameter("baseDir") == null) //baseDir cua application.prop la null
this.baseDir = childNode.getTextContent().trim(); //lay the ben ckfinder.xml, khi do phai thiet lap ben ckfinder.xml
else //nguoc lai lay ben application.prop
this.baseDir = servletConf.getInitParameter("baseDir");

this.baseDir = PathUtils.escape(this.baseDir);
this.baseDir = PathUtils.addSlashToEnd(this.baseDir);

if (childNode.getNodeName().equals("baseURL"))
if (servletConf.getInitParameter("baseURL") == null)
this.baseURL = childNode.getTextContent().trim();
else
this.baseURL=servletConf.getInitParameter("baseURL")+"/public/image/";

this.baseURL = PathUtils.escape(this.baseURL);
this.baseURL = PathUtils.addSlashToEnd(this.baseURL);

if (childNode.getNodeName().equals("licenseName"))
this.licenseName = childNode.getTextContent().trim();
if (childNode.getNodeName().equals("licenseKey"))
this.licenseKey = childNode.getTextContent().trim();
String value;
if (childNode.getNodeName().equals("imgWidth"))
value = childNode.getTextContent().trim();
value = value.replaceAll("//D", "");
try
this.imgWidth = Integer.valueOf(value);
catch (NumberFormatException var13)
this.imgWidth = null;


if (childNode.getNodeName().equals("imgQuality"))
value = childNode.getTextContent().trim();
value = value.replaceAll("//D", "");
method = clazz.getDeclaredMethod("adjustQuality", new Class[]String.class);
method.setAccessible(true);
this.imgQuality = Float.parseFloat(method.invoke(this, value).toString());

if (childNode.getNodeName().equals("imgHeight"))
value = childNode.getTextContent().trim();
value = value.replaceAll("//D", "");
try
this.imgHeight = Integer.valueOf(value);
catch (NumberFormatException var12)
this.imgHeight = null;


if (childNode.getNodeName().equals("thumbs"))
method = clazz.getDeclaredMethod("setThumbs", new Class[]NodeList.class);
method.setAccessible(true);
method.invoke(this, childNode.getChildNodes());

if (childNode.getNodeName().equals("accessControls"))
method = clazz.getDeclaredMethod("setACLs", new Class[]NodeList.class);
method.setAccessible(true);
method.invoke(this, childNode.getChildNodes());

if (childNode.getNodeName().equals("hideFolders"))
method = clazz.getDeclaredMethod("setHiddenFolders", new Class[]NodeList.class);
method.setAccessible(true);
method.invoke(this, childNode.getChildNodes());

if (childNode.getNodeName().equals("hideFiles"))
method = clazz.getDeclaredMethod("setHiddenFiles", new Class[]NodeList.class);
method.setAccessible(true);
method.invoke(this, childNode.getChildNodes());

if (childNode.getNodeName().equals("checkDoubleExtension"))
this.doubleExtensions = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue();
if (childNode.getNodeName().equals("disallowUnsafeCharacters"))
this.disallowUnsafeCharacters = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue();
if (childNode.getNodeName().equals("forceASCII"))
this.forceASCII = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue();
if (childNode.getNodeName().equals("checkSizeAfterScaling"))
this.checkSizeAfterScaling = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue();
Scanner sc;
if (childNode.getNodeName().equals("htmlExtensions"))
value = childNode.getTextContent();
sc = (new Scanner(value)).useDelimiter(",");
while (sc.hasNext())
String val = sc.next();
if (val != null && !val.equals(""))
this.htmlExtensions.add(val.trim().toLowerCase());


if (childNode.getNodeName().equals("secureImageUploads"))
this.secureImageUploads = Boolean.valueOf(childNode.getTextContent().trim()).booleanValue();
if (childNode.getNodeName().equals("uriEncoding"))
this.uriEncoding = childNode.getTextContent().trim();
if (childNode.getNodeName().equals("userRoleSessionVar"))
this.userRoleSessionVar = childNode.getTextContent().trim();
if (childNode.getNodeName().equals("defaultResourceTypes"))
value = childNode.getTextContent().trim();
sc = (new Scanner(value)).useDelimiter(",");
while (sc.hasNext())
this.defaultResourceTypes.add(sc.next());

if (childNode.getNodeName().equals("plugins"))
method = clazz.getDeclaredMethod("setPlugins", new Class[]Node.class);
method.setAccessible(true);
method.invoke(this, childNode);

if (childNode.getNodeName().equals("basePathBuilderImpl"))
method = clazz.getDeclaredMethod("setBasePathImpl", new Class[]String.class);
method.setAccessible(true);
method.invoke(this, childNode.getTextContent().trim());



method = clazz.getDeclaredMethod("setTypes", new Class[]Document.class);
method.setAccessible(true);
method.invoke(this, doc);
field = clazz.getDeclaredField("events");
field.setAccessible(true);
field.set(this, new Events());
this.registerEventHandlers();


File CKFinderServletConfig.java dùng để thiết lập thuộc tính trên file application.properties


package com.qlam.demo.config;
import com.ckfinder.connector.ConnectorServlet;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class CKFinderServletConfig
@Value("$ckeditor.storage.image.path")
private String baseDir;
@Value("$ckeditor.access.image.url")
private String baseURL;
@Bean
public ServletRegistrationBean connectCKFinder()
ServletRegistrationBean registrationBean=new ServletRegistrationBean(new ConnectorServlet(),"/ckfinder/core/connector/java/connector.java");
registrationBean.addInitParameter("XMLConfig","classpath:/static/ckfinder.xml");
registrationBean.addInitParameter("debug","false");
registrationBean.addInitParameter("configuration","com.qlam.demo.config.CKFinderConfig");
//ckfinder.xml
registrationBean.addInitParameter("baseDir",baseDir);
registrationBean.addInitParameter("baseURL",baseURL);
return registrationBean;


File WebMvcConfig.java dùng để thiết lập đường dẫn thư viện và file upload theo Spring MVC


package com.qlam.demo.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
// file:D:\\data\\file\\image\\
registry.addResourceHandler("/public/image/**").addResourceLocations("classpath:/static/uploadmedia/");
registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/");
registry.addResourceHandler("/ckfinder/**").addResourceLocations("classpath:/static/ckfinder/");
super.addResourceHandlers(registry);


File application.properties


# ===============================
# THYMELEAF
# ===============================
spring.thymeleaf.cache=false
# ===============================
# DATASOURCE
# ===============================
# Set here configurations for the database connection
# config dir so that ckeditor and ckfinder loading to media upload, write null so that use ckfinder.xml
ckeditor.storage.image.path=src/main/resources/static/uploadmedia/
ckeditor.access.image.url=http://localhost:8080

Xử lý với Controller class


Tạo package com.qlam.demo.controller

Chúng ta cần 1 class Controller để chạy trang chủ.

File QController.java đơn giản là mình cho nó dùng giao diện file adpost.html để hiện cho trang chủ.


package com.qlam.demo.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class QController
@GetMapping("/")
public String home()
return "adpost";


Thiết kế giao diện với thymeleaf engine


Mình tạo giao diện web đơn giản chia làm 2 phần:


  • Dùng Ckeditor tích hợp Ckfinder khi upload ảnh

  • Chạy Ckfinder khi nhấn một nút

Trong phần src/main/resources/templates tạo file adpost.html

File adpost.html


<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="head">
<meta charset="utf-8" />
<meta name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<title>Ckfinder</title>
</head>
<body>
<div id="page-content-wrapper">
<h1 id="home" class="text-center font-bold mt-1">Integrate
ckfinder into ckeditor in spring boot project</h1>
<h2>ShareEverythings.com</h2>
<!-- Section: Create Page -->
<section class="section mt-5 container-fluid">
<!-- First row -->
<div class="row">
<!-- First col -->
<div class="col-lg-6">
<h3>A. Integrate ckfinder into ckeditor</h3>
<!-- Second card -->
<div class="card mb-r">
<textarea name="content" id="content"></textarea>
</div>
<!-- /.Second card -->
</div>
<!-- /.First col -->
<div class="col-lg-6">
<h3>B. Ckfinder Button</h3>
<div class="avatar">
<img id="imgpreview"
src="https://yt3.ggpht.com/-f6NCDKG2Ukw/AAAAAAAAAAI/AAAAAAAAAAA/MqMm3rgmqCY/s48-c-k-no-mo-rj-c0xffffff/photo.jpg"
class="img-fluid" style="max-width: 300px; max-height: 300px;" />
</div>
<div class="file-field">
<p>
<strong id="xImagePath">Selected Image URL</strong><br /> <input
class="btn btn-primary btn-sm waves-effect waves-light"
type="button" value="Browse Image"
onclick="BrowseServer( 'Images:/', 'xImagePath' );" />
</p>
</div>
<p>Note: You should select square image !</p>
</div>
</div>
<!-- /.First row -->
</section>
<!-- /.Section: Create Page -->
</div>
<script src="ckeditor/ckeditor.js"></script>
<script src="ckfinder/ckfinder.js"></script>
<script>
CKEDITOR
.replace(
'content',

filebrowserBrowseUrl : 'ckfinder/ckfinder.html',
filebrowserImageBrowseUrl : 'ckfinder/ckfinder.html?type=Images',
filebrowserFlashBrowseUrl : 'ckfinder/ckfinder.html?type=Flash',
filebrowserUploadUrl : 'ckfinder/core/connector/java/connector.java?command=QuickUpload&type=Files',
filebrowserImageUploadUrl : 'ckfinder/core/connector/java/connector.java?command=QuickUpload&type=Images',
filebrowserFlashUploadUrl : 'ckfinder/core/connector/java/connector.java?command=QuickUpload&type=Flash'
);
/*Avatar start*/
function BrowseServer(startupPath, functionData)
// You can use the "CKFinder" class to render CKFinder in a page:
var finder = new CKFinder();
// The path for the installation of CKFinder (default = "/ckfinder/").
finder.basePath = '../';
//Startup path in a form: "Type:/path/to/directory/"
finder.startupPath = startupPath;
// Name of a function which is called when a file is selected in CKFinder.
finder.selectActionFunction = SetFileField;
// Additional data to be passed to the selectActionFunction in a second argument.
// We'll use this feature to pass the Id of a field that will be updated.
finder.selectActionData = functionData;
// Name of a function which is called when a thumbnail is selected in CKFinder. Preview img
// finder.selectThumbnailActionFunction = ShowThumbnails;
// Launch CKFinder
finder.popup();

// This is a sample function which is called when a file is selected in CKFinder.
function SetFileField(fileUrl, data)
document.getElementById(data["selectActionData"]).innerHTML = this
.getSelectedFile().name;
document.getElementById("imgpreview").src = fileUrl;

/*Avatar end*/
</script>
</body>
</html>

Chạy project


Kết quả thành công!
CkfinderJava (1)CkfinderJava (8)CkfinderJava (9)CkfinderJava (2)
Nhờ các plugin bạn có thể thay đổi kích thước ảnh.
CkfinderJava (3)CkfinderJava (4)


Video chi tiết Hướng dẫn tích hợp Ckfinder vào Ckeditor trong Spring Boot Java




Download Full Project Java



Lưu ý: nếu bạn build jar war file lỗi thì hãy thêm dòng sau vào mục plugins của pom.xml nhé:


<plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
</plugin>


Học hành, Lập trình, Spring Framework
Java, Lập trình
Xem Tiếp

Cách nén file tối ưu nhất với 7 zip

Leave a Comment


Hướng dẫn nén file tối ưu nhất với 7 zip


Trong bài viết này, tôi sẽ hướng dẫn thủ thuật nén file đạt mức tối ưu bằng phần mềm 7 ZIP (nén tốt hơn winrar). Điểm mạnh của 7 ZIP đó là nó hoàn toàn free và chức năng không hề kém cạnh các trình compress khác.
nen-va-giai-nen-voi-7-zip-0

Nén và giải nén là việc rất cần thiết cho việc lưu trữ dữ liệu gọn nhẹ. Và nhiều người cũng đã từng đặt câu hỏi “Tại sao file khi tải về file khá nhẹ mà giải nén ra nặng thế”. Đó là do người nén file đã sử dụng các kĩ thuật nén file đạt mức tối ưu nhất để giảm dung lượng file xuống mức tối thiểu.

Khác với phần mềm nén thông dụng như winrar (có phí), thì 7 zip hoàn toàn miễn phí.

[toggle title=”Lưu ý”]Thực tế không phải là trường hợp nào cũng nén được cao. Ví dụ, đối với file văn bản (word, exel,…) thì sẽ nén được rất nhiều nhưng đối với file .exe hoặc nhạc, phim, hình gì đó thì mức nén không cao (gần như chẳng nén được bao nhiêu hết). Những file đó có mức nén không cao vì vốn nó đã được nén rồi. Cho nên ta mới có thuật ngữ là nhạc nén, phim nén,… Điển hình là một bài hát, nếu không nén thì dung lượng một bài hát khoảng 5 phút thì sẽ có dung lượng khoảng 25MB (nhạc lossless) nhưng những bài hát .mp3 ta down trên mạng chỉ có khoảng 5MB. Hình cũng vậy, hình chưa nén là hình RAW, còn những định dạng ta hay xài .jpg là đã được nén. Vì thế, các bạn không nên quá lạm dụng.[/toggle]


 Giới thiệu sơ về 7-zip:


– Đây là một phần mềm nén miễn phí vì là phần mềm mã nguồn mở open source (giống Firefox, Google Chrome,… )

– Nhỏ gọn, tính năng không hề thua kém các phần mềm thương mại như Winrar, WinZip và thậm chí còn nén tốt hơn.

– Có 74 ngôn ngữ trong đó có cả tiếng Việt.

– Có chương trình quản lí tập tin (File Manager).

– Hỗ trợ nén và giải nén đa định dạng.

– Mức nén rất cao và tốc độ cũng rất nhanh nhờ sử dụng thuật toán LZMA.

– Hỗ trợ mã hóa file nén dùng AES-256 và đặt password cho file nén.

[alert-warning]7 zip chỉ có nhược điểm thế này. Sau khi mình dùng nhiều lần thì 7 zip nó tốn nhiều bộ nhớ khi nén và giải nén hơn winrar nên tốc độ nén nó nhanh hơn. Điều này bạn vẫn có thể khắc phục tránh tình trạng treo máy theo hướng dẫn bên dưới.[/alert-warning]


Sau đây mình sẽ hướng dẫn sử dụng 7 zip để nén và giải nén file:


Đầu tiên bạn tải 7 zip về tại đây!

Sau đó Cài đặt 7 zip

Mình sẽ nén 1 folder có dung lượng khoảng 2.6 GB như hình dưới
nen-file-bang-7-zip-dat-muc-toi-uu-nhat (1)

Bạn hãy tìm đến file hoặc folder mình cần nén và chọn 7-Zip > Add to archive…

Tại đây bạn sẽ chỉnh các thông số như sau
nen-file-bang-7-zip-dat-muc-toi-uu-nhat (2)


Giải thích các thiết lập nén


  • Archive format: dạng nén, bạn nên chọn 7z để nén nhanh và mạnh nhất.

  • Compression level: mức độ nén, chỉ khả năng yếu hay mạnh. Độ mạnh sắp xếp tăng dần trừ trên xuống dưới. Mức nén càng cao càng tốn nhiều RAM và thời gian.
    • Ultra: Mức nén cao nhất

    • Maximum: Tối đa

    • Normal: Bình thường

    • Fast: Nhanh

    • Fastest: Nhanh nhất

    • Store: Không nén


  • Compression method: Thuật toán nén file với 7-Zip
    • LZMA: thuật toán nén mặc định, tốc độ nhanh và mạnh(nên chọn nếu bạn muốn giải nén với winrar)

    • LZMA2: nâng cấp của LZMA có thể kém hơn trong 1 số trường hợp như WinRAR không đọc được file nén này

    • PPMd: chủ yếu dùng cho file văn bản với khả năng nén nhanh và mạnh

    • BBzip2: chủ yếu cùng cho file văn bản với tốc độ cao và khả năng nén tốt


  • Dictionary size: lượng RAM dùng để nén và giải nén. Số càng lớn thì RAM tốn càng nhiều nhưng nén mạnh và nhanh
    • Memory usage for Compressing: Nén

    • Memory usage for Decompressing: Giải nén


  • Word size: mục này để số càng cao thì khả năng nén càng mạnh. Vì vậy ta chọn số lớn nhất

  • Solid BLock size: mức độ nén cứng, số càng cao thì nén càng mạnh nhưng tốc độ nén bị giảm. Không ảnh hưởng đến RAM và chỉ sử dụng với chuẩn 7z, để đạt mức nén cao hãy chọn Solid

  • Number of CPU threads: số nhân CPU tham gia quá trình nén(không nên chọn tối đa. Ví dụ máy bạn có 4 luồng thì bạn nên chọn 2/4 hoặc 3/4 thôi nhé).

Ngoài ra bạn cũng có thể đặt password cho file nén, bạn tự tìm hiểu thêm.

Sau khi cấu hình xong nhấn OK để bắt đầu.
nen-file-bang-7-zip-dat-muc-toi-uu-nhat (3)

Thông số Compression ratio càng nhỏ tức tỉ lệ nén càng cao. Thời gian nén phụ thuộc hoàn toàn vào cấu hình máy của bạn cũng như tài nguyên đang có, không có 1 con số chính xác nào đâu nhé.

Kết quả nén với 7 zip từ 2.6 GB giảm còn 621 MB
nen-file-bang-7-zip-dat-muc-toi-uu-nhat (4)

Bạn lưu ý khi bạn cấu hình nén phía trên thì các thiết đặt đã tự động được lưu lại, nếu bạn có muốn nén file khác sẽ không cần phải thay đổi các thông số nữa.


Link tải 7 zip free



Công cụ, Nén, Phần mềm, Thủ thuật PC
Thủ thuật
Xem Tiếp