使用 MySQL、Thymeleaf 和 Spring Boot Framework 上传、存储和查看图像

news2024/11/19 5:52:26

在本文中,我们将使用 Spring Boot 框架从头开始构建映像库应用程序,用户可以在其中列出其映像。

以下是我们将在应用程序中实现的功能。

  • 用户可以列出他们的图像以及详细信息,例如,
    1. 名字
    2. 描述
    3. 图像
    4. 价格。(如果他们想卖)。
  • 任何人都可以查看列出的图像以及所有详细信息。

注意:我们将使用 MySQL 数据库来存储所有图像详细信息。

最终应用

 

 

注意:视频教程可在底部找到。

您可以在本文的底部找到源代码。

请严格按照以下提及的步骤从头开始构建应用程序。

第 1 步:从 Spring Initializr 创建一个项目。

  • 转到 Spring 初始化器。
  • 输入组名称 com.pixeltrice
  • 提及工件 ID,spring-boot-image-gallery-app
  • 添加以下依赖项。
    1. 春网
    2. 春季数据 JPA
    3. MySQL 驱动程序
    4. 百里香叶

第 2 步:按“生成”按钮,该项目将下载到您的本地系统上。

第 3 步:现在解压缩项目并将其解压缩到本地系统。

第 4 步:之后,将项目导入 IDE 中,例如 Eclipse。

选择文件 -> 导入 -> 现有 Maven 项目 -> 浏览 -> 选择文件夹 spring-boot-image-gallery-app-> 完成。

第 5 步:在应用程序中配置属性。属性

应用程序属性

# Set here configurations for the database connection
spring.datasource.url=jdbc:mysql://localhost:3306/imageGalleryApp?autoReconnect=true&useSSL=false
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=your MySQL Password

# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
#create-drop| update | validate | none
spring.jpa.hibernate.ddl-auto = update

# SQL dialect for generating optimized queries
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

uploadDir=/resources

#Enable multipart uploads
spring.servlet.multipart.enabled=true
# Threshold after which files are written to disk.
spring.servlet.multipart.file-size-threshold=2KB
# Max file size.
spring.servlet.multipart.max-file-size=200MB
# Max Request Size
spring.servlet.multipart.max-request-size=215MB

所有属性都是不言自明的,您通过查看它很容易理解。

第 6 步:为图像创建实体类。

在此步骤中,我们将定义实体类,该实体类将与数据库中存在的表进行映射。

ImageGallery.java

package com.pixeltrice.springbootimagegalleryapp.entity;

import java.util.Arrays;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
@Table(name = "image_gallery")
public class ImageGallery {

	@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id", nullable = false, unique = true)
	private Long id;
	
	@Column(name = "name", nullable = false)
	private String name;
	
	@Column(name = "description", nullable = false)
	private String description;	
	
	@Column(name = "price",nullable = false, precision = 10, scale = 2)
    private double price;
	
	@Lob
    @Column(name = "Image", length = Integer.MAX_VALUE, nullable = true)
    private byte[] image;
    
    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "create_date", nullable = false)
    private Date createDate;

	public ImageGallery() {}

	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;
	}

	public String getDescription() {
		return description;
	}

	public void setDescription(String description) {
		this.description = description;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public byte[] getImage() {
		return image;
	}

	public void setImage(byte[] image) {
		this.image = image;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}

	@Override
	public String toString() {
		return "Product [id=" + id + ", name=" + name + ", description=" + description + ", price=" + price + ", image="
				+ Arrays.toString(image) + ", createDate=" + createDate + "]";
	}
   
}

在实体上方,该类将与 MySQL 数据库中名为“image_gallery”的表进行映射。由于该类带有@Entity注释标记,因此它是一个持久 Java 类。

@Table注解指示与上述实体类映射的数据库表名。 @Id注解用于将变量表示为表中的主键。

@Column注释用于表示与上述变量或字段映射的列的名称。

@Lob注释用于将大型对象存储到数据库中,例如字节数组或大型字符串。在我们的例子中,我们以字节数组的形式存储图像。

此注释用于指定使用 Lob 标记或批注的字段应在数据库表中以 BLOB(二进制大对象)数据类型的形式表示。

