当前位置:网站首页>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!
边栏推荐
- Codeforces Round #798 (Div. 2)(A~D)
- Simple code implementation of addition, subtraction, multiplication and division calculator
- QT database realizes page turning function
- Axi4 increase burst / wrap burst/ fix burst and narrow transfer
- Leetcode 2185. Counts the string containing the given prefix
- Three common methods of C language array initialization ({0}, memset, for loop assignment) and their principles
- Implementation and debug of process hiding under x64
- Player practice 17 xvideowidget
- Player practice 11 audio resampling
- TestEngine with ID ‘junit-vintage‘ failed to discover tests
猜你喜欢

Tcp/ip network communication knowledge record
![[early knowledge of activities] list of recent activities of livevideostack](/img/d8/a367c26b51d9dbaf53bf4fe2a13917.png)
[early knowledge of activities] list of recent activities of livevideostack

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

Huawei equipment is configured with H virtual private network

Implementation and debug of process hiding under x64

C语言中主函数调用另外一个函数,汇编代码理解

In C language, the main function calls another function, which is understood by assembly code

Ppt cannot be opened, always prompt how to fix it

高考回憶錄

Player practice 17 xvideowidget
随机推荐
SystemC time
Visual studio common shortcuts
Write policy of cache
Postgresql14 installation and use tutorial
Soft test (VI) Chrome browser installation selenium IDE
Lua tvalue structure
String concatenation and ternary operators
Player actual combat 23 decoding thread
[MySQL] basic database operation
Two months' experience in C language
QT to realize the simple use of SQLite database
Brush one question every day /537 Complex multiplication
C secret arts script Chapter 2 (detailed explanation of pointers) (Section 3)
Reverse analysis from x86 to x64tips
Mémoire de l'examen d'entrée à l'université
Visual positioning guidance system for industrial manipulator (robot)
【MySQL】数据库基本操作
Llvm pass-- virtual function protection
C secret arts script Chapter 2 (detailed explanation of pointer) (Section 1)
Analysis of two-dimensional array passing as function parameter (C language)