当前位置:网站首页>Tu oses le croire? Il m'a fallu deux jours pour développer un système de gestion.
Tu oses le croire? Il m'a fallu deux jours pour développer un système de gestion.
2022-06-12 14:30:00 【Java notes crevettes】
Cliquez sur le numéro public,UtilisationTemps partiel pour apprendre
Analyse des difficultés
Mais quand j'ai appris la nouvelle,C'est encore un choc à l'intérieur,Après tout, c'est un système de gestion complet,L'interface fonctionnelle ne doit pas être trop rudimentaire.Et tout, de la conception de la base de données à la livraison de l'ensemble du système, est fait seul,L'effet challenge est directement tiré!Mais calme - toi et réfléchis,Ce n'est pas très difficile non plus,Le processus global du projet est:Conception——>Documentation——>Codage——>Livraison.
Une fois le processus terminé,Commencez par une mise en œuvre étape par étape de rien,Je ne pensais pas qu'à la dernière étape,Il m'a fallu un jour et demi!!Il a fallu une demi - journée de plus pour optimiser l'ensemble du projet!
Examen du projet
Démonstration de l'effet final:

Sélection technique:
SpringBoot
Thymeleaf
Mybatis-Plus
MySQL
PageHelper
Lombok
Redis(Utilisation optimisée de la page post)
Introduction au processus opérationnel du projet
Module de connexion、Gestion du module utilisateur et attribution des rôles aux utilisateurs,Gestion du module des bulletins d'information、Module produit(Y compris les produits de base、Classification des marchandises、Ordre)Gestion、Gestion des modules de rôle; Si une ressource frontale a la permission d'utiliser cette ressource ,Utiliséthymeleaf Fonctions de base de la syntaxe des modèles pour l'identification des jugements et le téléchargement de fichiers .
Construction du projet(Utilisation du moteur Template)
1. Créer d'abordMavenProjets
Introduire les dépendances correspondantes, Construire le Répertoire de fichiers requis