第 7 步:为 ImageGallery 实体类创建存储库接口

在这里,我们将创建存储库,该存储库将与我们的数据库通信并执行所有类型的 CRUD 操作。在此步骤中,我们将扩展一个名为 JpaRepository 的预定义类,该类提供了创建、删除、更新和从数据库表中获取数据所需的所有可能方法。

ImageGalleryRepository.java

package com.pixeltrice.springbootimagegalleryapp.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.pixeltrice.springbootimagegalleryapp.entity.ImageGallery;


@Repository
public interface ImageGalleryRepository extends JpaRepository<ImageGallery, Long>{

}

JpaRepository<ImageGallery, Long>: 在尖括号<>我们必须提到主键的实体类名和数据类型。因为在我们的例子中,实体类名是图像库,主键是具有类型的id

@Repository:此注释指示类或接口完全专用于执行各种 CRUD 操作,例如创建、更新、读取或删除数据库中的数据。

第 8 步:创建图像库服务类

ImageGalleryService.java

package com.pixeltrice.springbootimagegalleryapp.service;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.pixeltrice.springbootimagegalleryapp.entity.ImageGallery;
import com.pixeltrice.springbootimagegalleryapp.repository.ImageGalleryRepository;



@Service
public class ImageGalleryService {

	@Autowired
	private ImageGalleryRepository imageGalleryRepository;
	
	public void saveImage(ImageGallery imageGallery) {
		imageGalleryRepository.save(imageGallery);	
	}

	public List<ImageGallery> getAllActiveImages() {
		return imageGalleryRepository.findAll();
	}

	public Optional<ImageGallery> getImageById(Long id) {
		return imageGalleryRepository.findById(id);
	}
}

第 9 步:创建控制器类

在控制器类中,我们将创建 API,以存储和获取来自 MySQL 数据库的图像。

ImageGalleryController.java

package com.pixeltrice.springbootimagegalleryapp.controller;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.pixeltrice.springbootimagegalleryapp.entity.ImageGallery;
import com.pixeltrice.springbootimagegalleryapp.service.ImageGalleryService;


@Controller
public class ImageGalleryController {
	
	@Value("${uploadDir}")
	private String uploadFolder;

	@Autowired
	private ImageGalleryService imageGalleryService;

	private final Logger log = LoggerFactory.getLogger(this.getClass());

	@GetMapping(value = {"/", "/home"})
	public String addProductPage() {
		return "index";
	}

