L'auteur qui utilise Spring pour les affaires a étudié «[Introduction à la programmation SpringBoot2](https://www.amazon.co.jp/Spring-Boot-2-Introduction à la programmation-Yano Palmada / dp / 4798053473)» C'est comme une feuille de triche / un mémo de lecture. Le public cible est ceux qui ont appris les bases de Java et n'ont aucune expérience avec Spring Boot - le niveau qui a commencé à étudier les bases. Le langage est Java, L'outil de construction est Maven, Le moteur de modèle est Thymeleaf.
Un framework (groupe) créé en combinant la bibliothèque fournie par Spring Framework et Spring MVC (framework) pour le développement d'applications WEB à grande vitesse.
Puisque cet article est utilisé comme aide-mémoire, il est omis ici.
Groovy est un langage adapté à la réalisation de prototypes en peu de temps avant le développement à grande échelle en Java. Groovy est omis ici. @ RestController Il est utilisé pour construire un système accessible de l'extérieur pour récupérer les informations nécessaires. Utilisations telles que le renvoi des informations nécessaires au format texte ou XML lors de l'accès. @ RequestMapping Cela signifie exécuter cette méthode lors de l'accès à cette adresse. Écrivez comme `@RequestMapping (" / ") ʻet spécifiez le chemin comme argument. Lors de l'accès au chemin spécifié, la méthode avec cette annotation sera exécutée.
SampleController.java
@RestController
public class SampleController {
@RequestMapping("/")
public String index() {
return "Hello SpringBoot World";
}
}
Un moteur de modèle qui peut être utilisé en ajoutant des balises HTML. la caractéristique est,
--Préparation d'un attribut unique de "th: ◯◯" dans la balise
home.html
<body>
<h1>Hello!</h1>
<p class="msg" th:text="${msg}">this is sample.</p>
</body>
Il est possible d'écrire du HTML avec Groovy comme moteur de modèle, mais il est omis ici pour plus de commodité.
[@Controller est décrit au chapitre 3](# -controller)
@ ResponseBody
Pour les méthodes avec «@ ResponseBody», la valeur de retour devient le contenu de la réponse tel quel.
Pour la méthode du contrôleur avec @ RestController
, la valeur de retour sera le contenu sans ajouter @ ResponseBody
.
Les méthodes des classes de contrôleur avec @ Controller
renvoient souvent la classe ModelAndView, sauf lorsque vous devez renvoyer JSON ou XML, vous pouvez ajouter @ ResponseBody
au contrôleur pour le contenu. Il peut se retourner.
Spring Boot utilise le serveur Java intégré pour exécuter l'application, aucun déploiement n'est donc requis. Cela fonctionne bien avec les éléments qui exécutent des programmes à l'intérieur du serveur, tels que les services cloud. Bien qu'il présente l'inconvénient d'augmenter la taille du fichier, il devient de facto le standard du développement Web en Java.
La définition de parent est la suivante
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
La définition des dépendances est la suivante
<dependencies>
<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>
</dependencies>
Les définitions de build et plugin sont les suivantes
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Lorsque vous créez un projet Spring Starter avec Spring Tool Suite (STS), un fichier appelé MyBootAppApplication.java
est créé par défaut.
Si @SpringBootApplication est attaché, ce sera une classe qui sera appelée au démarrage de SpringBoot.
SpringApplication.run, la classe annotée lancera l'application.
"Exécuter" est une méthode pour démarrer une application. Pour les arguments, préparez l'instance Class de la classe à exécuter et les données à transmettre en tant que paramètres.
MyBootAppApplication.java
@SpringBootApplication
public class MyBootAppApplication {
public static void main(String[] args) {
SpringApplication.run(MyBootAppApplication.class, args);
}
}
architecture | rôle |
---|---|
Model | Gérer les données utilisées par l'application |
View | Affichage de l'écran de la poignée |
Controller | Contrôlez l'ensemble du processus |
En utilisant une variable de chemin sous la forme de @RequestMapping (" / {param} ")
, vous pouvez recevoir la valeur passée à la partie de chemin sous l'adresse en tant que variable.
[Qu'est-ce que @RequestMapping](# -requestmapping)
Indique que la valeur est transmise par une variable de chemin.
@RequestMapping("/{num}")
public String index(@PathVariable int num){
int res = 0;
for(int i = 1; i<= num; i++){
res += i;
}
return "total:" + res;
}
Les services REST peuvent également renvoyer des classes en tant que valeurs de retour autres que String. L'instance renvoyée est convertie au format JSON.
//Définissez la classe DataObject séparément
public DataObject index(@PathVariable int id) {
return new DataObject();
}
Lorsque vous utilisez une page Web normale, ajoutez @ Controller
avant la classe de contrôleur.
Dans cet article, je souhaite utiliser Thymeleaf comme modèle, alors ajoutez la dépendance à pom.xml comme suit.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
@ Controller Utilisé pour rendre et afficher des pages HTML à l'aide de modèles.
SampleController.java
@Controller
public class SampleController {
@RequestMapping("/")
public String home(){
return "home";
}
}
Model
est une classe de gestion des données utilisées sur les pages Web.
Les données peuvent être transmises en définissant la valeur utilisée dans le modèle dans ce Modèle
.
Définissez la valeur avec ʻaddAttribute. Spécifiez le nom de la valeur dans le premier argument et la valeur complémentaire dans le deuxième argument. En suivant l'exemple ci-dessous, la valeur de la variable msg peut être récupérée sous la forme
$ {msg}` côté modèle.
La valeur de retour ne peut pas être utilisée comme «Modèle» (car elle ne contient pas d'informations sur le modèle).
@RequestMapping("/{num}")
public String home(@PathVariable int num, Model model) {
...
model.addAttribute("msg", "total:" + res);
return "home";
}
Gérez les données utilisées dans les modèles et les informations sur les vues (noms de modèles, etc.). En renvoyant ce ModelAndView
comme valeur de retour, le modèle défini sera utilisé. Définissez l'objet comme ʻaddObject (String entitySetName, Object entity) , et définissez le nom de la vue à utiliser avec
setViewName (String viewName) `.
@RequestMapping("/{num}")
public ModelAndView index(@PathVariable int num, ModelAndView mav) {
...
mav.addObject("msg", "total:" + res);
mav.setViewName("home");
return mav;
}
Model
Il gère toutes les données utilisées dans le modèle, mais comme il ne contient pas d'informations relatives à la vue, Model
ne peut pas être utilisé comme valeur de retour.
ModelAndView
Gérez toutes les données utilisées dans le modèle et toutes les informations sur la vue. En renvoyant ModelAndView
comme valeur de retour, le modèle défini sera utilisé.
Préparez un formulaire avec <form method =" POST "action =" / ">
, et envoyez POST avec la même destination " / "
. Dans la balise ʻinput type = "text" , la valeur de $ value est affichée dans le champ de saisie comme dans
th: text = "$ {value}" . S'il y a plusieurs arguments pour
@ RequestMapping tels que
@RequestMapping (value =" / ", method = RequestMethod.POST), omettez le nom de l'argument comme
value = "/" pour la destination du mappage. Besoin d'écrire sans. L'exemple a la même adresse et fait la distinction entre «GET» et «POST» pour les méthodes. La valeur envoyée depuis le formulaire est traitée par la méthode d'envoi.
@ RequestParam est une annotation pour spécifier la valeur soumise dans le formulaire, qui transmet la valeur saisie dans le formulaire
name =" text1 " à cet argument
str`.
[Côté Conrotorer]
SampleController.java
@Controller
public class SampleController {
@RequestMapping(value="/", method=RequestMethod.GET)
public ModelAndView index(ModelAndView mav) {
mav.setViewName("form");
mav.addObject("msg", "please put and send your name.");
return mav;
}
@RequestMapping(value="/", method=RequestMethod.POST)
public ModelAndView send(@RequestParam("text1")String str, ModelAndView mav) {
mav.addObject("msg", "Bonjour");
mav.addObject("value", "message");
mav.setViewName("form");
return mav;
}
[Côté modèle]
form.html
<body>
<h1>Sample Form</h1>
<p th:text ="${msg}">Cela remplace msg</p>
<form method="POST" action="/">
<input type="text" name="text1" th:value="${value}"/>
<input type="submit" value="Click" />
</form>
</body>
La valeur soumise à partir du formulaire est reçue par la méthode send
. La méthode a quatre arguments avec @ RequestParam
afin de pouvoir recevoir des valeurs du formulaire. Spécifiez le nom du paramètre avec "valeur" et spécifiez la contrainte nulle de la valeur avec "obligatoire".
[Côté contrôleur]
SampleController.java
@Controller
public class SampleController {
@RequestMapping(value="/", method=RequestMethod.GET)
public ModelAndView index(ModelAndView mav) {
//Demande GET omise
}
@RequestMapping(value="/", method=RequestMethod.POST)
public ModelAndView send(
//Case à cocher: la valeur peut obtenir l'état sélectionné sous forme de valeur booléenne
@RequestParam(value="check1", required=false)boolean check1,
//Bouton radio: transmettez la valeur de l'élément sélectionné en tant que valeur de chaîne, mais null si elle n'est pas sélectionnée
@RequestParam(value="radio1",required=false)String radio1,
//Liste de sélection: lorsqu'un seul élément est sélectionné, la valeur est transmise en tant que valeur de chaîne, mais lorsque plusieurs éléments peuvent être sélectionnés, elle est transmise en tant que tableau de chaînes, et lorsqu'elle n'est pas sélectionnée, elle est nulle.
@RequestParam(value="select1", required=false)String select1,
@RequestParam(value="select2", required=false)String[] select2,
ModelAndView mav) {
String res = "";
//Traitement omis
...
//Incorporer la résolution dans le msg
mav.addObject("msg", res);
mav.setViewName("form");
return mav;
}
}
[Côté modèle]
<body>
<h1>Form Controll Example</h1>
<form method="POST" action="/">
<div>
<input type="checkbox" id="check1" name="check1" />
<label for="check1">Case à cocher</label>
</div>
<div>
<input type="radio" id="radioA" name="radio1" value="male" />
<label for="radioA">Masculin</label>
</div>
<div>
<input type="radio" id="radioB" name="radio1" value="female" />
<label for="radioB">Femme</label>
</div>
<div>
<select id="select1" name="select1" size="4">
<option value="Red">rouge</option>
<option value="Blue">Bleu</option>
<option value="Yellow">Jaune</option>
</select>
<select id="select2" name="select2" size="4" multiple="multiple">
<option value="SmartPhone">téléphone intelligent</option>
<option value="Tablet">Tablette</option>
<option value="Laptop">Portable</option>
</select>
</div>
<input type="submit" value="Click" />
</form>
</body>
Il existe ** forward ** et ** redirect ** pour vous permettre de passer à une autre adresse lorsque vous accédez à une adresse.
[Côté contrôleur]
SampleController.java
@Controller
public class SampleController {
@RequestMapping("/")
public ModelAndView index(ModelAndView mav) {
mav.setViewName("home");
return mav;
}
//"/other"L'adresse elle-même"/"Il est remplacé par, et le contenu affiché est également"/"Devenez une chose.
@RequestMapping("/other")
public String other() {
return "redirect:/";
}
//"/home"Lorsque vous y accédez, le contenu affiché reste le même"/"Montrez des choses.
@RequestMapping("/home")
public String home() {
return "forward:/";
}
}
[Côté modèle]
home.html
<body>
<h1>Home Page</h1>
</body>
Les classes fréquemment utilisées peuvent être utilisées en les décrivant directement dans une expression constante comme une constante "** # nom **". Puisqu'il s'agit d'une constante de classe, elle peut être utilisée en appelant directement des méthodes de classe. Comme "# dates. Méthode de classe". L'exemple suivant
Objet utilitaire | constant |
---|---|
#strings | Constante de classe de chaîne |
#numbers | Constante de classe numérique |
#Bools | Constante de classe booléenne |
#dates | Constante de classe de date |
#objects | Constante de classe d'objets |
#arrays | Constante de classe de tableau |
#lists | Répertorier les constantes de classe |
#sets | Définir la constante de classe |
#maps | Constante de classe de carte |
Utilisez la méthode format
de la constante de classe Date # dates
, créez un objet de classe Date dans le premier argument et spécifiez le format aaaa / MM / jj HH: mm: ss
dans le deuxième argument.
<p th:text="${#dates.format(new java.util.Date(), 'dd/MMM/yyyy HH:mm')}"></p>
En utilisant la méthode formatInteger
de la constante # nombres
de la classe Number, l'entier est affiché comme premier argument et les chiffres du deuxième argument sont affichés, séparés par le troisième argument.
<p th:text="${#numbers.formatInteger(10000000, 3, 'COMMA')}"></p>
Le toUpperCase
de la constante de classe String # strings
est une méthode qui convertit le texte de l'argument en majuscules.
<p th:text="${#strings.toUpperCase('show uppercase')}"></p>
En écrivant comme {param.id}
, vous pouvez recevoir la valeur envoyée sous la forme "id = ○○" et utiliser les paramètres directement dans le modèle sans passer par le contrôleur. Cependant, comme les valeurs obtenues sont des tableaux, les valeurs sont extraites et utilisées.
<!--/?id=hoge&name=Passer comme fuga-->
<p th:text="'from parameter.. id=' + ${param.id[0] + ',name=' + param.name[0]}"></p>
Extrayez la valeur du fichier de propriétés et utilisez-la dans le modèle. La méthode de description est # {spécifier la valeur}
message.properties
article.title=this is home page.
article.message=this message from properties.
<h1 th:text="#{article.title}"></h1>
<p th:text="#{article.message}"></p>
Lorsque vous accédez à /? Id = fuga
, ** / hoge / fuga ** est défini pour le lien.
<p><a href="home.html" th:href="@{/hoge/{id}(id=${param.id})}">link</a></p>
Les expressions variables peuvent utiliser des objets ainsi que des nombres et du texte. La façon de faire est de spécifier un objet et d'utiliser * {valeur}
pour récupérer la valeur dans l'objet sélectionné.
<table th:object="${object}">
<tr><th>ID</th><td th:text="*{id}"></td></tr>
<tr><th>NAME</th><td th:text="*{name}"></td></tr>
<tr><th>MAIL</th><td th:text="*{value}"></td></tr>
</table>
Si vous entourez le texte avant et après avec "|", vous pouvez directement écrire l'expression variable et combiner les chaînes.
<p th:text="|My name is *{name}. Mailaddress is *{value}.|"></p>
Dans Thymeleaf, lors de la sortie de texte en tant qu'expression variable, toutes les balises HTML sont échappées pour des raisons de sécurité, donc
Vous pouvez libérer l'échappement en utilisant th: utext
. Cependant, si la valeur contient une balise HTML, elle fonctionnera telle quelle, donc si vous créez du texte basé sur les informations envoyées par l'utilisateur, vous serez vulnérable aux attaques telles que XSS.
[Côté contrôleur]
@RequestMapping("/")
public ModelAndView index(ModelAndView mav) {
mav.setViewName("home");
mav.addObject("msg", "message 1<hr/>message 2<br/>message3");
return mav;
}
[Côté modèle]
<p th:utext="${msg}">message.</p>
Modifiez le contenu de la sortie en fonction du résultat de la valeur booléenne préparée à l'avance.
[Côté contrôleur]
@RequestMapping("/{id}")
public ModelAndView index(@PathVariable int id,
ModelAndView mav) {
mav.setViewName("check");
mav.addObject("id",id);
mav.addObject("num",id % 2 == 0);
mav.addObject("even","Even number!");
mav.addObject("odd","Odd number...");
return mav;
}
[Côté modèle]
check.html
<p th:class="${num} ? 'even' : 'odd'"></p>
La valeur définie est «true» (nombre différent de zéro, «0», Dans le cas de (y compris du texte autre que des valeurs telles que "off" et "no"), cette balise et les balises qu'elle contient sont affichées.
Si la valeur définie est «false» (y compris du texte tel que le nombre zéro, «0», «off», «no»), cette balise et les balises internes sont affichées.
[Côté contrôleur]
@RequestMapping("/{id}")
public ModelAndView index(@PathVariable int id,
ModelAndView mav) {
mav.setViewName("check");
mav.addObject("id",id);
mav.addObject("num",id >= 0);
mav.addObject("trueVal","POSITIVE!");
mav.addObject("falseVal","negative...");
return mav;
}
[Côté modèle]
check.html
<p th:if="${num}" th:text="${id} + ' is ' + ${trueVal}"></p>
<p th:unless="${num}" th:text="${id} + ' is ' + ${falseVal}"></p>
Vérifie la valeur de l'expression conditionnelle spécifiée, recherche la même valeur à partir du «th: case» à l'intérieur et renvoie uniquement cette balise.
th: case =" * "
est un joker qui attrape tout ce qui ne remplit aucune des conditions.
[Côté contrôleur]
@RequestMapping("/{month}")
public ModelAndView index(@PathVariable int month,
ModelAndView mav) {
mav.setViewName("index");
int m = Math.abs(month) % 12;
m = m == 0 ? 12 : m;
mav.addObject("month",m);
mav.addObject("check",Math.floor(m / 3));
return mav;
}
[Côté modèle]
<div th:switch="${check}">
<p th:case="0" th:text="|${month} - Winter|"></p>
<p th:case="1" th:text="|${month} - Spring|"></p>
<p th:case="2" th:text="|${month} - Summer|"></p>
<p th:case="3" th:text="|${month} - Autumn|"></p>
<p th:case="4" th:text="|${month} - Winter|"></p>
<p th:case="*">...?</p>
</div>
Dans th: each
, préparez un tableau ou une collection en tant que valeur et décrivez-le à la manière d'une instruction for étendue comme value: $ {list}
. Cela récupérera les valeurs dans l'ordre de la liste après les deux points et les assignera aux variables avant les deux points.
[Côté modèle]
<table>
<tr>
<th>NAME</th>
<th>MAIL</th>
<th>TEL</th>
</tr>
<tr th:each="obj:${data}">
<td th:text="${obj[0]}"></td>
<td th:text="${obj[1]}"></td>
<td th:text="${obj[2]}"></td>
</tr>
</table>
Si vous le déclarez sous la forme __ $ {variable} __
, il sera évalué à l'avance et l'expression de variable sera exécutée.
[Côté contrôleur]
ArrayList<Pockemon> monsters = new ArrayList<>();
monsters.add(new Pockemon(0,"Hitokage","Fire"));
monsters.add(new Pockemon(1,"Fushigidane","Grass"));
monsters.add(new Pockemon(2,"Zenigame","Water"));
mav.addObject("num", 1);
mav.addObject("monsters",monsters);
return mav
[Côté modèle]
<div th:object="${monsters.get(${num})}">
<p th:text="*{id}"></p>
</div>
Même si vous ne le préparez pas sous la forme d'attributs comme th: text
(il y a un côté qui n'affecte pas l'affichage de la page même si Thymeleaf ne fonctionne pas), Thymeleaf directement entre les balises HTML Vous pouvez écrire l'expression variable de. Si vous écrivez th: inline =" text "
dans la balise, vous pouvez écrire une expression variable comme [[$ {variable}]]
à l'intérieur pour activer le traitement en ligne.
[Côté contrôleur]
ArrayList<Pockemon> monsters = new ArrayList<>();
monsters.add(new Pockemon(0,"Hitokage","Fire"));
monsters.add(new Pockemon(1,"Fushigidane","Grass"));
monsters.add(new Pockemon(2,"Zenigame","Water"));
mav.addObject("monsters",monsters);
return mav
[Côté modèle]
<tr th:inline="text" th:each="monster : ${monsters}">
<td>[[${monster.id}]]</td>
<td>[[${monster.name}]]</td>
<td>[[${monster.type}]]</td>
</tr>
Spécifiez la valeur <script th: inline =" javascript ">
et ʻinline comme
"javascript" ʻau lieu de"texte"
, et l'expression de variable est` / * [[$ {expression variable}]] ] * / ʻEt en écrivant sous forme de commentaire, il peut être utilisé en l'incorporant dans le script.
python
<script th:inline="javascript">
console.log(/*[[$(variable)]]*/);
</script>
Une méthode appelée ** fragment de modèle ** qui compose une page en combinant plusieurs fichiers. Insérez la partie décrite comme une partie dans le fichier qui peut être coupée et manipulée comme un ** fragment ** à l'emplacement spécifié d'un autre modèle.
[Modèles qui deviennent des pièces]
part.html
<p th:fragment="frag_body">
[Côté incorporation]
<p th:include="part::frag_body">
Dans Spring, JSP et Groovy peuvent également être utilisés comme moteurs de modèles, mais ils sont omis pour plus de commodité.
En Java, DB est utilisé à l'aide de JPA (API de persistance Java Persistence API). Même au printemps, l'accès à la base de données est effectué à l'aide de SpringBootStarterDataJPA.
Si vous gérez votre projet avec Maven, ajoutez la dépendance suivante à pom.xml et utilisez-la.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Lors de l'utilisation de JPA, la partie de données est définie comme une classe appelée ** entité **. Une table est définie dans la base de données et les données y sont stockées sous forme d'enregistrements, mais l'entité peut être considérée comme stockant chacun de ces enregistrements en tant qu'objet Java.
Vous trouverez ci-dessous un exemple de la classe ** Entity ** qui sert de modèle.
@Entity
@Table(name="mydata")
public class MyData {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
private long usrId;
@Column(length = 50, nullable = false)
private String usrName;
@Column(length = 200, nullable = true)
private String usrAddress;
@Column(nullable = true)
private Integer age;
@Column(nullable = true)
private String comment;
public long getUsrId() { return usrId; }
public void setUsrId(long usrId) { this.usrId = usrId; }
public String getUsrName() { return usrName; }
public void setUsrName(String usrName) { this.usrName = usrName; }
public String getUsrAddress() { return usrAddress; }
public void setUsrAddress(String usrAddress) { this.usrAddress = usrAddress; }
public Integer getAge() { return age; }
public void setAge(Integer age) { this.age = age; }
public String getComment() { return comment; }
public void setComment(String comment) { this.comment = comment; }
}
@ Entity
Annotation indiquant qu'il s'agit d'une classe d'entité
@ Table(name="mydata")
Spécifie la table affectée à cette classe d'entité. Si nom
est omis, le nom de la classe sera utilisé comme nom de la table.
@ Id
Spécifier la clé primaire
@ GeneratedValue(strategy = GenerationType.AUTO)
Générez automatiquement une valeur pour le champ de la clé primaire. La méthode de génération est spécifiée dans strategy
, et dans l'exemple, GenerationType.AUTO
et la valeur du type d'énumération sont spécifiées pour être attribuées automatiquement.
@ Column
Spécifiez le nom de colonne attribué au champ. Si «nom» est omis, le nom du champ est utilisé tel quel comme nom de colonne.
@Argument de colonne | La description |
---|---|
name | Spécifier le nom de la colonne |
length | Longueur maximale(Nombre de caractères dans la chaîne)Spécifier |
nullable | Spécifiez s'il faut autoriser null |
Entity-> Une classe qui permet aux données stockées dans des tables d'être traitées comme des objets dans Java Préparé comme une interface de référentiel->, il génère et implémente automatiquement un traitement d'accès à la base de données à usage général, il n'est donc presque pas nécessaire d'écrire du code.
Créé en héritant de JpaRepository @ Repository Indique que cette classe est une classe d'accès aux données.
@Repository
public interface MyDataRepository extends JpaRepository<MyData, Long> {
}
@ Autowired
Dans l'exemple, «@ Autowired» est utilisé pour injecter une instance MyDataRepository dans un champ.
Si vous mettez @ Autowired
devant la variable d'instance, il recherchera la classe correspondante dans les classes avec @ Component
, la renouvellera et la plongera dans le champ. Bien qu'il dise «@ Component», «@ Controller», «@ Repository», «@ Service» sont utilisés correctement en fonction de la couche.
Toutes les entités peuvent être automatiquement récupérées par la méthode fournie dans JpaRepository, qui est la source d'héritage.
@Controller
public class SampleController {
@Autowired
MyDataRepository repository;
@RequestMapping("/")
public ModelAndView home(ModelAndView mav) {
mav.setViewName("home");
Iterable<MyData> list = repository.findAll();
mav.addObject("data", list);
return mav;
}
}
「Create」「Read」「Update」「Delete」 @ ModelAttribute Il est utilisé pour préparer automatiquement une instance de la classe d'entité. Spécifiez le nom de l'instance dans l'argument. Dans la méthode d'index pour l'accès GET, une nouvelle instance est créée et affectée à l'argument de MyData (toutes les valeurs sont des valeurs initiales). Dans la méthode de formulaire appelée par l'accès POST, les valeurs du formulaire soumis sont automatiquement collectées et transmises à l'instance MyData.
repository.saveAndFlush(mydata);
L'entité préparée est spécifiée dans l'argument de la méthode saveAndFlush
fournie dans JpaRepository et est rendue persistante.
@ Transactional
L'annotation «@ Transactional» est pour la fonction de transaction, et en l'attachant à la méthode, l'accès à la base de données exécuté dans la méthode sera exécuté dans un lot.
Dans le cas d'un traitement qui réécrit des données, les transactions sont des traitements importants, par exemple empêcher l'accès à la base de données de l'extérieur et causer des problèmes d'intégrité des données.
L'argument readOnly = false
indique littéralement qu'il est" en lecture seule (non réinscriptible) ".
Lorsque readOnly = false
est défini, la transaction passe d'une transaction en lecture seule à une transaction qui permet la mise à jour des données telle que l'enregistrement.
SampleController.java
@Controller
public class SampleController {
@Autowired
MyDataRepository repository;
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index(@ModelAttribute("formModel") MyData mydata,
ModelAndView mav) {
mav.setViewName("index");
mav.addObject("msg", "this is sample content.");
Iterable<MyData> list = repository.findAll();
mav.addObject("datalist", list);
}
@RequestMapping(value = "/", method = RequestMethod.POST)
@Transactional(readonly = false)
public ModelAndView form(@ModelAttribute("formModel") MyData mydata,
ModelAndView mav){
repository.saveAndFlush(mydata);
return new ModelAndView("redirect:/");
}
}
<body>
<table>
<form method="post" action="/" th:object="${formModel}">
<tr>
<td><label for="name>Nom</label></td>
<td><input type="text" name="name" th:value="*{name}" /></td>
</tr>
<tr>
<td><label for="name>âge</label></td>
<td><input type="text" name="age" th:value="*{age}" /></td>
</tr>
<tr>
<td><label for="name>Email</label></td>
<td><input type="text" name="mail" th:value="*{mail}" /></td>
</tr>
<tr>
<td><label for="name>Note</label></td>
<td><textarea name="memo" th:value="*{memo}" cols="20" rows="5"></textarea></td>
</tr>
</form>
</table>
<hr/>
<table>
<tr>
<th>ID</th>
<th>Nom</th>
</tr>
<tr th:each="obj : ${datalist}">
<td>${obj.id}</td>
<td>${obj.name}</td>
</tr>
<table>
</body>
@ PostConstruct Indique que la méthode est appelée après que le constructeur a créé une instance. Le contrôleur est créé une seule fois au début et l'instance est conservée par la suite.
SampleComtroller.java
@PostConstruct
public void init(){
MyData d1 = new MyData();
d1.setName("tuyano");
d1.setAge(123);
d1.setMail("[email protected]");
d1.setMemo("this is my data!");
repository.saveAndFlush(d1);
MyData d2 = new MyData();
d2.setName("hanako");
d2.setAge(15);
d2.setMail("hanako@flower");
d2.setMemo("my girl friend.");
repository.saveAndFlush(d2);
MyData d3 = new MyData();
d3.setName("sachiko");
d3.setAge(37);
d3.setMail("sachico@happy");
d3.setMemo("my work friend...");
repository.saveAndFlush(d3);
}
【modèle】
Th: object =" $ {formModel} "
est spécifié dans <form>
, mais si l'entité à éditer est définie dans ce formModel
,type = "hidden"
le fera. L'ID est stocké dans le champ masqué.
<body>
<h1 th:text="${title}">Edit page</h1>
<table>
<form method="post" action="/edit" th:object="${formModel}">
<input type="hidden" name="id" th:value="*{id}" />
<tr><td><label for="name">Nom</label></td>
<td><input type="text" name="name" th:value="*{name}" /></td></tr>
<tr><td><label for="age">âge</label></td>
<td><input type="text" name="age" th:value="*{age}" /></td></tr>
<tr><td><label for="mail">Email</label></td>
<td><input type="text" name="mail" th:value="*{mail}" /></td></tr>
<tr><td><label for="memo">Note</label></td>
<td><textarea name="memo" th:text="*{memo}"
cols="20" rows="5"></textarea></td></tr>
<tr><td></td><td><input type="submit" /></td></tr>
</form>
</table>
</body>
Implémentez le processus de recherche et de récupération des entités par ID dans le référentiel.
findById
est une méthode pour récupérer une instance MyData avec un numéro d'identification comme argument.
MyDataRepository.java
@Repository
public interface MyDataRepository extends JpaRepository<MyData, Long> {
public MyData findById(Long name):
}
Dans la méthode d'édition appelée au moment de l'accès GET, l'entité est acquise par «findById» qui prend l'ID envoyé dans la requête comme argument, et «get» est utilisé pour spécifier le nom «formModel» et «addObject». ..
La méthode de mise à jour est appelée lorsque le formulaire est soumis à / edit
. Lors de l'enregistrement d'une entité basée sur les données du formulaire envoyées, mettez-la à jour avec le même saveAndFlush
que lors de l'enregistrement de nouvelles données. La différence entre une nouvelle sauvegarde et une mise à jour est de savoir si un ID est spécifié pour l'entité argument.
SampleController.java
@RequestMapping(value = "/edit/{id}", method = RequestMethod.GET)
public ModelAndView edit(@ModelAttribute MyData mydata, @PathVariable int id, ModelAndView mav) {
mav.setViewName("edit");
mav.addObject("title","edit mydata.");
MyData data = repository.findById((long)id);
mav.addObject("formModel",data.get());
return mav;
}
@RequestMapping(value = "/edit", method = RequestMethod.POST)
@Transactional(readOnly=false)
public ModelAndView update(@ModelAttribute MyData mydata, ModelAndView mav) {
repository.saveAndFlush(mydata);
return new ModelAndView("redirect:/");
}
Il existe une méthode delete
pour GET access to / delete
et une méthode remove
pour gérer l'accès POST.
La méthode delete
recherche l'entité avec l'ID spécifié par findById
et l'affiche. Après cela, l'entité envoyée par la méthode de suppression envoyée par POST est supprimée. N'oubliez pas d'ajouter l'annotation «@ Transactional» à la méthode car «delete» implique également de changer la base de données.
@RequestMapping(value = "/delete/{id}", method = RequestMethod.GET)
public ModelAndView delete(@PathVariable int id, ModelAndView mav) {
mav.setViewName("delete");
mav.addObject("title", "delete mydata.");
MyData data = repository.findById((long)id);
mav.addObject("formModel", data);
return mav;
}
@RequestMapping(value = "/delete", method = RequestMethod.POST)
@Transactional(readOnly = false)
public ModelAndView remove(@RequestParam long id, ModelAndView mav){
repository.delete(id);
return new ModelAndView("redirect:/");
}
JpaRepository a une fonction intégrée de génération de code automatique à l'aide d'un dictionnaire. JpaRepository génère et exécute le texte de requête par JPQL.
findById(argument)
↓
"find" "by" "id"argument
↓
"select *de la table où id=argument"Exécution de la requête
And Il est utilisé lors de la recherche d'un élément qui correspond aux deux valeurs de deux éléments. Préparez deux arguments comme valeur de chaque élément.
findByIdAndName
↓
from MyDataEntity where id = ?1 and name = ?2
Or Il est utilisé lors de la recherche d'un élément qui correspond à l'une des valeurs de deux éléments. Préparez deux arguments comme valeur de chaque élément.
findByIdOrName
↓
from MyDataEntity where id = ?1 or name = ?2
Between Il est utilisé lors du passage de deux arguments en tant que valeurs et lors de la recherche d'une valeur entre eux. Recherchez des éléments dans une certaine plage d'éléments spécifiés.
findByAgeBetween
↓
from MyDataEntity where age between ?1 and ?2
LessThan Recherchez les éléments numériques inférieurs à la valeur spécifiée dans l'argument.
findByAgeLessThan
↓
from MyDataEntity where age < ?1
GreaterThan Recherchez les éléments numériques supérieurs à la valeur spécifiée dans l'argument.
findByAgeGreaterThan
↓
from MyDataEntity where age > ?1
IsNull Recherche un élément spécifié avec une valeur nulle.
findCommentIsNull
↓
from MyDataEntity where comment is null
IsNotNull, NotNull
Recherche la valeur de l'élément spécifié qui n'est pas nulle. Comprendre même avec Not Null
findByCommentNotNull,
findByCommentIsNotNull
↓
from MyDataEntity where comment not null
Like Effectuez une recherche LIKE du texte. Recherche ambiguë d'une valeur à partir d'un élément spécifié. Vous pouvez l'utiliser avec un caractère générique attaché à la valeur transmise à l'argument.
findByNameLike
↓
from MyDataEntity where name like ?1
NotLike Recherche ambiguë de choses qui n'incluent pas la chaîne de recherche. Vous pouvez l'utiliser avec un caractère générique attaché à la valeur transmise à l'argument.
findByNameNotLike
↓
from MyDataEntity where name not like ?1
OrderBy
Précisez la commande. Il est ajouté après le nom de la méthode de recherche normale. Vous pouvez spécifier un ordre croissant ou décroissant en ajoutant ʻAsc ou
Desc` après le nom de l'élément.
findByNameOrderByAgeAsc
↓
from MyDataEntity where name = ?1 order by age Asc
Not Recherchez les éléments dont l'élément spécifié n'est pas égal à la valeur de l'argument.
findByNameNot
↓
from MyDataEntity where name <> ?1
In Rechercher si la valeur de l'élément spécifié correspond à l'une des valeurs fournies dans la collection d'arguments
findByNameIn(Collection<String> name)
↓
from MyDataEntity where name in ?1
NotIn Recherche la valeur de l'élément spécifié qui ne correspond à aucune des valeurs fournies dans la collection d'arguments
findByNameNotIn(Collection<String> name)
↓
from MyDataEntity where name not in ?1
@Repository
public interface MyDataRepository extends JpaRepository<MyData, Long> {
// "%" + str + "%"Vous devez spécifier un caractère générique comme
public List<MyData> findById(Long name);
public List<MyData> findByNameLike(String name);
public List<MyData> findByIdIsNotNullOrderByIdDesc();
public List<MyData> findByAgeGreaterThan(Integer age);
public List<MyData> findByAgeBetween(Integer age1, Integer age2);
}
find [By ○○] [Other search conditions] [OrderBy etc.]
** Toutes les recherches simples sont des méthodes générées automatiquement. Seul le traitement de recherche complexe est défini et utilisé dans DAO **
En préparant à l'avance la validation dans le modèle, des règles sont définies pour chaque élément d'entrée et il est possible de vérifier si la valeur d'entrée est violée. @ Validated Cela vérifiera la valeur de l'entité pour la variation. En ajoutant cela, chaque valeur de l'entité sera vérifiée automatiquement.
@ BindingResult
Le résultat du contrôle de validation est reçu par l'argument suivant, BindingResult
.
Vous pouvez vérifier si une erreur s'est produite avec la méthode hasErrors
. S'il est "vrai", il y a une erreur, et s'il est "faux", il n'y a pas d'erreur, donc dans le cas ci-dessous, le traitement (stockage de données, etc.) quand il n'y a pas d'erreur dans ʻif (! Result.hasErrors ()) `est effectué. ..
if(!result.hasErrors()) {...}
L'expression de variable est définie dans $ {# fields.detailedErrors ()}
dans th: each est un objet qui résume les résultats des contrôles de validation de chaque champ de l'entité dans # fields
, etdetailedErrors. La méthode
renvoie des informations sur l'erreur qui s'est produite sous forme de liste collective. Dans th: each
, les objets d'erreur sont retirés de la liste et définis dans la variable ʻerror`.
<li th:each="error : ${#fields.detailedErrors}" class="err" th:text="${error.message}">
ʻError a une propriété appelée
message, qui vous donne le message de l'erreur qui s'est produite. Il est affiché sous la forme
th: text =" $ {error.message} "`.
【modèle】
<form method="post" action="/" th:object="${formModel}">
<ul>
<li th:each="error : ${#fields.detailedErrors()}"
class="err" th:text="${error.message}" />
</ul>
<tr><td><label for="name">Nom</label></td>
<td><input type="text" name="name"
th:field="*{name}" /></td></tr>
<tr><td><label for="age">âge</label></td>
<td><input type="text" name="age"
th:field="*{age}" /></td></tr>
<tr><td><label for="mail">Email</label></td>
<td><input type="text" name="mail"
th:field="*{mail}" /></td></tr>
<tr><td><label for="memo">Note</label></td>
<td><textarea name="memo" th:field="*{memo}"
cols="20" rows="5" ></textarea></td></tr>
<tr><td></td><td><input type="submit" /></td></tr>
</form>
【entité】
@Entity
@Table(name = "mydata")
public class MyData {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column
@NotNull
private long id;
@Column(length = 50, nullable = false)
@NotEmpty
private String name;
@Column(length = 200, nullable = true)
@Email
private String mail;
@Column(nullable = true)
@Min(0)
@Max(200)
private Integer age;
@Column(nullable = true)
private String memo;
//…… Accessor omis ……
}
【manette】 Un exemple qui vérifie si la valeur d'entrée enfreint le jeu de validation dans l'entité et permet à la valeur d'être stockée uniquement lorsque la règle est satisfaite.
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index(
@ModelAttribute("formModel") MyData mydata,
ModelAndView mav) {
mav.setViewName("index");
mav.addObject("msg","this is sample content.");
mav.addObject("formModel",mydata);
Iterable<MyData> list = repository.findAll();
mav.addObject("datalist",list);
return mav;
}
@RequestMapping(value = "/", method = RequestMethod.POST)
@Transactional(readOnly=false)
public ModelAndView form(
@ModelAttribute("formModel") @Validated MyData mydata,
BindingResult result,
ModelAndView mov) {
ModelAndView res = null;
if (!result.hasErrors()){
repository.saveAndFlush(mydata);
res = new ModelAndView("redirect:/");
} else {
mov.setViewName("index");
mov.addObject("msg","sorry, error is occured...");
Iterable<MyData> list = repository.findAll();
mov.addObject("datalist",list);
res = mov;
}
return res;
}
<input type="text" name="name" th:value="*{name}" th:errorclass="err" />
La propriété name
de l'objet prend la valeurth: value = "* {name}"
. Un attribut appelé «th: errorclass» est fourni pour spécifier le nom de classe à appliquer lorsqu'une erreur se produit. Le traitement est appliqué uniquement lorsqu'une erreur se produit à cause de cela.
<div th:if="${#fields.hasErrors('name')}" th:errors="*{name}" th:errorclass="err">
hasErrors
utilise th: if
pour afficher un doug uniquement lorsque true
, qu'une erreur se soit produite ou non dans le champ spécifié dans l'argument.
Le message d'erreur est affiché en utilisant l'attribut th: errors
, et dans l'exemple,` * {name} ʻest spécifié.
【modèle】
<form method="post" action="/" th:object="${formModel}">
<tr><td><label for="name">Nom</label></td>
<td><input type="text" name="name"
th:value="*{name}" th:errorclass="err" />
<div th:if="${#fields.hasErrors('name')}"
th:errors="*{name}" th:errorclass="err">
</div></td></tr>
<tr><td><label for="age">âge</label></td>
<td><input type="text" name="age"
th:value="*{age}" th:errorclass="err" />
<div th:if="${#fields.hasErrors('age')}"
th:errors="*{age}" th:errorclass="err">
</div></td></tr>
<tr><td><label for="mail">Email</label></td>
<td><input type="text" name="mail"
th:value="*{mail}" th:errorclass="err" />
<div th:if="${#fields.hasErrors('mail')}"
th:errors="*{mail}" th:errorclass="err">
</div></td></tr>
<tr><td><label for="memo">Note</label></td>
<td><textarea name="memo" th:text="*{memo}"
cols="20" rows="5" ></textarea></td></tr>
<tr><td></td><td><input type="submit" /></td></tr>
</form>
Annotation de validation | Contenu |
---|---|
@ Null | Vérifiez que la valeur est nulle |
@ NotNull | Ne pas autoriser la valeur à être nulle |
@ Min(int num) | Spécifiez la valeur minimale qui peut être saisie dans l'élément pour saisir une valeur numérique (entier) |
@ Max(int num) | Spécifiez la valeur maximale qui peut être saisie dans l'élément pour saisir une valeur numérique (entier) |
@ DecimalMin(String num) | BigDecimal,BigInteger,Spécifier la valeur minimale lors de la définition de la valeur avec la valeur de chaîne int est également OK |
@ DecimalMax(String num) | BigDecimal,BigInteger,Spécifier la valeur maximale lors de la définition de la valeur avec la valeur de chaîne int est également OK |
@ Degits(integer=5, fraction=10) | Limitation du nombre de chiffres dans la partie entière et la partie fractionnaire |
@ Future | N'acceptez que les dates et heures futures du présent |
@ Past | N'acceptez que les routes passées du présent |
@ Size(min=1, max=10) | Spécifiez le nombre d'éléments stockés d'objets tels que des chaînes et des classes de collection en plus de String |
@ Pattern(regexp="[a-zA-Z]+") | Vérifiez l'entrée en spécifiant le modèle d'expression régulière |
Annotation de validation | Contenu |
---|---|
@ NotEmpty | Les caractères nuls ou vides ne sont pas autorisés |
@ Length(min=5, max=10) | Une annotation qui spécifie la plage de longueurs de chaîne utilisée pour Stringt |
@ Range | Il est utilisé dans l'élément numérique pour spécifier la plage de la valeur minimale et de la valeur maximale.@Avec Min@Max peut être mis en place |
Vérifiez si la valeur saisie est une adresse e-mail | |
@ CreditCardNumber | Il est utilisé pour les éléments saisis numériquement sous forme de valeurs numériques ou de valeurs de chaîne pour vérifier si elles sont au format numérique Creca. |
@ EAN | Norme de numéro d'identification de code à barres |
Comment personnaliser le message d'erreur affiché en anglais
Spécifiez le message d'affichage à l'aide de la valeur message
lors de la préparation d'une annotation pour validation dans la classe d'entité
@NotEmpty(message="Pas de blancs")
@Email(message="Adresse e-mail uniquement")
@Min(value=0, message="Zéro ou supérieur")
@Max(value=200, message="200 ou moins")
La maintenabilité étant médiocre dans le développement réel, les messages doivent être gérés en préparant un fichier de propriétés. Il peut être géré en créant un fichier texte avec le nom "ValidationMessages.properties" dans le dossier de ressources.
Pour votre propre travail de Varidata
La classe d'annotation est
Créez une classe de type d'annotation qui décrit le nom après @ interface
La classe de validation est définie en implémentant l'interface javax.validation.ConstraintValidator. ConstraintValidator
a deux méthodes, ʻinitialize et ʻisValid
, et les implémente pour décrire le traitement nécessaire.
Méthode d'initialisation La classe d'annotation spécifiée par le type générique est passée en argument Obtenez des informations sur les annotations au besoin
La pièce à valider
La valeur saisie (String) et l'instance ConstraintValidator
sont passées en arguments.
Vérifiez la valeur ici et renvoyez la valeur booléenne
selon que la validation est correcte ou non.
[Classe d'annotation]
@Documented
@Constraint(validatedBy = PhoneValidator.class)
@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
@ReportAsSingleViolation
public @interface Phone {
String message() default "Please input a phone number.";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() dedault {};
}
[Classe de validation]
public class PhoneValidator implements ConstraintValidator<Phone, String> {
@Override
public void initialize(Phone phone){
}
@Override
public boolean isValid(String input, ConstraintValidatorContext cxt){
if(input == null){
return false;
}
return input.matches("[0-9()-]*");
}
}
En préparant un référentiel, l'accès à la base de données est possible avec presque aucune écriture de code, mais il y a une limite, alors considérez comment utiliser la fonction d'accès à la base de données fournie par SpringDataJPA à partir de l'application Spring Boot.
DataAccessObject Lorsque vous utilisez DB, lorsque vous accédez à la page pour afficher les données, préparez le processus pour récupérer les données dans le gestionnaire de requêtes du contrôleur et les afficher dans la vue. En d'autres termes, préparez le traitement d'accès à la base de données nécessaire pour chaque gestionnaire de requêtes du contrôleur.
Si vous écrivez un processus pour chaque demande, le contrôleur deviendra gonflé, donc séparez l'accès aux données et la logique. Par conséquent, préparez un objet appelé DAO (Data Access Object) qui permet d'accéder à la base de données. Appelez-les depuis le contrôleur et effectuez le traitement nécessaire.
ʻEn préparant un champ pour stocker la classe EntityManager`, il fournit les fonctions requises pour utiliser l'entité.
Query
est un objet qui a une fonction équivalente à une seule phrase de requête pour interroger des données avec SQL.
La requête JPQL est une instance Query
Lorsque createQuery
de EntityManager est appelé en spécifiant une phrase de requête par JPQL comme argument, une instance de requête pour exécuter la requête est générée.
Qu'est-ce que l'exemple from MyData
? Une phrase de requête JPQL équivalente à select * from mydata
Query query = entityManager.createQuery("from MyData");
La méthode getResultList
de la requête créée vous permet d'obtenir le résultat de l'exécution en tant qu'instance dans la requête.
List<MyData> list = query.getResultList();
@ SuppressWarnings
Dans l'exemple, l'annotation attachée à la variable list
supprime l'avertissement au moment de la compilation. En utilisant «décroché» comme argument, il est vérifié si la valeur de retour de la méthode est obtenue comme valeur du type de la variable de destination de stockage. Cela n'a rien à voir avec le comportement lui-même, ** pour éviter les avertissements au moment de la construction **
@SuppressWarnings("unchecked")
[Interface DAO]
public interface MyDataDao <T> extends Serializable {
public List<T> getAll();
}
[Classe d'implémentation DAO]
@Repository
public class MyDataDaoImpl implements MyDataDao<MyData> {
private static final long serialVersionUID = 1L;
private EntityManager entityManager;
public MyDataDaoImpl(){
super();
}
public MyDataDaoImpl(EntityManager manager){
this();
entityManager = manager;
}
@Override
public List<MyData> getAll() {
Query query = entityManager.createQuery("from MyData");
@SuppressWarnings("unchecked")
List<MyData> list = query.getResultList();
entityManager.close();
return list;
}
}
Créez un contrôleur qui utilise une entité dans DAO.
@ PersistenceContext
@ PersistenceContext
récupère le Bean de ʻEntityManager et le définit dans le champ. Dans Spring Boot, ʻEntityManager
est automatiquement enregistré en tant que bean, alors attribuez-le au champ du contrôleur avec @ PersistenceContext
.
La liaison de bean utilisant @ PersistenceContext
ne peut être placée que jusqu'à" ** 1 instance par classe ** "
@PersistenceContext
EntityManager entityManager;
La liste est acquise à partir de l'entité via DAO et l'objet de liste est passé au côté modèle en même temps que la définition du nom de modèle de la vue. Si vous assemblez le processus d'accès pour l'entité dans DAO, vous pouvez facilement appeler le processus d'accès côté contrôleur.
Iterable<MyData> list = dao.getAll();
mav.addObject("datalist", list);
public class SampleController {
//Dépôt
@Autowired
MyDataRepository repository;
//entité
@PersistenceContext
EntityManager entityManager;
// DAO
MyDataDaoImpl dao;
@PostConstruct
public void init() {
dao = new MyDataDaoImpl(entityManager);
MyData md = new MyData():
md.setHoge("fuga");
md.setNumber(123);
repository.saveAndFlush(md);
}
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index() {
mav.setViewName("index");
mav.addObject("msg", "Ceci est un exemple de MyData.");
Iterable<MyData> list = dao.getAll();
mav.addObject("datalist", list);
return mav;
}
}
[Interface DAO]
public interface MyDataDao<T> extends Serializable {
public List<T> getAll();
//Recherche et renvoie une entité avec un ID comme argument
public T findById(long id);
//Rechercher et renvoyer une entité par son nom
public List<T> findByName(String name);
}
[Classe d'implémentation DAO]
" from MyData where id = "
-> Requête JPQL (récupère l'entité avec l'ID comme argument)
getSingleResult
récupère et retourne une seule entité obtenue à partir de Query
Pour des choses comme ** une seule entité est recherchée ** (comme ID), il est préférable de renvoyer l'entité obtenue telle quelle plutôt que de la renvoyer sous forme de liste.
@Override
public MyData findById(long id) {
return (MyData)entityManager.createQuery("from MyData where id = "
+ id).getSingleResult();
}
" from MyData where name = "
-> Requête JPQL (récupère l'entité avec le nom comme argument)
getResultList
renvoie une liste, donc findByName
aList <MyData>
comme type de retour.
@SuppressWarnings("unchecked")
@Override
public List<MyData> findByName(String name) {
return (List<MyData>)entityManager.createQuery("from MyData where name = "
+ name).getResultList();
}
JPQL est un langage simple qui permet à JPA de générer des requêtes SQL et d'exploiter des bases de données en exécutant des instructions de requête similaires aux requêtes SQL.
HttpServletRequest
Nous avons utilisé @ RequestParam
comme argument lors de la réception et du traitement d'une valeur soumise, comme une méthode qui reçoit un formulaire avec POST
, mais vous pouvez également utiliser HttpServletRequest
comme argument.
En fait, le paramètre de @ RequestParam
est celui qui appelle getParameter
de HttpServletRequest
et effectue automatiquement l'opération pour recevoir le paramètre et définit le résultat comme un argument.
HttpServletResponse
peut également être spécifié comme argument
@RequestMapping(value = "/find", method = RequestMethod.POST)
public ModelAndView search(HttpServletRequest request,
ModelAndView mav) {
mav.setViewName("find");
String param = request.getParameter("fstr");
if (param == ""){
mav = new ModelAndView("redirect:/find");
} else {
mav.addObject("title","Find result");
mav.addObject("msg","「" + param + "Résultats de recherche");
mav.addObject("value",param);
List<MyData> list = dao.find(param);
mav.addObject("datalist", list);
}
return mav;
}
Tout ce qui est écrit dans l'instruction de requête JPQL dans un format tel que : fstr
dans la requête" " de MyData où id =: fstr "
"est traité comme une ** variable de paramètre **.
Le paramètre setParameter
suivant de l'instance Query
définit la valeur du deuxième argument sur la variable du premier argument et attribue la valeur au précédent: fstr
pour créer une requête.
[Interface DAO]
public List<T> find(String fstr);
[Classe d'implémentation DAO]
@Override
public List<MyData> find(String fstr){
List<MyData> list = null;
String qstr = "from MyData where id = :fstr";
Query query = entityManager.createQuery(qstr)
.setParameter("fstr", Long.parseLong(fstr));
list = query.getResultList();
return list;
}
Vous pouvez définir plusieurs paramètres dans une requête en connectant setParameter
(renvoyant une instance de requête avec des paramètres déjà définis) dans une chaîne de méthodes.
String qstr = "from MyData where id = :fid or name like :fname or mail like :fmail";
Long fid = 0L;
Query query =
entityManager.createQuery(qstr).setParameter("fid", fid)
.setParameter("fname", "%" + fstr + "%")
.setParameter("fmail", fstr + "@%");
Certaines variables de paramètres à incorporer dans la requête définissent leurs valeurs en spécifiant un nombre. Définissez l'intégration des paramètres en spécifiant un nombre après "**? **" comme "? 1`
String qstr = "from MyData where id = ?1 or name like ?2 or mail like ?3";
Long fid = 0L;
Query query = entityManager.createQuery(qstr).setParameter(1, fid)
.setParameter(2, "%" + fstr + "%")
.setParameter(3, fstr + "@%");
Les requêtes nommées peuvent être créées en utilisant @ NamedQuery
. Ajouter à la déclaration de classe d'entité
Nommez et définissez la chaîne de requête
@Entity
@NamedQuery(
name = "findWithName",
query = "from MyData where name like :fname"
)
@Table(name = "mydata")
public class MyData {
...
}
Utilisez @ NamedQueries
pour combiner plusieurs requêtes
Vous pouvez ajouter @ NamedQuery
autant de fois que vous le souhaitez, séparés par des virgules.
@NamedQueries (
@NamedQuery(
name="findWithName",
query="from MyData where name like :fname"
)
)
createNamedQuery
obtient une requête avec ce nom en spécifiant le nom de l'annotation de requête dans le texte comme argument, et crée une instance Query
.
Placez la requête dans la classe d'entité, détachée du code DAO à l'aide d'une requête nommée
-> Lorsqu'il s'agit de plusieurs entités, il est facile à comprendre en mettant des requêtes avec la même fonction dans chacune avec le même nom
Query query = entityManager
.createQuery("findWithName")
.setParameter("fname", "%" + fstr + "%");
Puisqu'il est absurde de réécrire l'entité à chaque fois que la fonction de recherche est étendue, je souhaite préparer une requête du côté qui exécute réellement l'accès à la base de données.
Les requêtes peuvent être déclarées avec @ Query
dans l'interface qui sera le référentiel
@ Query
utilisera la requête spécifiée lors de l'appel de la méthode qui décrit l'annotation
@Repository
public interface MyDataRepository extends JpaRepository<MyData, Long> {
@Query("SELECT d FROM MyData d ORDER BY d.name")
List<MyData> findAllOrderByName();
}
Essayez d'appeler le référentiel pour exécuter la requête à partir du contrôleur Il n'y a pas de différence interne car le lieu de préparation de la requête est DAO ou le référentiel.
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index(ModelAndView mav) {
mav.setViewName("index");
mav.addObject("title","Find Page");
mav.addObject("msg","Ceci est un exemple de MyData.");
Iterable<MyData> list = repository.findAllOrderByName(); //dao.getAll();
mav.addObject("datalist", list);
return mav;
}
Si vous souhaitez effectuer une recherche détaillée, vous devrez inclure la valeur de la condition de recherche dans la requête. Dans ce cas, les paramètres peuvent être préparés dans le texte de requête défini dans l'annotation de requête.
@NamedQuery (
name = "findByAge",
query = "from MyData where age > :min and age < :max"
)
Préparez @ NamedQuery
de cette manière avant la classe d'entité et appelez-la depuis DAO en transmettant la valeur au paramètre intégré dans la requête.
Essayez d'appeler findByAge
depuis DAO
Pour créer une instance Query
, utilisez createNamedQuery
comme argument et spécifiez le nom de la requête.
Utilisez ensuite setParameter
pour passer la valeur au paramètre du texte de requête préparé dans @ NamedQuery
.
Recherchez ensuite l'entité avec getResultList
public List<MyData> findByAge(int min, int max);
@suppresswarning
@Override
public List<MyData> findByAge(int min, int max) {
return (List<MyData>) entityManager
.createNamedQuery("findByAge")
.setParameter("min", min)
.setParameter("max", max)
.getResultList();
}
Lorsque vous utilisez @ Query
, la méthode pour incorporer une variable dans le texte de la requête et la spécifier avec l'argument de la méthode est la même.
Cependant, utilisez @ Param
pour spécifier quelle variable est associée à quel paramètre
Vous trouverez ci-dessous un exemple lorsque le findByAge
ajouté à @ NamedQuery
est imprimé dans le référentiel.
[Interface du référentiel]
@Query("from MyData where age > :min and age < :max")
public List<MyData> findByAge(@Param("min") int min, @Param("max") int max);
Le fait d'avoir la requête dans l'entité elle-même ou de la préparer dans le référentiel dépend de la conception de l'application.
Il existe également une fonction pour accéder à la base de données par chaîne de méthodes sans utiliser un langage comme JPQL-> Criteria API L'API Criteria utilise une combinaison de trois classes
classe | Ce que tu peux faire |
---|---|
CriteriaBuilder | Gérer la génération de requêtes |
CriteriaQuery | Exécution de la requête |
Root | Vous pouvez restreindre les entités d'ici par la racine de l'entité recherchée |
① Acquisition de Criteria Builder
Préparez une instance de CriteriaBuilder
et appelez ʻEntityManager # getCriteriaBuilder`
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
② Création de requêtes de critères Ne prenez pas une instruction de requête comme argument Spécifiez la propriété de classe d'une entité spécifique comme argument pour accéder à cette entité
CriteriaQuery <Entity> query = builder.createQuery(Entity.class);
③ Acquisition de Root Obtenir la racine avec la méthode from de CriteriaQuery Spécifiez la propriété Class de l'entité à rechercher dans l'argument
Root <Entity> root = query.from(Entity.class);
④ Exécution de la méthode CriteriaQuery
Appel d'une méthode pour restreindre les entités avec CriteriaQuery
Appelez une chaîne de méthodes au besoin
query.select(root);
⑤ Créez une requête pour obtenir le résultat
Enfin, générez une requête avec createQuery
et obtenez le résultat List
avec getResultList
.
Spécifier QriteriaQuery
comme argument de createQuery
est différent du traitement de la recherche par une requête normale.
List<Entity> list = (List<MyData>)entityManager
.createQuery(query)
.getResultList();
return list;
Voici un exemple pour obtenir toutes les entités par la méthode getAll
.
Spécifiez MyData.class comme argument de la méthode from
pour obtenir la racine
Vous pouvez obtenir une instance racine qui contient toutes les données MyData comme informations
Après avoir obtenu la racine, pour obtenir toutes mes données, appelez avec CriteriaQuery # select
comme argument et spécifiez MyData.class.
Après cela, si vous createQuery
this CriteriaQuery
et getResult
, vous pouvez obtenir tous les Mydata.
@Override
public List<MyData> getAll() {
List<MyData> list = null;
CriteriaBuilder builder =
entityManager.getCriteriaBuilder();
CriteriaQuery<MyData> query =
builder.createQuery(MyData.class);
Root<MyData> root = query.from(MyData.class);
query.select(root);
list = (List<MyData>)entityManager
.createQuery(query)
.getResultList();
return list;
}
Seules les entités dont le texte d'argument et la valeur de nom correspondent sont recherchées.
Après avoir acquis l'instance racine, effectuez un traitement pour restreindre les entités à récupérer.
Après select (root)
, utilisez la chaîne de méthodes pour affiner les entités en utilisant la méthode where
avec Expression (qui gère l'évaluation de diverses expressions) comme argument.
Méthode ʻEqual Vérifie s'ils sont égaux par l'expression et l'objet spécifiés dans l'argument, et retourne le résultat comme une instance de la classe
Predicate. Puisque
Predicate a le rôle d'exprimer les conditions et les expressions spécifiées dans la méthode en tant qu'objets, par exemple, dans le cas de ʻequal
, Predicate
indiquant les conditions qui sont les mêmes que celles spécifiées dans l'argument est préparé, et les entités qui correspondent aux conditions sont réduites.
// where(Expression<boolen>)
// equal(Expression, Object)
query.select(root)
.where(builder.equal(root.get("name"), fstr));
Méthode | Format | La description |
---|---|---|
equal | equal(Expression> x, Expression> y) | Créez un prédicat pour vérifier que les arguments sont égaux. |
gt | gt(Expression<? extends java.lang.Number> x, Expression<? extends java.lang.Number> y) | Créez un prédicat pour vérifier si le premier argument est supérieur au deuxième argument. |
greaterThan | greaterThan(Expression<? extends Y> x, Expression<? extends Y> y) | Créez un prédicat pour vérifier si le premier argument est supérieur au deuxième argument. |
ge | ge(Expression<? extends java.lang.Number> x, Expression<? extends java.lang.Number> y) | Créez un prédicat pour vérifier si le premier argument est supérieur ou égal au second. |
greaterThanOrEqualTo | greaterThanOrEqualTo(Expression<? extends Y> x, Expression<? extends Y> y) | Créez un prédicat pour vérifier si le premier argument est supérieur ou égal au second. |
lt | lt(Expression<? extends java.lang.Number> x, Expression<? extends java.lang.Number> y) | Créez un prédicat pour vérifier si le premier argument est inférieur au second. |
lessThan | Predicate | lessThan(Expression<? extends Y> x, Y y) |
le | le(Expression<? extends java.lang.Number> x, java.lang.Number y) | Créez un prédicat pour vérifier si le premier argument est inférieur ou égal au deuxième argument. |
lessThanOrEqualTo | lessThanOrEqualTo(Expression<? extends Y> x, Y y) | Créez un prédicat pour vérifier si le premier argument est inférieur ou égal au deuxième argument. |
between | between(Expression<? extends Y> v, Expression<? extends Y> x, Expression<? extends Y> y) | Créez un prédicat pour vérifier que le premier argument est une valeur entre les deuxième et troisième arguments. |
isNull | isNull(Expression<?> x) | Créez un prédicat qui vérifie si l'expression est nulle. |
isNotNull | isNotNull(Expression<?> x) | Créez un prédicat qui vérifie si l'expression n'est pas nulle. |
isEmpty | isEmpty(Expression |
Créez un prédicat pour vérifier si la collection est vide. |
isNotEmpty | isNotEmpty(Expression |
Créez un prédicat pour vérifier que la collection n'est pas vide. |
like | like(Expression<java.lang.String> x, Expression<java.lang.String> pattern) | Créez un prédicat qui vérifie si l'expression satisfait le modèle donné. |
and | and(Expression<java.lang.Boolean> x, Expression<java.lang.Boolean> y) | Crée le produit logique d'une expression booléenne donnée. |
or | or(Expression<java.lang.Boolean> x, Expression<java.lang.Boolean> y) | Crée la somme logique des expressions booléennes données. |
not | not(Expression<java.lang.Boolean> restriction) | Refusez la limitation donnée. |
Le résultat récupéré utilise la méthode ʻorderBy pour obtenir l'entité en tant que
List L'argument ʻExpression
utilise CriteriaBuilder # get
pour spécifier le chemin qui indique la propriété de l'entité.
L'argument de ʻorderBy` dans les ensembles d'exemples Predicate pour trier les éléments de nom par ordre croissant.
query.select(root).orderBy(builder.asc(root.get("name")));
La méthode get de l'entité de la requête est [getSingleResult](ajoute une méthode de recherche à ### DAO) qui ne renvoie qu'une seule entité et [getResultList](### obtient le résultat de Query) qui renvoie toutes les entités sous forme de liste. y a-t-il Lorsque vous utilisez réellement le DB, vous pouvez également spécifier la position et le numéro pour l'obtenir.
Spécifiez une valeur entière pour l'argument La position d'acquisition commence par 0 dans la liste.
query.setFirstResult(int pos);
Spécifiez le numéro à acquérir Seul le nombre maximum pouvant être obtenu est défini, donc s'il n'y a pas assez d'entités, seules certaines seront récupérées.
@Override
public List<MyData> getAll() {
int offset = 1; //Spécifier la position d'extraction
int limit = 2; //Précisez le numéro à retirer
List<MyData> list = null;
CriteriaBuilder builder =
entityManager.getCriteriaBuilder();
CriteriaQuery<MyData> query =
builder.createQuery(MyData.class);
Root<MyData> root =
query.from(MyData.class);
query.select(root);
list = (List<MyData>)entityManager
.createQuery(query)
.setFirstResult(offset)
.setMaxResults(limit)
.getResultList();
return list;
}
Dans une base de données où plusieurs tables fonctionnent les unes par rapport aux autres, les entités sont liées et traitées par une fonction appelée «association». -> Avoir une autre entité comme propriété de la classe
@ OneToOne Indique une correspondance biunivoque entre deux entités @ OneToMany Le multiple de l'autre entité correspond à une entité @ ManyToOne Pour plusieurs entités, une seule des autres entités correspond @ ManyToMany Relations dans lesquelles plusieurs autres entités correspondent à plusieurs entités
L'exemple MsgData
permet à un membre de publier n'importe quel nombre de messages, donc
Associé à MyData
dans @ ManyToOne
[Entité associée]
@Entity
@Table(name = "msgdata")
@Getter
@Setter
public class MsgData {
@Id
@Column
@NotNull
private long id;
@Column
private String title;
@Column(nullable = false)
@NotEmpty
private String message;
@ManyToOne
private MyData mydata;
//Ci-dessous, le constructeur et l'accesseur sont omis.
}
[Entité associée] Ajouter la propriété msgdatas à associer à MsgData
@Entity
@Table(name = "mydata")
@Getter
@Setter
public class MyData {
@OneToMany(cascade = CascadeType.ALL)
@Column(nullable = true)
private List<MsgData> msgdatas;
}
Dans le référentiel «save», lors de l'enregistrement, s'il y a un champ associé à une autre entité, l'instance est acquise en fonction des informations envoyées et définie automatiquement. Par conséquent, il n'est pas nécessaire que le programmeur mette en œuvre le processus d'enregistrement des enregistrements associés en tenant compte de la coopération des entités.
repository.saveAndFlush(msgdata);
<Points de coopération des entités>
En logique métier, la partie qui est mise en composants pour pouvoir y accéder depuis l'application est généralement appelée «** couche de service **», et contrairement à DAO qui utilise des contrôleurs et des modèles, c'est une classe qui peut être appelée et utilisée de n'importe où.
Ce qui peut être librement appelé à la fois à partir du contrôleur et de la logique métier (modèle) est ** service **
Spring Framework peut être utilisé à tout moment en enregistrant simplement ce service en tant que bean et en écrivant des annotations.
○ Couche d'application
·manette
Gestionnaire de demande
·modèle
Logique métier
entité
○ Couche de domaine
·un service
・ Dépôt
@ Service Une annotation pour enregistrer cette classe en tant que service, et la classe de service place cette annotation avant le nom de la classe.
@ PersisitenceContext
C'est pour assigner automatiquement le Bean de ʻEntityManager, et il est également possible de préparer et d'utiliser ʻEntityManager
dans le service plutôt que du côté de la classe du contrôleur.
@Service
public class MyDataService {
@PersistenceContext
private EntityManager entityManager;
@SuppressWarnings("unchecked")
public List<MyData> getAll() {
return (List<MyData>) entityManager
.createQuery("from MyData").getResultList();
}
public MyData get(int num) {
return (MyData)entityManager
.createQuery("from MyData where id = " + num)
.getSingleResult();
}
public List<MyData> find(String fstr) {
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<MyData> query = builder.createQuery(MyData.class);
Root<MyData> root = query.from(MyData.class);
query.select(root).where(builder.equal(root.get("name"), fstr));
List<MyData> list = null;
list = (List<MyData>) entityManager.createQuery(query).getResultList();
return list;
}
}
Accès à la base de données depuis DAO à l'aide du bean de service
Utiliser le service créé comme un bean avec @ Autowired
en association avec le contrôleur
La classe de service dans laquelle «@ Service» est décrit est beanisée dans l'application et affectée au champ par «@ Autowired».
@Controller
public class SampleController {
@Autowired
MyDataRepository repository;
//Associer un bean de service à un champ
@Autowired
private MyDataService service;
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index(ModelAndView mav) {
mav.setViewName("index");
mav.addObject("title","Find Page");
mav.addObject("msg","Ceci est un exemple de MyData.");
//Obtenez toutes les entités
List<MyData> list = service.getAll();
mav.addObject("datalist", list);
return mav;
}
// "/find"GET gestionnaire de requêtes omis
@RequestMapping(value = "/find", method = RequestMethod.POST)
public ModelAndView search(HttpServletRequest request,
ModelAndView mav) {
mav.setViewName("find");
String param = request.getParameter("fstr");
if(param == "") {
mav = new ModelAndView("redirect:/find");
} else {
mav.addObject("title", "Find result");
mav.addObject("msg", "「" + param + "Résultats de recherche");
mav.addObject("value", param);
//Rechercher des entités
List<MyData> list = service.find(param);
mav.addObject("datalist", list);
}
return mav;
}
//Le constructeur, l'accesseur, etc. sont omis ci-dessous.
}
"** Service " dans le développement d'applications Web signifie généralement " Programme Web accessible de l'extérieur et recevant les informations nécessaires **" Il existe des services REST au format JSON et au format XML qui peuvent être utilisés de l'extérieur.
@RestController
public class MyDataRestController {
@Autowired
private MyDataService service;
@RequestMapping("/rest")
public List<MyData> restAll() {
return service.getAll();
}
@RequestMapping("/rest/{num}")
public MyData restBy(@PathVariable int num) {
return service.get(num);
}
}
Lors de la manipulation avec XML dans RestController, préparez une bibliothèque "Jackson DataFormat XML" qui analyse et traite le format des données.
@ XmlRootElement
Indique qu'il s'agit de l'élément racine des données XML. Request handler restAll La seule différence est qu'il renvoie l'objet avec ʻou
restByet est normalement converti au format JSON, et si
@ XmlRootElement` est attaché, il est converti au format XML.
Si vous utilisez Maven
pom.xml
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
** Les composants ** sont des beans générés automatiquement dans votre application, et les instances de bean peuvent être utilisées en liant avec @ Autowired
.
Un service est un type de composant-> un composant de la couche service est appelé un ** service **
@ Component Les annotations font connaître la classe à laquelle elle est attachée à l'application en tant que composant. Les instances de classe seront désormais enregistrées en tant que beans
Si le constructeur a @ Autowired
attaché, le constructeur avec this @ Autowired
créera l'instance lorsque l'instance de cette classe est enregistrée en tant que bean.
Si le constructeur avec @ Autowired
n'est pas préparé dans la classe de composant, une erreur se produira lors de l'exécution de l'application et le démarrage échouera, alors assurez-vous de le préparer.
L'argument d'instance de MySampleBean (ApplicationArguments args)
est un objet qui gère l'argument passé lorsque l'application est exécutée, c'est-à-dire lorsque SpringApplication.run
est exécuté dans la classe avec @ SpringBootApplication
spécifié.
Préparez cette instance en tant qu'argument lors de l'utilisation de l'argument passé à l'exécution
Dans l'exemple de méthode, utilisez ʻApplicationArgments # getNonOptionArgs pour extraire l'argument d'exécution de l'application en tant que
List`.
@Component
public class MySampleBean {
private int max = 10;
@Autowired
public MySampleBean(ApplicationArguments args) {
List<String> files = args.getNonOptionArgs();
try {
max = Integer.parseInt(files.get(0));
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
public int count() {
counter++;
counter = counter > max ? 0 : counter;
return counter;
}
}
Ajouter un gestionnaire de requêtes à la classe de contrôleur pour tirer parti du composant
Si vous l'associez à un champ avec @ Autowired
, il sera automatiquement lié, vous pouvez donc exécuter bean.count
dans le gestionnaire de requêtes.
Les composants peuvent être librement utilisés de n'importe où en les associant à des champs avec @ Autowired
.
S'il y a une fonction à usage général à appeler à partir de plusieurs gestionnaires de requêtes, il est bon de la résumer pour le moment
@Autowired
MySampleBean bean;
@RequestMapping("/count")
public int count() {
return bean.count();
}
De plus, «@ Controller» est un composant qui joue le rôle d'un contrôleur, «@ Repository» est un type de composant auquel un rôle spécial est attribué pour l'accès aux données, et «@ Component» a un tel rôle spécial. Peut être attaché à quelque chose qui ne l'est pas
Dans Spring, vous pouvez lier un bean préparé en standard à l'aide d'une annotation telle que @ Autowired
, ou créer votre propre ** composant ** ou ** service ** et l'utiliser comme un bean.
Les beans peuvent être utilisés à divers endroits tels que les contrôleurs en utilisant la ** classe de configuration **
En fait, en raison de l'idée de Spring Boot de ** du fichier de configuration à l'annotation **, la méthode de ** création d'un fichier de configuration ** n'est pas recommandée.
Si vous ajoutez @ Configuration
même à une classe générale qui n'hérite pas d'une classe spéciale, cette classe sera instanciée en tant que classe de configuration au démarrage de l'application, et les beans etc. qui y sont décrits seront enregistrés dans l'application.
[Classe de configuration avec des beans enregistrés dans le champ]
@Configuration
public class MyBootAppConfig {
@Bean
MyDataBean myDataBean(){
return new MyDataBean();
}
}
Si vous préparez une méthode qui retourne une instance de la classe avec @ Bean
dans la classe de configuration, elle sera enregistrée en tant que bean.
[Classe Bean d'origine]
public class MyDataBean {
@Autowired
MyDataRepository repository;
public String getTableTagById(Long id){
Optional<MyData> opt = repository.findById(id);
MyData data = opt.get();
String result = "<tr><td>" + data.getName()
+ "</td><td>" + data.getMail() +
"</td><td>" + data.getAge() +
"</td><td>" + data.getMemo() +
"</td></tr>";
return result;
}
}
Si vous faites @ Autowired
pendant que le bean est préparé dans l'application, l'instance sera automatiquement liée.
[Contrôleur associé au champ pour utiliser le bean]
@Autowired
MyDataBean myDataBean;
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public ModelAndView indexById(@PathVariable long id,
ModelAndView mav) {
mav.setViewName("pickup");
mav.addObject("title","Pickup Page");
String table = "<table>"
+ myDataBean.getTableTagById(id)
+ "</table>";
mav.addObject("msg","pickup data id = " + id);
mav.addObject("data",table);
return mav;
}
Spring Framework fournit une classe ** Page ** pour la division de page, qui peut être utilisée pour réaliser la nation de page, qui est une fonction qui gère les données pour chaque page.
En spécifiant des paramètres, vous pouvez spécifier le nombre d'enregistrements sur la page et le numéro de page à afficher (exemple de 2 données / page, qui est la 0ème page).
【Comment accéder】
/page?size=2&page=0
La méthode findAll
, qui est un gestionnaire de requêtes, prend unPagable
comme argument, récupère une instance de Page
et la transmet au modèle avec le nom datalist
.
[Contrôleur avec gestionnaire de requêtes qui implémente la pagination]
@RequestMapping(value = "/page", method = RequestMethod.GET)
public ModelAndView index(ModelAndView mav, Pageable pageable) {
mav.setViewName("index");
mav.addObject("title","Find Page");
mav.addObject("msg","Ceci est un exemple de MyData.");
Page<MyData> list = repository.findAll(pageable); //●
mav.addObject("datalist", list);
return mav;
}
Puisque «Page» est une sous-classe de «List», l'entité passée au modèle peut être affichée dans le tableau de la même manière que «List».
【modèle】
<table>
<tr><th>ID</th><th>Nom</th><th>Email</th><th>âge</th><th>Note(tel)</th></tr>
<tr th:each="obj : ${datalist}">
<td th:text="${obj.id}"></td>
<td th:text="${obj.name}"></td>
<td th:text="${obj.mail}"></td>
<td th:text="${obj.age}"></td>
<td th:text="${obj.memo}"></td>
</tr>
</table>
Méthode | revenir |
---|---|
Pageable#getPageNumber() | Numéro de la page actuelle |
Pageable#getPageSize() | Nombre d'enregistrements à afficher sur la page |
Pageable#first() | Première pageable |
Pageable#previousOrFirst() | Précédent ou premier pageable |
Pageable#next() | Suivant Pageable |
Si vous prenez une entité distincte par pagination, vous devez vous déplacer vers l'avant et l'arrière de la page et préparer les fonctions liées à l'affichage de la page, définissez-la comme une classe Java à l'aide de ** l'objet utilitaire ** Vous pouvez appeler la méthode interne depuis Thymeleaf pour afficher le résultat.
Pour utiliser des objets utilitaires, préparez une classe ʻAttributeTagProcessor qui traite les attributs Thymeleaf et une classe
Dialectpour combiner cette classe. Lorsque
th: text =" name "" et l'attribut unique de Thymeleaf sont décrits, la valeur "name" est reçue et traitée comme le traitement de l'attribut appelé text, préparez donc le traitement spécifique.
«Un constructeur et« doProcess »sont fournis dans la classe créée en héritant de AbstractAttributeTagProcessor». Les arguments passés à cette méthode sont les suivants
Type d'argument | La description |
---|---|
ITemplatecontext | Gérez le contexte du modèle. Extrayez les informations de modèle telles que le moteur de modèle et les informations de configuration à partir d'ici. |
IProcessableElementTag | Les informations telles que les attributs incorporés dans les balises peuvent être récupérées dans les classes qui gèrent les balises d'élément. |
AttributeName | Gère les noms d'attributs et les préfixes (texte qui précède les valeurs) |
String | Valeur d'attribut |
IElementTagStructureHandler | Une classe qui gère des structures telles que l'incorporation d'attributs dans des éléments |
Lorsqu'une expression de variable Thymeleaf etc. est décrite dans la valeur Traitez l'expression de variable à l'aide de la fonction d'évaluation de valeur ** résolveur ** intégrée au moteur de modèle pour obtenir la valeur résultante. Puisqu'il est nécessaire d'effectuer un traitement d'attribut réel, l'exemple ci-dessous est exécuté avec doProcess
[Classe d'héritage AbstractAttributeTagProcessor]
public class MyPageAttributeTagProcessor extends AbstractAttributeTagProcessor {
private static final String ATTR_NAME = "mypage";
private static final int PRECEDENCE = 10000;
public static int size = 2;
public MyPageAttributeTagProcessor(final String dialectPrefix) {
super(TemplateMode.HTML, dialectPrefix, null,
false, ATTR_NAME, true, PRECEDENCE, true);
}
protected MyPageAttributeTagProcessor(TemplateMode templateMode,
String dialectPrefix, String elementName,
boolean prefixElementName,
String attributeName,
boolean prefixAttributeName,
int precedence,
boolean removeAttribute) {
super(templateMode, dialectPrefix, elementName,
prefixElementName, attributeName, prefixAttributeName,
precedence,removeAttribute);
}
@Override
protected void doProcess(ITemplateContext context,
IProcessableElementTag tag,
AttributeName attrName,
String attrValue,
IElementTagStructureHandler handler) {
final IEngineConfiguration configuration = context.getConfiguration();
final IStandardExpressionParser parser =
StandardExpressions.getExpressionParser(configuration);
final IStandardExpression expression =
parser.parseExpression(context, attrValue);
int value = (int)expression.execute(context);
value = value < 0 ? 0 : value;
handler.setAttribute("href", "/page?size=" + size + "&page=" + value);
}
}
ʻAbstractProcessorDialect a une méthode appelée
getProcessors qui obtient un ensemble qui résume ʻIProcessor
.
ʻIProcessorest une classe qui traite des choses telles que les attributs Thymeleaf. L'exemple crée une instance
Set, incorpore le ʻI Processor
et effectue un processus de retour
.
[Collecter comme attributs en tant que classe Dialect]
public class MyDialect extends AbstractProcessorDialect {
private static final String DIALECT_NAME = "My Dialect";
public MyDialect() {
super(DIALECT_NAME, "my", StandardDialect.PROCESSOR_PRECEDENCE);
}
protected MyDialect(String name, String prefix,
int processorPrecedence) {
super(name, prefix, processorPrecedence);
}
@Override
public Set<IProcessor> getProcessors(String dialectPrefix) {
final Set<IProcessor> processors = new HashSet<IProcessor>();
processors.add(new MyPageAttributeTagProcessor(dialectPrefix));
return processors;
}
}
Enregistrez et utilisez Bean
pour utiliser ʻAttributeTagProcessor et
Dialect`
① Créer un moteur de modèle
Après avoir créé l'instance SpringTemplateEngine
, définissez le résolveur de modèle avec setTemplateResolver
.
Ceci définit le résolveur de modèle créé par templateResolver
Incorporez l'instance MyDialect créée dans le moteur de modèle préparé avec ʻaddDialect, et lorsque le moteur de modèle
revient`, il sera utilisé pour le rendu.
② Créer un templateResolver
Créez une instance de ClassLoaderTemplateResolver
et définissez le préfixe, définissez s'il faut activer la mise en cache, définir le suffixe, définir le mode modèle, etc.
[Classe de structure]
@Configuration
public class MyBootAppConfig {
...
@Bean
public ClassLoaderTemplateResolver templateResolver() {
ClassLoaderTemplateResolver templateResolver =
new ClassLoaderTemplateResolver();
templateResolver.setPrefix("templates/");
templateResolver.setCacheable(false);
templateResolver.setSuffix(".html");
templateResolver.setTemplateMode("HTML5");
templateResolver.setCharacterEncoding("UTF-8");
return templateResolver;
}
@Bean
public SpringTemplateEngine templateEngine(){
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.addDialect(new MyDialect());
return templateEngine;
}
}
【modèle】
<div>
<a my:mypage="${datalist.getNumber() - 1}"><<prev</a>
|
<a my:mypage="${datalist.getNumber() + 1}">next>></a>
</div>
L'utilisation de base de NoSQL MongoDB est presque la même que celle de la base de données SQL car MongoRepository est conçu de la même manière que JpaRepository-> ** Write and call repository **
Omis
Recommended Posts