2. CompilationyamlProfil
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/supplier?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
username: root
password: root
# thymeleaf Configuration
thymeleaf:
# Fermer le cache
cache: false
prefix: classpath:/templates/
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml3. Construction de base au début du projet
Au début de la construction d'un projet , Pour rendre le système plus normalisé , J'ai l'habitude de configurer et de déclarer les bases à l'avance , Les technologies impliquées dans la conception d'un projet dès le début et certaines configurations de base pour ces technologies , Tout doit être planifié à l'avance (Habitudes personnelles).Par exemple,:Gestion des exceptions、Intercepteur、Filtre、 Classe constante, etc. .
①Gestion des exceptions
@ControllerAdvice
public class ExceptionHandler {
private final org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
@org.springframework.web.bind.annotation.ExceptionHandler(Exception.class)
public ModelAndView exception(HttpServletRequest request, Exception e ) throws Exception {
logger.error("Request URL:{},Exception:{}",request.getRequestURL(),e);
if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class )!= null){
throw e;
}
ModelAndView mv = new ModelAndView();
mv.addObject("url",request.getRequestURL());
mv.addObject("exception",e);
mv.setViewName("error/error");
return mv;
}
}② Intercepteur
L'intercepteur traite principalement de certaines ressources , Similaire à certaines ressources qui nécessitent la connexion de l'utilisateur , Certains ne sont pas nécessaires ,Par exemple,: La fonction login n'a pas besoin d'être bloquée , La gestion des utilisateurs nécessite l'ajout d'une opération d'interception , Afin d'améliorer la sécurité du système .
Interception de connexion
public class LoginInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (request.getSession().getAttribute("user") == null){
response.sendRedirect("/api");
return false;
}
return true;
}
}Libération des ressources
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/api/**")
.excludePathPatterns("/api","/api/doLogin");
}
}4. CompilationControllerCode du Contrôleur avant
Commencez par créer unFileControllerCatégorie
① Sautez à la page de téléchargement du fichier
// Sautez à la page de téléchargement du fichier
@RequestMapping("/file-upload")
public String userList(){
return "file-upload";
}② Réaliser la fonction de téléchargement de fichiers
@RequestMapping("/doAddForUser")
public String doAdd(User user, @RequestParam("file") MultipartFile files, HttpServletRequest request) throws IOException {
//String path = null;
if (files != null && !files.isEmpty()){
String name = UUID.randomUUID().toString().replace("-","");
//Obtenir une extension de fichier
String ext = FilenameUtils.getExtension(files.getOriginalFilename());
// Définir le chemin de téléchargement du fichier
String url =request.getSession().getServletContext().getRealPath("/upload/");
File file = new File(url);
if (!file.exists()){
file.mkdir();
}
//Chemin d'essai
System.out.println(request.getServletPath()+ "/upload");
System.out.println(request.getContextPath() + "/upload/");
// Enregistrer le fichier renommé dans un chemin absolu
files.transferTo(new File(url+"/"+name+"."+ext));
user.setAvatar(request.getContextPath() + "/upload/"+name+"."+ext);
}
user.setId(UUID.randomUUID().toString());
String salt = PasswordUtils.getSalt();
String password = user.getPassword();
String encode = PasswordUtils.encode(password, salt);
user.setSalt(salt) ;
user.setPassword(encode);
user.setCreateTime(new Date());
userService.save(user);
return "redirect:/api/users";
}Note:: Comment réaliser le téléchargement de fichiers multiples :
③ Réaliser la fonction de téléchargement de fichiers multiples
La fonction de téléchargement de fichiers multiples n'est pas implémentée dans ce projet
private void commons(Object obj, @RequestParam("file") CommonsMultipartFile[] files, HttpServletRequest request) throws IOException {
//String path = null;
for (int i = 0; i < files.length; i++) {
if (files[i] != null && !files[i].isEmpty()){
String name = UUID.randomUUID().toString().replace("-","");
//Obtenir une extension de fichier
String ext = FilenameUtils.getExtension(files[i].getOriginalFilename());
// Définir le chemin de téléchargement du fichier
String url =request.getSession().getServletContext().getRealPath("/upload/");
File file = new File(url);
if (!file.exists()){
file.mkdir();
}
//Chemin d'essai
System.out.println(request.getServletPath()+ "/upload");
System.out.println(request.getContextPath() + "/upload/");
// Enregistrer le fichier renommé dans un chemin absolu
files[i].transferTo(new File(url+"/"+name+"."+ext));
if (i == 0){
obj.setUrl1(request.getContextPath() + "/upload/"+name+"."+ext);
}
if (i == 1){
obj.setUrl2(request.getContextPath() + "/upload/"+name+"."+ext);
}
if (i == 2){
obj.setUrl3(request.getContextPath() + "/upload/"+name+"."+ext);
}
if (i == 3){
obj.setUrl4(request.getContextPath() + "/upload/"+name+"."+ext);
}
if (i == 4){
obj.setUrl5(request.getContextPath() + "/upload/"+name+"."+ext);
}
}
}
}5. Optimisation des projets
Pour les articles qui ne sont pas séparés de l'avant et de l'arrière , La plupart des optimisations de cache de page sont utilisées , Lorsque le système subit un flux important à un moment donné , Les données de la page peuvent être mises en cache lorsque le premier utilisateur accède à la page ,Voilà., Les pages visitées par les utilisateurs ultérieurs sont toutes extraites du cache ,Ça réduit Fonctionnement de la base de données,Réduction de la pression sur la base de données, Pour obtenir un traitement optimisé .
① Importer des dépendances
<!--Redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--commons-pools2 Dépendance du pool d'objets-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>② yamlConfiguration
## RedisConfiguration
redis:
# Adresse du serveur
host: localhost
# Port
port: 6379
# Base de données
database: 0
# Temps mort
connect-timeout: 10000ms
lettuce:
pool:
# Nombre maximum de connexions
max-active: 8
# Temps d'attente maximal de blocage de la connexion Par défaut -1
max-wait: 10000ms
# Temps libre maximum Par défaut8
max-idle: 200
# Connexion minimale libre Par défaut8
min-idle: 5④ RedisTraitement de sérialisation
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
//keySérialisation
redisTemplate.setKeySerializer(new StringRedisSerializer());
//valueSérialisation
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
//hashTypekeySérialisation de
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
//hashTypevalueSérialisation de
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
}③ Traitement optimisé
@Autowired
private NewsService newsService;
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private ThymeleafViewResolver viewResolver;
@RequestMapping(value = "/news",produces = "text/html;charset=utf-8")
@ResponseBody
public String roles(Model model, @RequestParam(value = "pageNo",defaultValue = "1")Integer pageNo
, @RequestParam(value = "pageSize",defaultValue = "10")Integer pageSize
, HttpServletRequest request, HttpServletResponse response){
//RedisObtenir la page,Si ce n'est pas vide, Retourner directement à la page
ValueOperations valueOperations = redisTemplate.opsForValue();
String html = (String) valueOperations.get("news-list");
if (!StringUtils.isEmpty(html)){
return html;
}
PageHelper.startPage(pageNo,pageSize);
List<News> list = newsService.list();
PageInfo<News> pageInfo = new PageInfo<>(list);
model.addAttribute("news",list);
model.addAttribute("pageInfo",pageInfo);
//Si vide,Rendu manuel,DépôtRedisMilieu et retour
WebContext context = new WebContext(request, response, request.getServletContext(), request.getLocale(), model.asMap());
html = viewResolver.getTemplateEngine().process("news-list", context);
if (!StringUtils.isEmpty(html)){
//Définir un délai d'expiration pour le cache
valueOperations.set("news-list",html,60, TimeUnit.SECONDS);
}
return html;
}④ RedisVoir

6. Notes
Attention!@ControllerEt@RestControllerLa différence entre, Ce projet utilise une page de rendu de modèle ,Et@Controller C'est pour répondre à la page ;Et@RestControllerC'est pour revenir àJson
Annotation de la méthode requise pendant la phase d'optimisation du projet @ResponseBody, Parce que nous mettons en cache toute la page , Donc pour convertir la page en JSONStockage.

InjectionThymeleafAnalyseur,Sera spécifique La page est analysée en Json Chaîne à stocker


Sera déposé dansRedis Données en plus du temps d'expiration , Parce que les données de la page sont alignées sur la base de données , Si l'utilisateur voit des données il y a des dizaines de secondes ou une minute, c'est à peine acceptable. .

Le Code est actuellement synchronisé avec Gitee:
https://gitee.com/gao-wumao/supplier
Allez à l'entrepôt si nécessaire. , Et s'il vous plaît, Messieurs, ne soyez pas avares avec les trois ligues. !
Source::https://blog.csdn.net/Gaowumao
Recommandations:
Le plus completjavaQuestionnaire d'entrevue

PS:Parce que la plate - forme des numéros publics a changé les règles de poussée,Si vous ne voulez pas manquer le contenu,N'oubliez pas de lire un peu“Je regarde”,Ajouter“Étoile”,De cette façon, chaque fois qu'un nouvel article est poussé, il apparaîtra pour la première fois dans votre liste d'abonnements.Point“Je regarde”Soutenez - nous!
边栏推荐
- Redis core configuration and advanced data types
- Brush one question every day /537 Complex multiplication
- Notepad common settings
- Player actual combat 23 decoding thread
- QT link error: undefined reference to VTable for "XXX“
- Nesting of C language annotations
- Tool notes - common custom tool classes (regular, random, etc.)
- 2022版Redis数据删除策略
- Copy word content to excel and automatically divide it into multiple columns
- Dynamic search advertising intelligent search for matching keywords
猜你喜欢

Soft test (VI) Chrome browser installation selenium IDE

Redis核心配置和高级数据类型

Two methods of QT using threads

Perfect ending | detailed explanation of the implementation principle of go Distributed Link Tracking

For cross-border e-commerce, the bidding strategy focusing more on revenue - Google SEM

Reverse order of Excel

The original Xiaoyuan personal blog project that has been around for a month is open source (the blog has basic functions, including background management)

TestEngine with ID ‘junit-vintage‘ failed to discover tests

Printing colored messages on the console with printf

Llvm pass-- virtual function protection
随机推荐
Dynamic search advertising intelligent search for matching keywords
Write policy of cache
3. Hidden processes under the ring
Xshell (I) is missing mfc110u DLL file resolution
Introduction to functions (inline functions and function overloading)
Tcp/ip network communication knowledge record
Why do Chinese programmers change jobs?
Soft test (VI) Chrome browser installation selenium IDE
Brush one question every day /537 Complex multiplication
Create a slice slice pit using the make method
Machine learning learning notes
And, or, not equal, operator
Visual positioning guidance system for industrial manipulator (robot)
Player actual combat 13 create qtopengl project to promote window control and reload qoopenglwedge
Pay attention to click and pursue more users to enter the website. What bidding strategy can you choose?
Configuring OSPF pseudo connection for Huawei devices
Player practice 15 xdemux and avcodecparameters
Design of PLC intelligent slave station based on PROFIBUS DP protocol
Redis core configuration and advanced data types
Software package for optimization scientific research field