	@PostMapping("/image/saveImageDetails")
	public @ResponseBody ResponseEntity<?> createProduct(@RequestParam("name") String name,
			@RequestParam("price") double price, @RequestParam("description") String description, Model model, HttpServletRequest request
			,final @RequestParam("image") MultipartFile file) {
		try {
			//String uploadDirectory = System.getProperty("user.dir") + uploadFolder;
			String uploadDirectory = request.getServletContext().getRealPath(uploadFolder);
			log.info("uploadDirectory:: " + uploadDirectory);
			String fileName = file.getOriginalFilename();
			String filePath = Paths.get(uploadDirectory, fileName).toString();
			log.info("FileName: " + file.getOriginalFilename());
			if (fileName == null || fileName.contains("..")) {
				model.addAttribute("invalid", "Sorry! Filename contains invalid path sequence \" + fileName");
				return new ResponseEntity<>("Sorry! Filename contains invalid path sequence " + fileName, HttpStatus.BAD_REQUEST);
			}
			String[] names = name.split(",");
			String[] descriptions = description.split(",");
			Date createDate = new Date();
			log.info("Name: " + names[0]+" "+filePath);
			log.info("description: " + descriptions[0]);
			log.info("price: " + price);
			try {
				File dir = new File(uploadDirectory);
				if (!dir.exists()) {
					log.info("Folder Created");
					dir.mkdirs();
				}
				// Save the file locally
				BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(new File(filePath)));
				stream.write(file.getBytes());
				stream.close();
			} catch (Exception e) {
				log.info("in catch");
				e.printStackTrace();
			}
			byte[] imageData = file.getBytes();
			ImageGallery imageGallery = new ImageGallery();
			imageGallery.setName(names[0]);
			imageGallery.setImage(imageData);
			imageGallery.setPrice(price);
			imageGallery.setDescription(descriptions[0]);
			imageGallery.setCreateDate(createDate);
			imageGalleryService.saveImage(imageGallery);
			log.info("HttpStatus===" + new ResponseEntity<>(HttpStatus.OK));
			return new ResponseEntity<>("Product Saved With File - " + fileName, HttpStatus.OK);
		} catch (Exception e) {
			e.printStackTrace();
			log.info("Exception: " + e);
			return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
		}
	}
	
	@GetMapping("/image/display/{id}")
	@ResponseBody
	void showImage(@PathVariable("id") Long id, HttpServletResponse response, Optional<ImageGallery> imageGallery)
			throws ServletException, IOException {
		log.info("Id :: " + id);
		imageGallery = imageGalleryService.getImageById(id);
		response.setContentType("image/jpeg, image/jpg, image/png, image/gif");
		response.getOutputStream().write(imageGallery.get().getImage());
		response.getOutputStream().close();
	}

	@GetMapping("/image/imageDetails")
	String showProductDetails(@RequestParam("id") Long id, Optional<ImageGallery> imageGallery, Model model) {
		try {
			log.info("Id :: " + id);
			if (id != 0) {
				imageGallery = imageGalleryService.getImageById(id);
			
				log.info("products :: " + imageGallery);
				if (imageGallery.isPresent()) {
					model.addAttribute("id", imageGallery.get().getId());
					model.addAttribute("description", imageGallery.get().getDescription());
					model.addAttribute("name", imageGallery.get().getName());
					model.addAttribute("price", imageGallery.get().getPrice());
					return "imagedetails";
				}
				return "redirect:/home";
			}
		return "redirect:/home";
		} catch (Exception e) {
			e.printStackTrace();
			return "redirect:/home";
		}	
	}

	@GetMapping("/image/show")
	String show(Model map) {
		List<ImageGallery> images = imageGalleryService.getAllActiveImages();
		map.addAttribute("images", images);
		return "images";
	}
}	

控制器类中存在的每个 API 的说明。

  1. @GetMapping(value = {“/”, “/home”}):每当请求到达此 API 时,它都会返回索引,由于我们已经在应用程序中实现了百里香叶,因此它将返回 index.html 页面。

2. @PostMapping(“/image/saveImageDetails”):用于将新的图像详细信息存储到MySQL数据库中。

request.getServletContext().getRealPath(uploadFolder):如您所见,我们已经通过从 application.properties 文件中分配值 /resources 来初始化变量 uploadFolder

我们将参数传递给 getRealPath(),因此它将返回您在本地系统中创建工作区的完整路径。因此对我来说

file.getOriginal文件名():它将返回产品图片的实际名称,例如image.png,这取决于您上传的产品名称。

Paths.get(uploadDirectory, fileName).toString():它将返回系统上保存上传图像的确切位置。

之后,我们将图像转换为字节数组,并将所有与图像相关的详细信息(例如名称,描述,图像等)存储到MySQL数据库中。

如您所见,我们将图像以 byte[] 形式存储在数据库表中,这就是为什么在实体类中我们必须使用注释@Lob

3. @GetMapping(“/image/display/{id}”):该接口用于从数据库中获取特定图像的 byte[] 形式,并将其转换为 jpeg、png、jpg 或 gif 格式以显示在浏览器中。

4. @GetMapping(“/image/imageDetails”):它根据镜像 ID 从数据库中获取镜像详情,并显示在镜像详情中.html

5. @GetMapping(“/image/show”):这是控制器类中的最后一个API,用于在images.html页面中显示产品列表及其详细信息。

第 10 步:创建 HTML 页面

在最后一步中,我们看到我们的应用程序需要三个 HTML 页面。让我们创建它。

注意:确保你应该在\src\main\resources\templates中创建所有HTML页面

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <title>PixelTrice</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <link rel="stylesheet" href="/css/style.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<br><br>
<h1 class="text-center">Spring Boot Image Gallery Application</h1><br><br>
<div class="contact py-sm-5 py-4">
		<div class="container py-xl-4 py-lg-2">
		<!-- form -->
		<form id="form">
				<div class="contact-grids1 w3agile-6">
					<div class="row">
						<div class="col-md-6 col-sm-6 contact-form1 form-group">
							<label class="col-form-label">Name</label>
							<input type="text" class="form-control" placeholder="Product Name" id="name" name="name" required="required">
							<p id="error_name"></p>
						</div>
						<div class="col-md-6 col-sm-6 contact-form1 form-group">
							<label class="col-form-label">Description</label>
							<textarea class="form-control" placeholder="Product Description" id="description" rows="3" cols="45" name="description" required="required"></textarea>
							<p id="error_description"></p>
						</div>
						<div class="col-md-6 col-sm-6 contact-form1 form-group">
							<label class="col-form-label">Image</label>
							<input type="file" class="form-control" placeholder="" name="image" id="image" required="required">
							<p id="error_file"></p>
						</div>
						<div class="col-md-6 col-sm-6 contact-form1 form-group">
							<label class="col-form-label">Price</label>
							<input type="text" class="form-control" placeholder="Price" name="price" id="price" required="required">
							<p id="error_price"></p>
						</div>
					</div>
					
						<div class="right-w3l col-md-6">
							<input type="button" id="submit" class="btn btn-primary form-control" value="Submit">
							<br><br>
						</div>
						<a href="/image/show" style="float:left;" class="btn btn-success text-right">Show All</a>
				</div>
				<br>
				<div id="success" class="text-center" style="color:green;"></div>
				<div id="error" class="text-center" style="color:red;"></div>
			</form>
		</div>
	</div>
<p class="text-center">
  	<img src="/images/loader.gif" alt="loader" style="width: 150px;height: 120px;" id="loader">
</p>
	<script src="/js/product.js"></script>
</body>
</html>

images.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
  <title>PixelTrice</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <link rel="stylesheet" href="/css/style.css">
  <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/dataTables.bootstrap.min.css">
</head>
<body>
<br>
<h1 class="text-center">Spring Boot Image Gallery Application
<a href="/home" class="btn btn-danger text-right">Go Home</a>
</h1>
<br><br>

<table id="example" class="table table-striped table-bordered text-center">
        <thead>
            <tr>
                <th>SR. No.</th>
                <th>Name</th>
                <th>Image</th>
                <th>Description</th>
                <th>Price</th>
                <th>Created date</th>
                <th>Action</th>
            </tr>
        </thead>
        <tbody th:with="count=0">
        <tr th:each = "imageGallery, hh : ${images}">           
                <td th:with="count=${count + 1}" th:text="${count}"></td>
                <td th:text="${imageGallery.name}"></td>
                <td><img th:src="@{${'/image/display/'+ imageGallery.id}}" 
                class="card img-fluid" style="width:300px" alt=""/></td>
                <td th:text="${imageGallery.description}"></td>
                <td th:text="${imageGallery.price}"></td>
                <td th:text="${#dates.format({imageGallery.createDate}, 'dd-MM-yyyy')}"/></td>
               <td><a th:href="@{/image/imageDetails(id=${imageGallery.id})}" class="btn btn-info text-right" target="_blank">View</a></td>
            </tr>
        </tbody>
    </table>


	<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
	<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
	<script src="https://cdn.datatables.net/1.10.21/js/dataTables.bootstrap.min.js"></script>
	<script type="text/javascript">
	$(document).ready(function() {
	    $('#example').DataTable();
	} );
	</script>
</body>
</html>

imagedetails.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="ISO-8859-1">
<title>PixelTrice</title>
<meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <link rel="stylesheet" href="/css/style.css">
</head>
<body>
<br>
	<div class="banner-bootom-w3-agileits py-5">
		<div class="container py-xl-4 py-lg-2">
			<!-- tittle heading -->
			<h3 class="tittle-w3l text-center mb-lg-5 mb-sm-4 mb-3">
				<span>I</span>mage
				<span>D</span>etails</h3><br>
			<!-- //tittle heading -->
			<div class="row">
				<div class="col-lg-5 col-md-8 single-right-left ">
					<div class="grid images_3_of_2">
						<div class="flexslider">
						<div class="thumb-image">
							<img th:src="@{${'/image/display/'+id}}" 
							 class="img img-responsive img-fluid" alt=""> 
						</div>
							<div class="clearfix"></div>
						</div>
					</div>
				</div>

				<div class="col-lg-7 single-right-left simpleCart_shelfItem">
					Name: <span th:text="${name}" class="mb-3"></span>
					<p class="mb-3">
						Price :&#36; <span class="item_price" th:text="${price}"></span>
					</p>
					<div class="product-single-w3l">
						Description: <span th:text="${description}" class="my-sm-4 my-3"> 
						</span>
					</div><br>
					<a href="/image/show">Go Back</a>
					&emsp;<a href="/">Go Home</a>
				</div>
			</div>
		</div>
	</div>
</body>
</html>

第 11 步:创建 css 和 javascript 文件

在此步骤中,我们将为我们的应用程序创建样式.css产品.js。还在图像文件夹中放置了一个加载图像。

确保你应该在 src\main\resources\static\css 和 product.js 在路径 src\main\resources\static\js 中创建 style.css

注意我们需要在路径 src\main\resources 上再创建一个包含命名图像的文件夹,我们必须在其中存储加载图像 您可以从我的 GitHub 帐户上提供的源代码下载它。

product.js

   $(document).ready(function() {
    $('#loader').hide();
    $("#submit").on("click", function() {
    	$("#submit").prop("disabled", true);
    	var name = $("#name").val();
        var file = $("#image").val(); 
        var price = $("#price").val();
        var description = $("#description").val();
        var form = $("#form").serialize();
    	var data = new FormData($("#form")[0]);
    	data.append('name', name);
    	data.append('price', price);
    	data.append('description', description); 
    	//alert(data);
        $('#loader').show();
        if (name === "" || file === "" || price === "" || description === "") {
        	$("#submit").prop("disabled", false);
            $('#loader').hide();
            $("#name").css("border-color", "red");
            $("#image").css("border-color", "red");
            $("#price").css("border-color", "red");
            $("#description").css("border-color", "red");
            $("#error_name").html("Please fill the required field.");
            $("#error_file").html("Please fill the required field.");
            $("#error_price").html("Please fill the required field.");
            $("#error_description").html("Please fill the required field.");
        } else {
            $("#name").css("border-color", "");
            $("#image").css("border-color", "");
            $("#price").css("border-color", "");
            $("#description").css("border-color", "");
            $('#error_name').css('opacity', 0);
            $('#error_file').css('opacity', 0);
            $('#error_price').css('opacity', 0);
            $('#error_description').css('opacity', 0);
                    $.ajax({
                        type: 'POST',
                        enctype: 'multipart/form-data',
                        data: data,
                        url: "/image/saveImageDetails", 
                        processData: false,
                        contentType: false,
                        cache: false,
                        success: function(data, statusText, xhr) {
                        console.log(xhr.status);
                        if(xhr.status == "200") {
                        	$('#loader').hide(); 
                        	$("#form")[0].reset();
                        	$('#success').css('display','block');
                            $("#error").text("");
                            $("#success").html("Product Inserted Succsessfully.");
                            $('#success').delay(2000).fadeOut('slow');
                         }	   
                        },
                        error: function(e) {
                        	$('#loader').hide();
                        	$('#error').css('display','block');
                            $("#error").html("Oops! something went wrong.");
                            $('#error').delay(5000).fadeOut('slow');
                            location.reload();
                        }
                    });
        }
            });
        });

注意:请参考我的Github帐户了解样式.css代码。

现在我们可以运行应用程序了,但在此之前,请确保您提供了正确的 MySQL 用户名、密码和架构名称。

还要验证文件夹结构,如图所示。

第 12 步:运行应用程序

运行应用程序后,添加图像详细信息和视图,如图所示。

进入本地主机:8080上传图片,如图所示。

按提交按钮将图像详细信息存储在MySQL数据库中。点击 全部显示 按钮查看图像。

 

单击“查看”按钮以查看图像的详细信息。

 

下载源代码

总结

在本教程中,我们学习并构建了使用 MySQL、Thymeleaf 和 Spring Boot Framework 上传、存储和查看图像的应用程序。源代码在我的 Github 帐户上可用,如果卡在任何地方或遇到一些错误,请通过它。您也可以在下面的评论部分提出任何疑问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/72384.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Win11 启用旧右键菜单 _ Windows11 右键改回老版

Win11 系统在使用上和之前的系统差不多&#xff0c;但是在设计上&#xff0c;有了很大的改变&#xff0c;系统界面&#xff0c;设置等功能都使用了全新的风格&#xff0c;包括右键菜单&#xff0c;这让很多用户使用起来都很不习惯&#xff0c;因此想改回旧版的右键菜单来使用。…

汽车控制器概述

目录 一、整车控制器&#xff08;VCU&#xff09; 功能 工作模式 二、发动机控制器/电子控制单元&#xff08;ECU&#xff09; ECU基本组成 ECU的作用 ECU的工作原理 常见的ECU的类型 三、电机控制器&#xff08;MCU&#xff09; 四、 电池管理系统&#xff08;BMS&a…

cubeIDE开发, stm32的USB从设备串口驱动设计

一、USB_OTG简介 USB_OTG&#xff08;OTG&#xff0c;ON THE GO&#xff09;是一款双角色设备(DRD) 控制器&#xff0c;同时支持从机&#xff08;USB DEVICE&#xff09;功能和主机&#xff08;USB HOST&#xff09;功能。在主机模式下&#xff0c;OTG 支持全速&#xff08;OTG…

2022圣诞在即,出海品牌如何做好网红营销?

随着2022圣诞节逐渐临近&#xff0c;节日气氛也开始浓郁起来&#xff0c;尤其在社交媒体上&#xff0c;圣诞主题的内容越来越多&#xff0c;随之而来的则是各种营销与折扣。受经济形势影响&#xff0c;性价比在当下显得尤为重要&#xff0c;有60%的消费者表示&#xff0c;今年圣…

【能效分析】安科瑞变电所运维云平台解决方案应用分析

概述 安科瑞 李亚俊 壹捌柒贰壹零玖捌柒伍柒 AcrelCloud-1000变电所运维云平台基于互联网&#xff0b;大数据、移动通讯等技术开发的云端管理平台&#xff0c;满足用户或运维公司监测众多变电所回路运行状态和参数、室内环境温湿度、电缆及母线运行温度、现场设备或环境视频场…

CentOS MySQL安装

1.查询是否已经存在mariadb。 rpm -qa|grep mariadb如果存在需要卸载。 rpm -e --nodeps mariadb-libs-5.5.68-1.el7.x86_642.通过xftp上传MySQL和Hive压缩包。 3.解压压缩包。 tar -zxvf apache-hive-2.3.4-bin.tar.gz -C /opt/apps/ tar -zxvf mysql-5.7.27-el7-x86_64.ta…

042-推箱子游戏源代码2

上一讲:041-推箱子游戏1_CSDN专家-赖老师(软件之家)的博客-CSDN博客 摘要: 1、使用JAVA基础知识 2、GUI界面编程实现推箱子界面,常用控件的综合应用; 3、使用JAVA绘图技术实现推箱子过程的绘图功能; 4、使用键盘事件,通过方向键实现推箱子过程; 5、使用音频技术,…

Android实现车辆检测(含Android源码 可实时运行)

Android实现车辆检测(含Android源码 可实时运行) 目录 Android实现车辆检测(含Android源码 可实时运行) 1. 前言 2. 车辆检测数据集说明 3. 基于YOLOv5的车辆检测模型训练 4.车辆检测模型Android部署 &#xff08;1&#xff09; 将Pytorch模型转换ONNX模型 &#xff08…

Python编程 圣诞树教程 (附代码)程序员的浪漫

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.python 做圣诞树 1.turtle库 2.python函数的定义规则 2.引入库 3.定…

中断系统中的设备树__在S3C2440上使用设备树描述中断体验

目录 1 怎么描述一个中断 2 怎么描述一个中断控制器 3 总结 1 怎么描述一个中断 我们想在设备树文件中描述一个中断&#xff0c;那么需要两个东西 a.指定是哪一个中断控制器 b.是中断控制器里面的哪一个中断。 假设我们有一个网卡&#xff0c;当网卡有数据时会产生一个中…

论文速度系列三:SA-SSD、CIA-SSD、SE-SSD

如有错误&#xff0c;恳请指出。 参考网上资料&#xff0c;对一些经典论文进行快速思路整理 文章目录1. SA-SSD2. CIA-SSD3. SE-SSD1. SA-SSD paper&#xff1a;《Structure Aware Single-stage 3D Object Detection from Point Cloud》&#xff08;2020CVPR&#xff09; 结构…

网络工程师备考4章

4.1 历年考点分布 4.2 局域网和城域网 4.2.1 局域网体系与拓扑结构 一般数据链路层的协议都是IEEE这个组织规范的,网络层是有RFC这个组织规范的。 数据链路层是可以划分为两个子层的,第一个叫逻辑链路控制LLC(对接上面的网络层),第二个叫MAC子层(更偏向于物理层)。 最…

【hadoop】Hadoop 3.3.4 集群安装及简单使用

目录环境信息1. 准备1.1 服务器规划1.2 主机名及hosts文件修改1.2.1 hostname修改1.2.2 hosts文件修改1.3 创建hadoop用户&#xff08;建议&#xff09;1.4 为hadoop用户添加sudo权限1.5 互信免密登录1.6 快速文件同步&#xff08;可选&#xff09;2. 安装2.1 下载并安装jdk2.2…

变量学习笔记

一:作用域 说起变量第一个要说到的肯定就是作用域,正是因为不熟悉JS的作用域,往往就会把面向对象的作用域张冠李戴,毕竟有些东西总是习惯性 的这样,但是并不是每次照搬都是可以的,那么下一个问题就来了,js到底是什么作用域,当然是函数作用域了,我们的浏览器就是一个被…

基于工业物联网的温度监测系统在钢铁行业的应用

随着钢铁行业的快速发展&#xff0c;越来越多电气设备被接入到工业生产系统中&#xff0c;对自动化和连续性的生产提出新的要求&#xff0c;需要关注到供电的稳定可靠&#xff0c;也要关注到用电设备的运行状态。电气设备在长期运行中会面临越来越高的风险&#xff0c;引发危险…

ncurses交叉编译

1.环境 编译环境&#xff1a;ubuntu18.04虚拟机 板端&#xff1a;移远AG550平台 编译链aarch64-oe-linux 2.ncurses下载 ncurses库下载地址&#xff1a;Index of /pub/gnu/ncurses 下载5.9的版本 3.解压并且编译 tar xvf ncurses-5.9.tar.gz cd ncurses-5.9 执行configure命…

Android与H5(Vue)交互

Android与H5互调 实现效果&#xff1a; JS调用Android方法实现dialog弹窗&#xff0c;Android点击弹窗确定/取消按钮调用JS方法&#xff0c;在H5界面展示传递的参数。 Vue准备&#xff1a; 执行 npm run serve 命令启动项目&#xff0c;启动成功后会在命令行看到两个地址&am…

beego框架学习之安装框架

Beego 是一个快速开发 Go 应用的 HTTP 框架&#xff0c;可以用来快速开发 API、Web 及后端服务等各种应用&#xff0c;是一个 RESTful 的框架&#xff0c;相对于echo框架仅包含路由和控制器核心模块&#xff0c;beego是一个完整的MVC框架包括路由&控制器、model 数据库ORM封…

GitLab结合fortify实现自动化代码审计实践

一、背景 在甲方做安全的同学可能会有一项代码审计的工作&#xff0c;通常需要从gitlab把代码拉取下来&#xff0c;然后使用代码审计工具进行扫描&#xff0c;然后对结果进行人工确认&#xff1b; 在这个流程中需要做的事情比较繁琐&#xff0c;比如说gitlab如何配置token、如…

.net开发安卓入门 - 基本交互(Button,输入EditText,TextView,Toast)

.net开发安卓入门 - 基本交互前言TextViewEditTextButtonxml代码如下C#代码如下运行效果优化代码先看原生Android给一个View添加点击事件的三种方式在Xamarin.Android中添加onClick也的两种办法使用onClick绑定前后台调用处理逻辑第一步&#xff1a;第二步&#xff1a;第三步&a…