Mybatis

Vers le Haut 2022-01-15 02:46:17 阅读数:780

mybatis

MyBatis

Un..Proto - écologiejdbcRésumé des problèmes de programmation

1.CréationmysqlDonnées

Importer le script ci - dessous:

sql_table.sql:Structure de la feuille d'enregistrement

sql_data.sql:Enregistrer les données d'essai,Dans le développement réel de l'entreprise,Enfin, un script de données d'initialisation est fourni

2.Proto - écologiejdbcProcédure

UtiliserjdbcRequêtemysqlEnregistrement des tables d'utilisateurs dans la base de données.

Modifierpom.xml,Introduction de dépendances connexes

<!-- Introduire des dépendances de base de données -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>

Code du programme:JdbcTest.javaUtiliserjdbcMéthode originale(Non encapsulé)Réalisation de l'opération d'interrogation des enregistrements de table de base de données

public class JdbcTest {

public static void main(String[] args) {

Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {

Class.forName("com.mysql.jdbc.Driver"); // Charger le pilote de base de données
// Obtenir un lien vers la base de données via la classe de gestion des pilotes
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/order?characterEncoding=utf-8", "root", "root");
String sql = "select from user where username = ?"; // DéfinitionsqlDéclarations ?Représente un substituant
preparedStatement = connection.prepareStatement(sql); // Obtenir le prétraitementstatement
// Définir les paramètres,Le premier paramètre estsqlNuméro de séquence du paramètre dans l'instruction(De1C'est parti.),Le deuxième paramètre est la valeur du paramètre défini
preparedStatement.setString(1, "Wang Wu");
resultSet = preparedStatement.executeQuery();// Envoyer à la base de donnéessqlExécuter la requête,Ensemble de résultats de la requête
while (resultSet.next()) {
 // Parcourir l'ensemble de résultats de la requête
System.out.println(resultSet.getString("id") + " " + resultSet.getString("username"));
}
} catch (Exception e) {

e.printStackTrace();
} finally {

// Libérer des ressources
if (resultSet != null) {

try {

resultSet.close();
} catch (SQLException e) {

e.printStackTrace();
}
}
if (preparedStatement != null) {

try {

preparedStatement.close();
} catch (SQLException e) {

e.printStackTrace();
}
}
if (connection != null) {

try {

connection.close();
} catch (SQLException e) {

e.printStackTrace();
}
}
}
}
}

3.Résumé du problème

1)、Connexion à la base de données,Créer lors de l'utilisation,Ne pas utiliser de libération immédiate,Ouverture et fermeture fréquentes des connexions à la base de données,Gaspiller les ressources de la base de données,Affecter le rendement de la base de données.

Scénario:Gérer les connexions à la base de données en utilisant le pool de connexions à la base de données.

2)、Oui.sqlInstruction hardcore tojavaDans le Code,Sisql Modification des déclarations,Nécessite une recompilationjavaCode,Mauvais entretien du système.

Scénario:Oui.sqlInstruction configurée dansxmlDans le profil,Même sisqlChangement,Pas besoin.javaCode à recompiler.

3)、VerspreparedStatementParamètres de réglage dans,Définir les valeurs des paramètres pour la position du symbole d'occupation,Hard coded injavaDans le Code,Mauvais entretien du système.

Scénario:Oui.sqlL'instruction et les symboles et paramètres d'occupation sont tous configurés dansxmlMoyenne.

4)、DeResultSetLors de la traversée des données de l'ensemble de résultats,Code dur présent,Les champs du tableau d'acquisition sont codés en dur,Mauvais entretien du système.

Scénario:Ensemble de résultats à interroger,Cartographie automatique versjavaObjet.

2..mybatisPrincipe du cadre

1.mybatisQu'est - ce que c'est??

​ mybatisC'est unCadre de la couche persistante,- Oui.apacheHaut de la page.mybatisHébergementgoolecodeEn bas.,Plus tard, il a été hébergégithubEn bas.(https://github.com/mybatis/mybatis-3/releases).

​ mybatis Laissez les programmeurs se concentrer sur Concentrez - vous sur sqlAllez.,AdoptionmybatisMéthode de cartographie fournie,Génération libre et flexible(Semi - automatique,La plupart ont besoin d'un programmeur pour écriresql)Répondre aux besoinssqlDéclarations. mybatisPeut mettre preparedStatement Les paramètres d'entrée sont effectués automatiquement Carte d'entrée,Cartographier de façon flexible l'ensemble de résultats de la requête àjavaObjet.(Cartographie des extrants

2.mybatisPrincipe du cadre

Insérer la description de l'image ici

1、 mybatisConfiguration

SqlMapConfig.xml,Ce fichier estmybatisProfil global pour,ConfigurémybatisEnvironnement opérationnel, etc..

mapper.xmlLes documents sont:sqlFichier de cartographie,La base de données d'exploitation est configurée dans le fichiersqlDéclarations.Ce fichier doit êtreSqlMapConfig.xmlChargement moyen.

2、 AdoptionmybatisConstruction d'informations de configuration telles que l'environnementSqlSessionFactoryUsine de session

3、 Créé par l'usine de sessionsqlSessionSession,La base de données opérationnelle doit passer parsqlSessionEn cours.

4、 mybatisSous - jacent personnaliséExecutorBase de données des opérations d'interface de l'actionneur,ExecutorL'interface a deux implémentations,L'un est l'actionneur de base、L'un est l'actionneur de cache.

5、 Mapped StatementC'est aussimybatisUn objet encapsulé sous - jacent,Il est emballémybatisInformations de configuration etsqlInformations cartographiques, etc.mapper.xmlUn des fichierssqlCorrespondant à unMapped StatementObjet,sqlDeidC'est - à - direMapped statementDeid.

6、 Mapped StatementC'est exact.sqlExécuter les paramètres d'entrée pour définir,Y compris:HashMap、Type de base、pojo,ExecutorAdoptionMapped StatementEn courssqlAvant d'entrerjavaObjet mappé àsqlMoyenne,La cartographie des paramètres d'entrée estjdbcDans la programmationpreparedStatementDéfinir les paramètres.

7、 Mapped StatementC'est exact.sqlExécuter les résultats de sortie pour définir,Y compris:HashMap、Type de base、pojo,ExecutorAdoptionMapped StatementEn courssqlEnsuite, cartographiez les résultats de sortie àjavaDans l'objet,Le processus de cartographie des résultats de sortie est équivalent àjdbcProcessus d'analyse des résultats dans la programmation.

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-xRpLBkD3-1641215111304)(image/wpsPLJvK4.png)]

Trois.mybatisProgramme de démarrage

1.Structure technique

1.1 Besoins

Selon l'utilisateurid(Clé primaire)Interrogation des informations de l'utilisateur

Interrogation floue des informations de l'utilisateur par nom d'utilisateur

Ajouter un utilisateur

Supprimer l'utilisateur

Mettre à jour les utilisateurs

1.2 Modifierpom.xml,Introduction de dépendances connexes

<!-- IntroductionmybatisDépendance -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>

1.3 Nouveaulog4j.propertiesFichier des propriétés du Journal

mybatisUtilisation par défautlog4jComme information sur le journal de sortie.

InsrcSous le dossier,CrééresourcesDossiers,Clic droit pour sélectionnerMark Directory as --> resources root, Créer à l'intérieur log4j.propertiesLes documents sont les suivants:

# Global logging configuration
# Dans l'environnement de développement, le niveau de journalisation doit être défini à DEBUG, L'environnement de production est infoOuerror
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

Modifierpom.xml,Ajouter des dépendances de log

<!-- Introduire des dépendances de journaux -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

1.4 Nouveaudb.propertiesFichiers de propriétés

#mysql
db.username = root
db.password = root
db.jdbcUrl = jdbc:mysql://localhost:3306/order?characterEncoding=utf-8
db.driverClass = com.mysql.jdbc.Driver

Modifierpom.xml,AjoutermysqlDépendance

<!--mysqlDrive Pack -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>

1.5 SqlMapConfig.xmlProfil de base

SqlMapConfig.xml- Oui.mybatisProfil de base,ConfigurationmybatisEnvironnement opérationnel pour,Source des données、Affaires, etc..

InsrcSous le dossier,CrééresourcesDossiers, Créer à l'intérieur SqlMapConfig.xmlDocumentation.

Tout d'abord,,Créer d'abordmybatis Modèle de profil de base

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-15WQGLpl-1641215111309)(image/image-20200713211001576.png)]

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-sisJam0u-1641215111310)(image/image-20200713211254836.png)]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
</configuration>

Exiger que dans le profil de base ,configuration Toutes les configurations doivent être écrites strictement dans l'ordre suivant .[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-5vGnbLOq-1641215111311)(image/image-20210624155159869.png)]

Deuxièmement,,NouveauSqlMapConfig.xmlProfil de base

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-L9pu2OGi-1641215111311)(image/image-20200713211431635.png)]

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- Charger le fichier des propriétés db.properties -->
<properties resource="db.properties"></properties>
<!-- Configurer les paramètres globaux -->
<!--<settings></settings>-->
<!-- Alias personnalisé:Numériser les classes d'entités sous le paquet spécifié, Alias ces classes , Par défaut, son nom de classe ou ses initiales sont minuscules -->
<typeAliases>
<package name="com.cm.entity"/>
</typeAliases>
<!-- EtspringAprès intégration environmentsLa configuration sera annulée-->
<environments default="development">
<environment id="development">
<!-- UtiliserjdbcGestion des transactions, Le contrôle des transactions est assuré par mybatis-->
<transactionManager type="JDBC" />
<!-- Pool de connexion à la base de données,ParmybatisGestion,Adoption${} Charger directement les valeurs sur les fichiers de propriétés -->
<!-- -->
<dataSource type="POOLED">
<property name="driver" value="${db.driverClass}" />
<property name="url" value="${db.jdbcUrl}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</dataSource>
</environment>
</environments>
<!-- Chargement par lotsmapperFichier de cartographie:DésignationmapperNom du paquet où se trouve l'interface,mybatis Générer des objets proxy pour -->
<mappers>
<package name=" " />
</mappers>
</configuration>

1.6 MapperFichier de cartographie

Si vous voulez créer sous le même chemin que l'interface du même nom MapperFichier de cartographie,Modifications nécessairespom.xml.

La raison en est queIDEA Après compilation, la valeur par défaut de resources Les fichiers suivants sont placés dans targetDeclasspathEn bas.,Maissrc Il n'y a que JavaCompilation de fichiers.classLe fichier est placé dansclasspathEn bas., Les autres fichiers seront ignorés ,Par exemple.xmlDocumentation.

<build>
<!-- Identificationsrc/main/javaSous le cheminxmlDocumentation -->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>

Tout d'abord,,Créer d'abordmapper Modèle de fichier de cartographie

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-OA9QcZRn-1641215111312)(image/image-20200713211001576.png)]

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-6BuNuEZ1-1641215111314)(image/image-20200713212326790.png)]

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace=" ">
</mapper>

Deuxièmement,,NouveauMapperFichier de cartographie

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-ZdYqPANS-1641215111315)(image/image-20200713233247884.png)]

1.7 Structure technique

image-20200713233645180

2.SelonidUtilisateur de requête

2.1 Créationentity.UserCatégorie

User.javaEn tant quemybatisEn courssql La cartographie utilise , Habituellement, le nom de l'attribut correspond au champ de la table de base de données

import java.util.Date;
// Le nom de l'attribut correspond au champ de la table de base de données 
public class User {

private int id;
private String username;// Nom de l'utilisateur
private String sex;// Sexe
private Date birthday;// Anniversaire java.util.Date;
private String address;// Adresse
public User() {

}
public User(int id, String username, String sex, Date birthday, String address) {

this.id = id;
this.username = username;
this.sex = sex;
this.birthday = birthday;
this.address = address;
}
public int getId() {

return id;
}
public void setId(int id) {

this.id = id;
}
public String getUsername() {

return username;
}
public void setUsername(String username) {

this.username = username;
}
public String getSex() {

return sex;
}
public void setSex(String sex) {

this.sex = sex;
}
public Date getBirthday() {

return birthday;
}
public void setBirthday(Date birthday) {

this.birthday = birthday;
}
public String getAddress() {

return address;
}
public void setAddress(String address) {

this.address = address;
}
@Override
public String toString() {

return "User{" +
"id=" + id +
", username='" + username + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
", address='" + address + '\'' +
'}';
}
}

2.2 Modifier le fichier de cartographieUserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace Espace de noms,Le but est desql Gestion classifiée ,Pour l'isolementsqlDéclarations Attention!:Utilisation futuremapperDéveloppement d'une approche par procuration,namespaceA un rôle particulièrement important -->
<mapper namespace="com.cm.ch01.mapper.UserMapper">
<!-- Selon l'utilisateurid(Clé primaire)Interrogation des informations de l'utilisateur 1.id :En tant qu'identificateur unique 2.parameterType : Saisissez le type de cartographie des paramètres 3.resultType : Type de cartographie des paramètres de sortie ,Les alias peuvent être utilisés directement 4.? Placeholder : #{} S'il s'agit d'un type de données simple ,{} Les noms peuvent être écrits n'importe où ; Si le type de données de référence,{} Les noms à l'intérieur ne peuvent correspondre qu'à ceux de ce type Les noms des attributs sont cohérents -->
<select id="selectUserById" parameterType="Integer" resultType="User">
select * from user where id = #{id}
</select>
</mapper>

2.3 CréationUserMapper.javaInterface

/** MyBatis Spécification pour la mise en œuvre des relations cartographiques : 1.MapperInterfaces etMapperDexmlDocumentation, Doit avoir le même nom et sous le même paquet 2.MapperDexmlDans le fichier,namespace La valeur de doit être du même nom MapperNom complet de la classe de l'interface 3.MapperDans l'interface, Le nom de la méthode doit correspondre à MapperDexmlDansidD'accord. 4.Mapper Type de paramètre de la méthode dans l'interface ,Doit être compatible avecMapperDexmlDansparameterTypeLes valeurs de 5.MapperType de valeur de retour de la méthode dans l'interface,Doit être compatible avecMapperDexmlDansresultTypeLes valeurs de */
public interface UserMapper {

//AdoptionidInterrogation des informations de l'utilisateur
public User selectUserById(Integer id);
}

2.4 InSqlMapConfig.xmlChargement du fichier de cartographie

InsqlMapConfig.xmlChargement moyenUser.xml:

 <!-- Chargement par lotsmapperFichier de cartographie:DésignationmapperNom du paquet où se trouve l'interface,mybatis Générer des objets proxy pour -->
<mappers>
<package name="com.cm.ch01.mapper" />
</mappers>

2.5 NouveaujunitCatégorie d'essai

1). ModifiertestTable des matières,Clic droit pour sélectionnerMark Directory as -> Test Resources Root

img

2). Sélectionnez à construire junit Interface pour la classe d'essai ,Clic droit pour sélectionnerGo To -> Test

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-vs8rMXxE-1641215111316)(image/image-20200713221414296.png)]

3). CréationUserMapperTestCatégorie,Cochez la méthode à tester

image-20200713222841880

4). Écrire une classe de test

public class UserMapperTest {

// Créer un objet d'usine de session 
private SqlSessionFactory factory;
@Before
public void setUp() throws Exception {

//ChargementmybatisProfil de base
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void selectUserById() {

SqlSession sqlSession = factory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectUserById(1);
System.out.println(user);
sqlSession.close();
}
}

3.Interrogation floue des informations de l'utilisateur par nom d'utilisateur

3.1 Modifier le fichier de cartographieUserMapper.xml

<!-- Requête floue basée sur le nom d'utilisateur -->
<select id="selectUserByName" parameterType="String" resultType="User">
<!-- concat()Fonctions,Réaliser l'épissage -->
select * from user where username like CONCAT('%',#{username},'%')
</select>

3.2 ModifierUserMapper.javaInterface

 // Interrogation des informations de l'utilisateur par nom flou 
public List<User> selectUserByName(String name);

3.3 ModifierjunitCatégorie d'essai

@Test
public void selectUserByName() {

SqlSession sqlSession = factory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.selectUserByName("Xiao Ming");
for (User user : userList) {

System.out.println(user);
}
sqlSession.close();
}

4.Ajouter un utilisateur

4.1 Modifier le fichier de cartographieUserMapper.xml

<!-- Ajouter un utilisateur -->
<insert id="insertUser" parameterType="User">
<!-- Obtient l'objet actuellement inséré idValeur -->
<selectKey keyProperty="id" order="AFTER" resultType="Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>

4.2 ModifierUserMapper.javaInterface

//Insérer les informations de l'utilisateur
public void insertUser(User user);

4.3 ModifierjunitCatégorie d'essai

@Test
public void insertUser() throws ParseException {

SqlSession sqlSesison = factory.openSession();
UserMapper userMapper = sqlSesison.getMapper(UserMapper.class);
String str = "2019-09-09 12:12:12";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = sdf.parse(str);
User user = new User("Reese","2",date,"Suzhou");
userMapper.insertUser(user);
System.out.println(user);
sqlSesison.commit();
sqlSesison.close();
}

5.Modifier l'utilisateur

5.1 Modifier le fichier de cartographieUserMapper.xml

<!-- Mettre à jour les utilisateurs -->
<update id="updateUser" parameterType="User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id = #{id}
</update>

5.2 ModifierUserMapper.javaInterface

//Mettre à jour les informations de l'utilisateur
public void updateUser(User user);

5.3 ModifierjunitCatégorie d'essai

@Test
public void updateUser() {

SqlSession sqlSesison = factory.openSession();
UserMapper userMapper = sqlSesison.getMapper(UserMapper.class);
User user = userMapper.selectUserById(29);
user.setUsername("Li - si.");
userMapper.updateUser(user);
sqlSesison.commit();
sqlSesison.close();
}

6.Supprimer l'utilisateur

6.1 Modifier le fichier de cartographieUserMapper.xml

<!-- Supprimer l'utilisateur -->
<delete id="deleteUser" parameterType="int">
delete from user where id = #{id}
</delete>

6.2 ModifierUserMapper.javaInterface

//Supprimer les informations de l'utilisateur
public void deleteUser(Integer id);

6.3 ModifierjunitCatégorie d'essai

@Test
public void deleteUser() {

SqlSession sqlSesison = factory.openSession();
UserMapper userMapper = sqlSesison.getMapper(UserMapper.class);
userMapper.deleteUser(29);
sqlSesison.commit();
sqlSesison.close();
}

Quatre.SqlMapConfig-Contenu de la configuration

SqlMapConfig.xml

mybatisProfil global pourSqlMapConfig.xml, Le contenu et l'ordre de la configuration sont les suivants :

properties(Propriétés)

settings(Paramètres de configuration globaux)

typeAliases(Alias de type)

typeHandlers(Processeur de type)

objectFactory(Usine objet)

plugins(Plug - in)

environments( Objet de propriété de la collection d'environnement )

​ environment( Objet de sous - propriété environnement )

​ transactionManager(Gestion des transactions)

​ dataSource(Source des données)

mappers(Mapper)

1. propertiesPropriétés

Besoins:

Configurer les paramètres de connexion à la base de données individuellement dans db.propertiesMoyenne,Il suffit deSqlMapConfig.xmlChargement moyendb.propertiesValeur de l'attribut pour.

InSqlMapConfig.xml Il n'est pas nécessaire de hardcore les paramètres de connexion à la base de données .

Configurer les paramètres de connexion à la base de données uniquement dans db.propertiesMoyenne,Raisons: Faciliter la gestion unifiée des paramètres ,Autresxml On peut citer db.properties.

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-0wsczsgt-1641215111317)(image/wps1.jpg)]

InsqlMapConfig.xml Charger le fichier des propriétés :

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-W8OSGx3S-1641215111318)(image/wps2.jpg)]

propertiesCaractéristiques:

Attention!: MyBatis Les propriétés seront chargées dans l'ordre suivant: :

In properties Les attributs définis dans le corps de l'élément sont d'abord lus.

<properties resource="db.properties">
<!-- properties Vous pouvez également configurer certains noms d'attributs et valeurs d'attributs -->
<property name="" value="" />
</properties>

Et il litproperties Dans l'élémentresourceOu url Propriétés chargées , Il écrase la propriété Lue avec le même nom .

Dernière lectureparameterTypePropriétés passées, Il écrase la propriété Lue avec le même nom .

Suggestion:

Pas ici.properties Ajouter toute valeur d'attribut dans l'élément , Définir uniquement les valeurs des attributs à propertiesDans le document.

InpropertiesDans le document(Par exemple::db.propertiesDocumentation) Il doit y avoir une certaine particularité dans la définition des noms d'attributs ,Par exemple::XXXXX.XXXXX.XXXX

2. settingsConfiguration globale des paramètres

mybatis Le cadre peut ajuster certains paramètres de fonctionnement au moment de l'exécution .Par exemple,:**Activer le cache L2、Activer le chargement différé.** Les paramètres globaux affecteront mybatis Comportement opérationnel de .

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-n50gBhKh-1641215111318)(image/wps3.jpg)]

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-GZ8Y2gKJ-1641215111319)(image/wps4.jpg)]

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-qtEUdxIL-1641215111320)(image/wps5.jpg)]

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-hjLa8XYE-1641215111320)(image/wps6.jpg)]

3. typeAliases Alias

3.1 Besoins

Inmapper.xmlMoyenne, Beaucoup de définitions statement,statementBesoinparameterTypeSpécifiez le type de paramètre d'entrée、BesoinresultType Spécifie le type de cartographie pour les résultats de sortie .

Si vous saisissez le chemin complet du type lorsque vous spécifiez le type , Pas facile à développer ,Peut viserparameterTypeOuresultType Le type spécifié définit certains alias ,Inmapper.xml Défini par alias ,Facilité de développement.

3.2 mybatis Alias pris en charge par défaut

Alias Types de cartes
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal

3.3 Alias personnalisé

Alias de définition de lot

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-dDmdcAF1-1641215111321)(image/wps9.jpg)]

4. mappers(Configuration de la carte)

Chargement par lotsmapper

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-FfyH29uZ-1641215111322)(image/wps13.jpg)]

Cinq.Carte d'entrée-parameterType

AdoptionparameterTypeSpécifiez le type de paramètre d'entrée,Le type peut êtreType simple、hashmap、pojo Type d'emballage personnalisé pour .

Besoins

Compléter la requête complète des informations de l'utilisateur , Les critères de requête entrants sont complexes ( Peut inclure des informations sur l'utilisateur 、Autres informations,Comme les marchandises.、Ordre)

1.PasserpojoType d'emballage

1.1 Définir le type d'emballagepojo

Pour la demande supérieure , Recommandé pour un type d'emballage personnalisé pojo. Dans le type d'emballage pojo Envelopper les critères de requête complexes .

UserQueryVo Type d'emballage de l'utilisateur UserCustomSuccessionUser Est la classe d'extension de l'utilisateur , Informations sur l'utilisateur étendu

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-LS1qAHY8-1641215111322)(image/wps111.jpg)]

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-arTlo4hi-1641215111323)(image/wps222.jpg)]

1.2 mapper.xml

InUserMapper.xml Définir la requête complète d'information de l'utilisateur dans ( Conditions de requête complexes , Requête associée complexe par requête avancée ).

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-U4jIGxTO-1641215111323)(image/wps333.jpg)]

1.3 mapper.java

​ À l'interfaceUserMapper.javaMoyenne, Définir la méthode d'interrogation complète de l'information utilisateur .

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-c25sjaS3-1641215111324)(image/wps444.jpg)]

1.4 Code d'essai

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-BwRV320e-1641215111324)(image/wps555.jpg)]

2.PasserhashmapType

sql Le fichier de cartographie est défini comme suit :

2.1 UserMapper.xmlMoyenne

<!-- Passerhashmap Demande complète d'information de l'utilisateur hashmapAlias-->
<select id="findUserByHashmap" parameterType="hashmap" resultType="user">
select from user where id=#{id} and username like '%${username}%'
</select>

En haut#{id}、%${username}% - Oui.hashmapDekey.

2.2 Tests

Public void testFindUserByHashmap()throws Exception{

//Accèssession
SqlSession session = sqlSessionFactory.openSession();
//LimitémapperExemple d'interface
UserMapper userMapper = session.getMapper(UserMapper.class);
//Construire les critères de requêteHashmapObjet
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id", 1);
map.put("username", "Xiao Ming");
//PasserHashmap Object Query user List 
List<User>list = userMapper.findUserByHashmap(map);
//Fermersession
session.close();
}

Tests anormaux:

TransmismapDanskeyEtsqlParsed inkeyIncohérence.

Les résultats des tests ne sont pas erronés ,Juste à traverskey Obtenir une valeur vide .

Six.Cartographie des extrants-resultTypeEtresultMap

1.resultType

UtiliserresultTypeFaire la cartographie de sortie,Seuls les noms de colonnes etpojoLes noms des attributs sont cohérents,Cette colonne peut être cartographiée avec succès.

Si les noms de colonnes trouvés etpojo Tous les noms de propriétés sont incohérents ,Non créépojoObjet.

Tant que les noms de colonnes et pojo Il y a une cohérence entre les attributs dans ,Sera créépojoObjet.

1.1 Type simple de sortie

1.1.1 Besoins

Nombre total de listes de requêtes complètes pour les informations des utilisateurs , La pagination ne peut être réalisée que par le nombre total de requêtes et la liste complète des requêtes de l'utilisateur supérieur .

1.1.2 mapper.xml

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-NzyfRgsh-1641215111325)(image/wps21.jpg)]

1.1.3 mapper.java

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-L5vH7HYy-1641215111325)(image/wps22.jpg)]

1.1.4 Code d'essai

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-n7Nv1S4e-1641215111326)(image/wps23.jpg)]

1.1.5 Résumé

L'ensemble de résultats de la requête n'a qu'une ligne et une colonne , Vous pouvez utiliser des types simples pour la cartographie des sorties .

1.2 ProduitspojoObjet etpojoListe

Que ce soit la sortie pojo Un seul objet ou une liste (listY compris:pojo),Inmapper.xmlMoyenneresultType Le type spécifié est le même .

Inmapper.java Le type de valeur de retour de la méthode spécifiée est différent :

1.2.1 Output single pojoObjet, La valeur de retour de la méthode est un seul type d'objet

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-Z6ZKQkVr-1641215111326)(image/wps24.jpg)]

1.2.2 ProduitspojoObjetlist,La valeur de retour de la méthode estList<Pojo>

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-tiaEpQBF-1641215111327)(image/wps25.jpg)]

Les objets proxy dynamiques générés sont basés sur mapper.java Le type de valeur de retour de la méthode dans détermine qu'il s'agit d'un appel selectOne( Renvoie un seul appel d'objet )ToujoursselectList ( Renvoie l'appel de l'objet collection ).

2.resultMap

mybatisUtilisé dansresultMap Terminer la cartographie des résultats de sortie avancés .

2.1 resultMapMode d'emploi

Si les noms de colonnes trouvés etpojoNom de propriété incohérent pour,En définissant unresultMapPour les noms de colonnes etpojoFaire une relation de cartographie entre les noms de propriétés.

1、DéfinitionresultMap

2、UtiliserresultMapEn tant questatement Type de carte de sortie pour

2.2 Va sous sqlUtiliserUserTerminer la cartographie

SELECT id a , username b FROM USER WHERE id=#{value} User Le nom de l'attribut dans la classe est incompatible avec le nom de la requête supérieure .

2.2.1DéfinitionresultMap

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-0yTObHD6-1641215111327)(image/wps26.jpg)]

2.2.2 UtiliserresultMapEn tant questatement Type de carte de sortie pour

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-61qb2TlH-1641215111327)(image/wps27.jpg)]

2.2.3 mapper.java

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-pjp4nTgM-1641215111328)(image/wps28.jpg)]

2.2.4 Tests

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-vU4nDi4Z-1641215111330)(image/wps29.jpg)]

3. Résumé

UtiliserresultTypeFaire la cartographie de sortie,Seuls les noms de colonnes etpojoLes noms des attributs sont cohérents,Cette colonne peut être cartographiée avec succès.Si les noms de colonnes trouvés etpojoNom de propriété incohérent pour,En définissant unresultMapPour les noms de colonnes etpojoFaire une relation de cartographie entre les noms de propriétés.

Sept.Dynamiquesql

1.Qu'est - ce que la dynamiquesql?

mybatis Paire centrale sql Les déclarations sont flexibles , Juger par l'expression ,C'est exact.sql Faire des raccords flexibles 、Montage.

2.Qu'est - ce quesqlFragment?

Dynamique à réaliser sql Extrait du bloc de code de ,Former unsqlFragment.Autresstatement Peut être référencé sqlFragment, Faciliter le développement par les programmeurs .

3.Besoins

1.Besoins: Recherche de la liste des utilisateurs par sexe et nom de l'utilisateur PS: Sexe ou nom non autorisé nullOu une chaîne vide
2.Besoins: Nombre d'entrées de la liste des utilisateurs par sexe et nom de l'utilisateur PS: Sexe ou nom non autorisé nullOu une chaîne vide
3.Besoins: Recherche de la liste des utilisateurs par sexe et nom de l'utilisateur ,EtidLa valeur est15Ou20Ou25 PS: Sexe ou nom non autorisé nullOu une chaîne vide

4.CompilationUserCustomCatégorie

/** UserCustomSuccessionUser Est la classe d'extension de l'utilisateur , Informations sur l'utilisateur étendu */
public class UserCustom extends User{

}

5.CompilationUserQueryVOCatégorie

/** UserQueryVo Type d'emballage de l'utilisateur pojo */
public class UserQueryVO {

private UserCustom userCustom;
private List<Integer> ids;
public UserCustom getUserCustom() {

return userCustom;
}
public void setUserCustom(UserCustom userCustom) {

this.userCustom = userCustom;
}
public List<Integer> getIds() {

return ids;
}
public void setIds(List<Integer> ids) {

this.ids = ids;
}
}

6.CompilationUserMapper.xmlFichier de cartographie

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cm.ch02.sql.UserMapper">
<!-- sql Fragment :where L'étiquette n'est pas placée sur sqlDans le clip,Peut être améliorésql Utilisation des fragments -->
<sql id="user_query">
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and sex = #{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and username like concat('%',#{userCustom.username},'%')
</if>
</if>
</sql>
<!-- Entrée multipleidRequête -->
<sql id="user_query_id">
<if test="ids!=null">
<!-- foreach épissage itératif 1.collectionPropriétés: Saisissez les propriétés dans les paramètres 2.itemPropriétés:Nom de la variable temporaire 3.openPropriétés:Commence par... 4.closePropriétés:Fin... 5.separatorPropriétés:Séparateur -->
<!-- and (id=1 or id=10 or id=22) -->
<foreach collection="ids" item="user_id" open="and (" close=")" separator="or">
id=#{user_id}
</foreach>
<!-- and id in (1,10,22) -->
<!--<foreach collection="ids" open="and id in (" close=")" separator="," item="id"> #{id} </foreach>-->
</if>
</sql>
<!-- 1.Besoins: Recherche de la liste des utilisateurs par sexe et nom de l'utilisateur PS: Sexe ou nom non autorisé nullOu une chaîne vide -->
<select id="selectList" parameterType="UserQueryVO" resultType="UserCustom">
select * from user
<where>
<include refid="user_query"></include>
</where>
</select>
<!-- 2.Besoins: Nombre d'entrées de la liste des utilisateurs par sexe et nom de l'utilisateur PS: Sexe ou nom non autorisé nullOu une chaîne vide -->
<select id="selectCount" parameterType="UserQueryVO" resultType="int">
select count(*) from user
<where>
<include refid="user_query"></include>
</where>
</select>
<!-- 3.Besoins: Recherche de la liste des utilisateurs par sexe et nom de l'utilisateur ,EtidLa valeur est1Ou10Ou22 PS: Sexe ou nom non autorisé nullOu une chaîne vide -->
<select id="selectByIds" parameterType="UserQueryVO" resultType="UserCustom">
select * from user
<where>
<include refid="user_query"></include>
<include refid="user_query_id"></include>
</where>
</select>
</mapper>

7.CompilationUserMapper.javaInterface

import com.cm.entity.UserCustom;
import com.cm.entity.UserQueryVO;
import java.util.List;
public interface UserMapper {

public List<UserCustom> selectList(UserQueryVO vo);
public int selectCount(UserQueryVO vo);
public List<UserCustom> selectByIds(UserQueryVO vo);
}

8. Ajouter un scan au profil de base

<!-- Chargement par lotsmapperFichier de cartographie:DésignationmapperNom du paquet où se trouve l'interface,mybatis Générer des objets proxy pour -->
<mappers>
<package name="com.cm.ch02.sql" />
</mappers>

9.Tests

public class UserMapperTest {

private SqlSessionFactory factory;
@Before
public void setUp() throws Exception {

InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void selectList() {

SqlSession sqlSession = factory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserCustom userCustom = new UserCustom();
userCustom.setSex("1");
userCustom.setUsername("Ming");
UserQueryVO vo = new UserQueryVO();
vo.setUserCustom(userCustom);
List<UserCustom> list = userMapper.selectList(vo);
for (UserCustom user: list) {

System.out.println(user);
}
sqlSession.close();
}
@Test
public void selectCount() {

SqlSession sqlSession = factory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserCustom userCustom = new UserCustom();
userCustom.setSex("1");
userCustom.setUsername(null);
UserQueryVO vo = new UserQueryVO();
vo.setUserCustom(userCustom);
int count = userMapper.selectCount(vo);
System.out.println(count);
sqlSession.close();
}
@Test
public void selectByIds() {

SqlSession sqlSession = factory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
UserCustom userCustom = new UserCustom();
userCustom.setSex("");
userCustom.setUsername("Ming");
List<Integer> ids = new ArrayList<>();
ids.add(15);
ids.add(20);
ids.add(25);
UserQueryVO vo = new UserQueryVO();
vo.setUserCustom(userCustom);
vo.setIds(ids);
List<UserCustom> list = userMapper.selectByIds(vo);
for (UserCustom user: list) {

System.out.println(user);
}
sqlSession.close();
}
}

Huit.Cartographie avancée

1. Analyse du modèle de données sur les commandes

1.1 Contenu des données enregistrées dans chaque tableau

Sous - modules Familiarisez - vous avec le contenu de chaque enregistrement de tableau , équivalent à vos besoins en matière de système d'apprentissage (Fonction)Processus.

Tableau des utilisateurs:user

​ Les informations de l'utilisateur sur l'achat sont enregistrées

Tableau des commandes:orders

​ Les commandes créées par l'utilisateur sont enregistrées ( Commandes pour des articles )

Liste des commandes:orderdetail

​ Les détails de la commande, c'est - à - dire l'achat de l'article, sont consignés

Liste des produits:items

​ Les informations sur les produits sont enregistrées

1.2 Paramètres importants des champs pour chaque tableau

Champ non vide、Champ clé étranger

1.3 Relations entre les tables au niveau de la base de données

Relations clés étrangères:
1).Clé étrangèreuser_idLa table dans laquelleorders Appelé sous - table ;Par clé étrangèreuser_idPointez vers la table principale(Table des parents)userDansid
2).Clé étrangèreorders_idLa table dans laquelleorderdetail Appelé sous - table ;Par clé étrangèreorders_idPointez vers la table principale(Table des parents)ordersDansid
3).Clé étrangèreitems_idLa table dans laquelleorderdetail Appelé sous - table ;Par clé étrangèreitems_idPointez vers la table principale(Table des parents)itemsDansid

1.4 Relations d'affaires entre les tableaux

Lors de l'analyse des relations d'affaires entre les tableaux, assurez - vous d'analyser les relations d'affaires sur la base d'une certaine signification commerciale .

1). Analyser d'abord entre les niveaux de la base de données , Relations d'affaires entre les tableaux liés :

userEtorders:
user ---->orders: Un utilisateur peut créer plusieurs commandes ,Un à plusieurs
orders --->user: Une commande est créée par un seul utilisateur ,Un contre un.
ordersEtorderdetail:
orders --->orderdetail: Une commande peut comprendre plusieurs détails de commande , Parce qu'une commande peut acheter plusieurs articles , Les informations d'achat pour chaque article sont disponibles à l'adresse suivante: orderdetailEnregistrement,Une à plusieurs relations
orderdetail ---> orders: ..Les détails d'une commande ne peuvent être inclus que dans une seule commande ,Un contre un.
orderdetailEtitems:
orderdetail --->items: Un détail de commande ne correspond qu'à un seul élément d'information ,Un contre un.
items ---> orderdetail: Un article peut être inclus dans plusieurs détails de commande ,Un à plusieurs

2). Analyse entre les niveaux de la base de données , Existe - t - il une relation d'affaires entre les tableaux sans relation? :

ordersEtitems:
ordersEtitemsPeut passer entreorderdetail Le tableau établit la relation .

1.5 Analyse graphique

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-NQP0J6L6-1641215111331)(image/image-20200714004659822.png)]

2.Cartographie avancée-Requête individuelle

2.1 Besoins

Demander des informations sur la commande, Requête associée pour créer des informations utilisateur pour l'ordre

2.2 sqlDéclarations

select orders.*,user.sex,user.address,user.username,user.birthday
from orders,user
where orders.user_id = user.id

2.3 UtiliserresultMap L'idée de la cartographie

UtiliserresultMap Mapper les informations de commande dans les résultats de la requête vers OrdersDans l'objet,InordersAjouter à la classeUserPropriétés, Mapper les informations de l'utilisateur demandées par l'Association vers ordersDans l'objetuserDans les propriétés.

2.4 NouveauOrdersCatégorie

import java.util.Date;
/** Type de commande */
public class Orders {

private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
public Orders(Integer id, Integer userId, String number, Date createtime, String note) {

super();
this.id = id;
this.userId = userId;
this.number = number;
this.createtime = createtime;
this.note = note;
}
public Orders() {

super();
// TODO Auto-generated constructor stub
}
public Integer getId() {

return id;
}
public void setId(Integer id) {

this.id = id;
}
public Integer getUserId() {

return userId;
}
public void setUserId(Integer userId) {

this.userId = userId;
}
public String getNumber() {

return number;
}
public void setNumber(String number) {

this.number = number == null ? null : number.trim();
}
public Date getCreatetime() {

return createtime;
}
public void setCreatetime(Date createtime) {

this.createtime = createtime;
}
public String getNote() {

return note;
}
public void setNote(String note) {

this.note = note == null ? null : note.trim();
}
@Override
public String toString() {

return "Orders [id=" + id + ", userId=" + userId + ", number=" + number + ", createtime=" + createtime
+ ", note=" + note + "]";
}
}

2.5 NouveauOrdersCustomCatégorie

/** OrdersCustom Extension de la catégorie des commandes */
public class OrdersCustom extends Orders{

//resultMapComment
//Un contre un. Utilisateurs associés
private UserCustom userCustom;
public UserCustom getUserCustom() {

return userCustom;
}
public void setUserCustom(UserCustom userCustom) {

this.userCustom = userCustom;
}
@Override
public String toString() {

return super.toString()+"OrdersCustom [userCustom=" + userCustom + "]";
}
}

2.6 CréationOrdersUserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cm.ch03.oo.OrdersUserMapper">
<!-- Besoins:Demander des informations sur la commande, Requête associée pour créer des informations utilisateur pour l'ordre -->
<!-- typePropriétés: Type de retour réel idPropriétés:En tant queresultMapIdentification unique -->
<resultMap type="OrdersCustom" id="orderUserResultMap">
<!-- Configurer les informations de commande id: Spécifier un identifiant unique dans la colonne de requête result: Champs normaux dans le tableau Parmi eux:column Nom de colonne dans le tableau correspondant property Classe mappée àOrdersCustom Quel attribut dans la classe -->
<id column="id" property="id" />
<result column="user_id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- Configurer les informations de l'utilisateur OrdersCustomC'est liéUserCustom : Avecassociation Représenter une relation de cartographie individuelle propertyPropriétés: Mapper les informations de l'utilisateur pour la requête associée à OrdersCustomQuel attribut dans javaTypePropriétés:Type de propriété,Alias disponible -->
<association property="userCustom" javaType="UserCustom">
<id column="user_id" property="id" />
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="selectOrderUserResultMap" resultMap="orderUserResultMap">
select orders.*,user.sex,user.address,user.username,user.birthday
from orders,user
where orders.user_id = user.id
</select>
</mapper>

2.7 CréationOrdersUserMapper.javaInterface

import com.cm.entity.OrdersCustom;
import java.util.List;
public interface OrdersUserMapper {

//Besoins:Demander des informations sur la commande, Requête associée pour créer des informations utilisateur pour l'ordre resultMap
public List<OrdersCustom> selectOrderUserResultMap();
}

2.8 Ajouter un scan au profil de base

<!-- Chargement par lotsmapperFichier de cartographie:DésignationmapperNom du paquet où se trouve l'interface,mybatis Générer des objets proxy pour -->
<mappers>
<package name="com.cm.ch03.oo" />
</mappers>

2.9 Catégorie d'essai

import java.util.List;
public class OrdersUserMapperTest {

private SqlSessionFactory factory;
@Before
public void setUp() throws Exception {

factory = new SqlSessionFactoryBuilder().build(
Resources.getResourceAsStream("sqlMapConfig.xml"));
}
@Test
public void testSelectOrderUserResultMap(){

SqlSession sqlSession = factory.openSession();
OrdersUserMapper mapper = sqlSession.getMapper(OrdersUserMapper.class);
List<OrdersCustom> list = mapper.selectOrderUserResultMap();
for (OrdersCustom ordersCustom : list) {

System.out.println(ordersCustom);
}
sqlSession.close();
}
}

3.Cartographie avancée-Une à plusieurs requêtes

3.1 Besoins

Demander des informations sur les commandes et les détails des commandes

3.2 sqlDéclarations

select orders.*,
orderdetail.id od_id ,
orderdetail.items_id,
orderdetail.items_num
from orders,orderdetail
where orders.id = orderdetail.orders_id

3.3 Détails de la nouvelle commande OrderDetailCatégorie

/** Classe de détails de commande */
public class OrderDetail {

private Integer id;
private Integer orderId;
private Integer itemId;
private Integer itemNum;
public Integer getId() {

return id;
}
public void setId(Integer id) {

this.id = id;
}
public Integer getOrderId() {

return orderId;
}
public void setOrderId(Integer orderId) {

this.orderId = orderId;
}
public Integer getItemId() {

return itemId;
}
public void setItemId(Integer itemId) {

this.itemId = itemId;
}
public Integer getItemNum() {

return itemNum;
}
public void setItemNum(Integer itemNum) {

this.itemNum = itemNum;
}
public OrderDetail() {

super();
// TODO Auto-generated constructor stub
}
public OrderDetail(Integer id, Integer orderId, Integer itemId, Integer itemNum) {

super();
this.id = id;
this.orderId = orderId;
this.itemId = itemId;
this.itemNum = itemNum;
}
@Override
public String toString() {

return "OrderDetail [id=" + id + ", orderId=" + orderId + ", itemId=" + itemId + ", itemNum=" + itemNum + "]";
}
}

3.4 NouveauOrderDetailCustom Détails de la commande classe d'expansion

/** OrderDetail La classe d'expansion de */
public class OrderDetailCustom extends OrderDetail{

}

3.5 ModifierOrdersCustomCatégorie

/** OrdersCustom Extension de la catégorie des commandes */
public class OrdersCustom extends Orders{

//resultMapComment
//Un contre un.
private UserCustom userCustom;
//Un à plusieurs Une commande a plusieurs détails de commande 
private List<OrderDetailCustom> detailCustomList;
public UserCustom getUserCustom() {

return userCustom;
}
public void setUserCustom(UserCustom userCustom) {

this.userCustom = userCustom;
}
public List<OrderDetailCustom> getDetailCustomList() {

return detailCustomList;
}
public void setDetailCustomList(List<OrderDetailCustom> detailCustomList) {

this.detailCustomList = detailCustomList;
}
@Override
public String toString() {

return super.toString()+"OrdersCustom{" +
"userCustom=" + userCustom +
", detailCustomList=" + detailCustomList +
'}';
}
}

3.6 CréationOrderAndOrderDetailMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cm.ch04.om.OrderAndOrderDetailMapper">
<!-- Besoins: Demander des informations sur les commandes et les détails des commandes -->
<resultMap type="OrdersCustom" id="OrdersAndOrderDetailResultMap">
<id column="id" property="id"/>
<result column="user_id" property="userId" />
<result column="number" property="number" />
<result column="createtime" property="createtime" />
<result column="note" property="note" />
<!-- collection : Une à plusieurs associations 1.propertyPropriétés:OrdersCustom Implémenter un à plusieurs noms d'attributs dans 2.ofTypePropriétés:OrdersCustom Implémenter un à plusieurs types d'attributs dans -->
<collection property="detailCustomList" ofType="OrderDetailCustom">
<id column="od_id" property="id"/>
<result column="id" property="orderId"/>
<result column="items_id" property="itemId"/>
<result column="items_num" property="itemNum"/>
</collection>
</resultMap>
<select id="selectOrderAndOrderDetail" resultMap="OrdersAndOrderDetailResultMap">
select orders.*,
orderdetail.id od_id ,
orderdetail.items_id,
orderdetail.items_num
from orders,orderdetail
where orders.id = orderdetail.orders_id
</select>
<!-- Besoins: Demander des informations sur les commandes et les détails des commandes , Et l'information de l'utilisateur -->
<resultMap type="OrdersCustom" id="result" extends="OrdersAndOrderDetailResultMap">
<!-- Informations sur la commande -->
<!-- Détails de la commande -->
<!-- Informations sur l'utilisateur : Un contre un. -->
<association property="userCustom" javaType="UserCustom">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="birthday" property="birthday"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="selectOrderANDOrderDetailUser" resultMap="result">
select orders.*,
orderdetail.id od_id ,
orderdetail.items_id,
orderdetail.items_num,
user.sex,
user.username,
user.address,
user.birthday
from orders,orderdetail,user
where orders.id = orderdetail.orders_id and orders.user_id = user.id
</select>
</mapper>

3.7 CréationOrderAndOrderDetailMapper.javaInterface

import java.util.List;
public interface OrderAndOrderDetailMapper {

//Besoins: Demander des informations sur les commandes et les détails des commandes 
public List<OrdersCustom> selectOrderAndOrderDetail();
//Besoins: Demander des informations sur les commandes et les détails des commandes , Et l'information de l'utilisateur 
public List<OrdersCustom> selectOrderANDOrderDetailUser();
}

3.8 Ajouter un scan au profil de base

<!-- Chargement par lotsmapperFichier de cartographie:DésignationmapperNom du paquet où se trouve l'interface,mybatis Générer des objets proxy pour -->
<mappers>
<package name="com.cm.ch04.om" />
</mappers>

3.9 Catégorie d'essai

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
public class OrderAndOrderDetailMapperTest {

private SqlSessionFactory factory;
@Before
public void setUp() throws Exception {

factory = new SqlSessionFactoryBuilder().build(
Resources.getResourceAsStream("sqlMapConfig.xml"));
}
@Test
public void testSelectOrderAndOrderDetail() {

SqlSession sqlSession = factory.openSession();
OrderAndOrderDetailMapper mapper = sqlSession.getMapper(OrderAndOrderDetailMapper.class);
List<OrdersCustom> list = mapper.selectOrderAndOrderDetail();
for (OrdersCustom ordersCustom : list) {

System.out.println(ordersCustom);
}
System.out.println(list.size());
sqlSession.close();
}
@Test
public void testSelectOrderANDOrderDetailUser(){

SqlSession sqlSession = factory.openSession();
OrderAndOrderDetailMapper mapper = sqlSession.getMapper(OrderAndOrderDetailMapper.class);
List<OrdersCustom> list = mapper.selectOrderANDOrderDetailUser();
for (OrdersCustom ordersCustom : list) {

System.out.println(ordersCustom);
}
System.out.println(list.size());
sqlSession.close();
}
}

4.Cartographie avancée-Plusieurs à plusieurs requêtes

4.1 Besoins

Demander aux utilisateurs et aux utilisateurs d'acheter des informations sur les produits

4.2 sqlDéclarations

select u.*,
o.id oid, o.number, o.createtime ,
d.id did, d.items_num,
i.id iid, i.name, i.createtime itemsTime ,i.detail,i.price
from user u,orders o,orderdetail d,items i
where u.id = o.user_id and o.id = d.orders_id and d.items_id = i.id

4.3 Nouvel article ItemsCatégorie

import java.util.Date;
public class Items {

private Integer id;
private String name;
private Float price;
private String detail;
private String pic;
private Date createtime;
public Integer getId() {

return id;
}
public void setId(Integer id) {

this.id = id;
}
public String getName() {

return name;
}
public void setName(String name) {

this.name = name;
}
public Float getPrice() {

return price;
}
public void setPrice(Float price) {

this.price = price;
}
public String getDetail() {

return detail;
}
public void setDetail(String detail) {

this.detail = detail;
}
public String getPic() {

return pic;
}
public void setPic(String pic) {

this.pic = pic;
}
public Date getCreatetime() {

return createtime;
}
public void setCreatetime(Date createtime) {

this.createtime = createtime;
}
public Items() {

super();
// TODO Auto-generated constructor stub
}
public Items(Integer id, String name, Float price, String detail, String pic, Date createtime) {

super();
this.id = id;
this.name = name;
this.price = price;
this.detail = detail;
this.pic = pic;
this.createtime = createtime;
}
@Override
public String toString() {

return "Items [id=" + id + ", name=" + name + ", price=" + price + ", detail=" + detail + ", pic=" + pic
+ ", createtime=" + createtime + "]";
}
}

4.4 NouveauItemsCustom Catégorie d'expansion des produits de base

public class ItemsCustom extends Items{

}

4.5 ModifierOrderDetailCustom Détails de la commande classe d'expansion

/** OrderDetail La classe d'expansion de */
public class OrderDetailCustom extends OrderDetail{

// Avoir un article dans les détails d'une commande Un contre un.
private ItemsCustom itemsCustom;
public ItemsCustom getItemsCustom() {

return itemsCustom;
}
public void setItemsCustom(ItemsCustom itemsCustom) {

this.itemsCustom = itemsCustom;
}
}

4.6 ModifierUserCustom Classe d'expansion des utilisateurs

/** UserCustomSuccessionUser Est la classe d'extension de l'utilisateur , Informations sur l'utilisateur étendu */
public class UserCustom extends User{

// L'utilisateur a plusieurs commandes Un à plusieurs
private List<OrdersCustom> ordersList;
public List<OrdersCustom> getOrdersList() {

return ordersList;
}
public void setOrdersList(List<OrdersCustom> ordersList) {

this.ordersList = ordersList;
}
@Override
public String toString() {

return "UserCustom [toString()=" + super.toString() + "]";
}
}

4.7 CréationUserItemsMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cm.ch05.mm.UserItemsMapper">
<!-- Besoins: Demander aux utilisateurs et aux utilisateurs d'acheter des informations sur les produits -->
<resultMap type="UserCustom" id="map">
<!-- Informations sur l'utilisateur -->
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="birthday" property="birthday"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<!-- Informations sur la commande Un à plusieurs -->
<collection property="ordersList" ofType="OrdersCustom">
<id column="oid" property="id"/>
<result column="id" property="userId"/>
<result column="number" property="number"/>
<result column="createtime" property="createtime"/>
<!-- Détails de la commande Un à plusieurs -->
<collection property="detailCustomList" ofType="OrderDetailCustom">
<id column="did" property="id"/>
<result column="oid" property="orderId"/>
<result column="iid" property="itemId"/>
<result column="items_num" property="itemNum"/>
<!-- Informations sur les produits Un contre un. -->
<association property="itemsCustom" javaType="ItemsCustom">
<id column="iid" property="id"/>
<result column="name" property="name"/>
<result column="itemsTime" property="createtime"/>
<result column="detail" property="detail"/>
<result column="price" property="price"/>
</association>
</collection>
</collection>
</resultMap>
<select id="selectUserItems" resultMap="map">
select u.*,
o.id oid, o.number, o.createtime ,
d.id did, d.items_num,
i.id iid, i.name, i.createtime itemsTime ,i.detail,i.price
from user u,orders o,orderdetail d,items i
where u.id = o.user_id and o.id = d.orders_id and d.items_id = i.id
</select>
</mapper>

4.8 CréationUserItemsMapperInterface

import java.util.List;
public interface UserItemsMapper {

//Besoins: Demander aux utilisateurs et aux utilisateurs d'acheter des informations sur les produits 
public List<UserCustom> selectUserItems();
}

4.9 Ajouter un scan au profil de base

<!-- Chargement par lotsmapperFichier de cartographie:DésignationmapperNom du paquet où se trouve l'interface,mybatis Générer des objets proxy pour -->
<mappers>
<package name="com.cm.ch05.mm" />
</mappers>

4.10 Catégorie d'essai

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
public class UserItemsMapperTest {

private SqlSessionFactory factory;
@Before
public void setUp() throws Exception {

factory = new SqlSessionFactoryBuilder().build(
Resources.getResourceAsStream("sqlMapConfig.xml"));
}
@Test
public void testSelectUserItems() {

SqlSession sqlSession = factory.openSession();
UserItemsMapper mapper = sqlSession.getMapper(UserItemsMapper.class);
List<UserCustom> list = mapper.selectUserItems();
for (UserCustom userCustom : list) {

System.out.println("Numéro d'utilisateur:"+userCustom.getId()+" Nom d'utilisateur: "+userCustom.getUsername());
for(OrdersCustom ordersCustom : userCustom.getOrdersList()){

System.out.println("No de commande:"+ordersCustom.getId() +" Numéro d'utilisateur:"+ordersCustom.getUserId());
System.out.println("=============");
for(OrderDetailCustom od:ordersCustom.getDetailCustomList()){

System.out.println(" Détails de la commande no :"+od.getId()+" No de commande:"+od.getOrderId()+" Numéro de l'article:"+od.getItemId());
ItemsCustom item = od.getItemsCustom();
System.out.println("Numéro de l'article:"+item.getId()+" Nom commercial:"+item.getName());
}
}
}
sqlSession.close();
}
}

5.Cartographie avancée-Chargement différé

1.Qu'est - ce que le chargement différé

resultMapLa cartographie avancée peut être réalisée(Utiliserassociation、collection Mise en œuvre d'une cartographie individuelle et d'une cartographie individuelle à plusieurs ),association、collection Avec fonction de chargement différé .

Besoins: Si l'ordre est interrogé et que les informations de l'utilisateur de requête sont associées .

Si vous Interrogez d'abord les informations de commande, vous pouvez satisfaire aux exigences. , Nous recherchons l'information de l'utilisateur lorsque nous avons besoin d'interroger l'information de l'utilisateur . Mettre l'information de l'utilisateur Demande sur demande C'estChargement différé.

Chargement différé:Demandez d'abord à partir d'une seule table、Associer la requête à partir de la table d'association si nécessaire, Améliorer considérablement les performances de la base de données ,Parce que la requête d'une seule table est plus rapide que la requête associée de plusieurs tables.

2.UtiliserassociationMise en œuvre du chargement différé

2.1 Besoins

Interrogation des commandes et interrogation associée des informations de l'utilisateur

2.2 mapper.xml

Il faut définir deux mapper La méthode de statement.

1、 Demande seulement des informations de commande

SELECT * FROM orders

Dans l'enquête sur la commande statementUtilisé dansassociation Pour retarder le chargement (Mise en œuvre)Inférieursatatement( Requête associée information de l'utilisateur )

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-hvhXcZbV-1641215111332)(image/wps31.jpg)]

2、 Requête associée information de l'utilisateur

​ Dans les informations de commande demandées ci - dessus user_id Pour associer les informations de l'utilisateur de requête

​ UtiliserUserMapper.xmlDansfindUserById

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-0R4g7HqT-1641215111333)(image/wps32.jpg)]

Allez d'abord à l'exécution selectOrderUserLazyloading, Exécuter lorsque l'utilisateur doit être interrogé findUserById,AdoptionresultMap La définition pour configurer l'exécution du chargement différé .

2.3 Chargement différéresultMap

UtiliserassociationDansselect Spécifie le délai de chargement à exécuter statementDeid.

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-CnNscYWP-1641215111333)(image/wps33.jpg)]

2.4 mapper.java

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-FJ49jpY3-1641215111333)(image/wps34.jpg)]

2.5 Tests

2.5.1 Idées de test

1、 Exécuter le haut mapperMéthodes(selectOrderUserLazyloading), Appel interne com.mybatis.ch21.lazyloading.OrderUserMapperDansselectOrderUserLazyloading,Requête seulementordersInformation(Tableau unique).

2、 Dans le programme pour parcourir l'étape précédente List,Quand on appelleOrdersDansgetUserLa méthode, Début du chargement différé .

3、Chargement différé,Pour appelerUserMapper.xmlMoyennefindUserById Cette méthode permet d'obtenir des informations sur l'utilisateur .

2.5.2 Configuration de chargement retardée

mybatisLe chargement différé n'est pas activé par défaut,Besoin deSqlMapConfig.xmlMoyennesettingConfiguration.

InmybatisConfiguration dans le profil de base: lazyLoadingEnabled、aggressiveLazyLoading

Paramètres Description Valeur admissible Par défaut
lazyLoadingEnabled Paramètres globaux chargement paresseux .Si elle est réglée à‘false’, Tous les associés sont chargés par initialisation . true | false false
aggressiveLazyLoading Lorsque défini à‘true’Quand, Les objets paresseux peuvent être entièrement chargés par n'importe quel attribut paresseux .Sinon, Chaque propriété est chargée à la demande . true | false true
lazyLoadTriggerMethods Spécifie la méthode de déclenchement des objets chargés tardivement . A method name list separated by commas equals,clone,
hashCode,toString

InSqlMapConfig.xmlConfiguration moyenne:

<!-- Paramètres de configuration globaux, Reconfigurer au besoin -->
<settings>
<!-- Allumez l'interrupteur de chargement différé -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- Changez la charge positive en charge négative pour charger au besoin -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- Spécifier la méthode de déclenchement du chargement différé :Par défautequals,toString Ça va déclencher -->
<setting name="lazyLoadTriggerMethods" value=""/>
</settings>
2.5.3 Code d'essai

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-AyEwIHRF-1641215111334)(image/wps35.jpg)]

3. Retarder la réflexion sur le chargement

Non utilisémybatisFourniassociationEtcollection Fonction de chargement différé dans ,Comment réaliser le chargement différé??

La méthode de réalisation est la suivante::

Définir deuxmapperMéthodes:

1、Liste des commandes de requête

2、Selon l'utilisateuridInterrogation des informations de l'utilisateur

Idées de réalisation:

Va d'abord chercher le premier mapperMéthodes, Obtenir la liste des informations de commande

Dans la procédure(service), Appelez le deuxième mapper Méthode d'interrogation des informations de l'utilisateur .

En dernier analyse:

Utilisation de la méthode de chargement différé , Commencez par une simple requête sql( Une seule feuille est préférable , Vous pouvez également associer des requêtes ), Chargez les autres informations de la requête associée au besoin .

Neuf.Cache de requête

1.Cache de niveau 1

1.1 Qu'est - ce qu'un cache de requête

mybatisFournir un cache de requête,Utilisé pour soulager la pression des données,Amélioration des performances de la base de données.

mybaitsFournir un cache de premier niveau,Et cache secondaire.

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-lToEbQ6A-1641215111334)(image/wps41.jpg)]

**Le cache de niveau 1 estSqlSessionCache de niveau.**La construction est nécessaire lors de l'exploitation de la base de données sqlSessionObjet,Il y a une structure de données dans l'objet(HashMap)Utilisé pour stocker les données mises en cache.DifférentsqlSessionEntre les zones de données mises en cache(HashMap)Ne s'influencent pas les uns les autres.

Le cache L2 estmapper Mapper le cache au niveau du fichier ,PlusieursSqlSessionPour faire fonctionner le mêmeMapperDesqlDéclarations,PlusieursSqlSessionLe cache secondaire peut être partagé,Le cache L2 est CrossSqlSessionDe.

Pourquoi utiliser le cache?

S'il y a des données dans le cache, il n'est pas nécessaire de les extraire de la base de données , Améliorer considérablement les performances du système .

1.2 Cache de niveau 1

1.2.1 Comment fonctionne le cache de niveau 1

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-8F1CdZkN-1641215111335)(image/wps42.jpg)]

L'utilisateur qui lance la première requêteidPour1Informations sur l'utilisateur pour,Trouve d'abord s'il y en a dans le cache.idPour1Informations sur l'utilisateur pour,Si ce n'est pas le cas,Recherche d'informations sur l'utilisateur à partir de la base de données. Après avoir obtenu les informations de l'utilisateur ,Stocker les informations de l'utilisateur dans un cache de niveau 1.

SisqlSessionPour mettre en œuvrecommitFonctionnement(Effectuer l'insertion、Mise à jour、Supprimer),Vide.SqlSessionCache de niveau 1 dans,Ceci est fait pour que les informations les plus récentes soient stockées dans le cache,Évitez les lectures sales.

Utilisateur de la deuxième requêteidPour1Informations sur l'utilisateur pour,Trouve d'abord s'il y en a dans le cache.idPour1Informations sur l'utilisateur pour,Dans le cache,Obtenir les informations de l'utilisateur directement à partir du cache.

1.2.2 Test de cache de niveau 1

mybatisLe cache de niveau 1 est pris en charge par défaut, Il n'est pas nécessaire de configurer dans le fichier de configuration .

Suivez les étapes du principe de cache de niveau 1 ci - dessus pour tester .

UserMapper.xml

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-p8hcwcp7-1641215111335)(image/wps43.jpg)]

UserMapper.java

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-lHsDg6Pu-1641215111336)(image/wps44.jpg)]

Catégorie d'essai:UserMapperTest.java

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-P4D1H65j-1641215111336)(image/wps45.jpg)]

1.2.3 Application de cache de niveau 1

Développement formel,Oui.mybatisEtspringDéveloppement intégré, La transaction est contrôlée à serviceMoyenne.

Unservice Il y a beaucoup de méthodes mapperAppel de méthode.

service{

//Au début de l'exécution,Ouvrir la transaction,CréationSqlSessionObjet
//Premier appelmapperMéthodefindUserById(1)
//Deuxième appelmapperMéthodefindUserById(1), Extraire les données du cache de niveau 1 
//Fin de la méthode,sqlSessionFermer
}
service{

//Au début de l'exécution,Ouvrir la transaction,CréationSqlSessionObjet
//Premier appelmapperMéthodefindUserById(1)
//Deuxième appelmapperMéthodefindUserById(1), Extraire les données du cache de niveau 1 
//Fin de la méthode,sqlSessionFermer
}

Si c'est fait deux fois service Appeler pour interroger les mêmes informations utilisateur , Pas de cache de premier niveau ,Parce queserviceFin de la méthode,sqlSessionC'est fermé., Le cache de niveau 1 est vide .

2.Cache L2

2.1 Principes

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-Ps6hepL3-1641215111336)(image/wps51.jpg)]

D'abord.mybatisCache secondaire pour.

sqlSession1 Pour interroger les utilisateurs idPour1Informations sur l'utilisateur pour, La recherche d'informations utilisateur stocke les données de la requête dans le cache secondaire .

SiSqlSession3 Pour faire la même chose mapperEn bas.sql,Mise en œuvrecommitSoumettre,Videz ça. mapper Données de la zone de cache secondaire inférieure .

sqlSession2 Pour interroger les utilisateurs idPour1Informations sur l'utilisateur pour, Rechercher les données dans le cache , S'il y a des données extraites directement du cache .

Différence entre le cache L2 et le cache L1 , Le cache de niveau 2 a une plus grande portée ,PlusieurssqlSessionPeut partager unUserMapper Zone de cache secondaire pour .

UserMapper Il y a une zone de cache secondaire (Appuyez.namespacePoints),Autresmapper A également sa propre zone de cache secondaire (Appuyez.namespacePoints).

ChaquenamespaceDemapper Il y a deux zones de cache ,Deux.mapperDenamespaceSi c'est pareil,Ces deux - là.mapperMise en œuvresql Les données trouvées seront dans la même zone de cache secondaire .

2.2 Activer le cache L2

mybaitsLe cache secondaire demapperNiveau de portée,Sauf dansSqlMapConfig.xmlRéglage du commutateur principal pour le cache L2,Et en particulier,mapper.xmlActiver le cache L2 dans.

Première étape:Dans le profil de baseSqlMapConfig.xmlChine

<setting name="cacheEnabled" value="true"/>
Description Valeur admissible Par défaut
cacheEnabled Pour tout ce qui est sous ce profil cache Effectuer une ouverture globale / Réglage off . true false true

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-uLtJ21mR-1641215111337)(image/wps52.jpg)]

Deuxième étape:InUserMapper.xml Activer le cache 2

UserMapper.xmlEn bassql L'exécution complète est stockée dans sa zone de cache (HashMap).

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-f2uxme85-1641215111337)(image/wps53.jpg)]

2.3 AppelezpojoLa classe implémente l'interface de sérialisation

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-RbM4lpwl-1641215111337)(image/wps54.jpg)]

Effectuer une opération de désrialisation pour extraire les données mises en cache,Parce que les supports de stockage de données de cache L2 sont variés, C'est différent en mémoire .

2.4 Méthodes d'essai

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-Y9nQF1MS-1641215111338)(image/wps55.jpg)]

2.5 useCache Configuration

InstatementParamètres intermédiairesuseCache=falsePeut désactiver le courantselectCache secondaire de l'instruction, C'est - à - dire que chaque requête est envoyée sqlPour vérifier,La valeur par défaut esttrue,C'est ça.sqlUtilisation du cache secondaire.

<select id="findUserById" parameterType="int" resultType="user" useCache="false">

Résumé: Les données les plus récentes sont nécessaires pour chaque requête sql,Pour définiruseCache=false,Désactiver le cache L2.

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-svuW6X4t-1641215111338)(image/wps56.jpg)]

2.6 Rafraîchir le cache(Vider le cache)

InmapperLe même.namespaceMoyenne, S'il y a autre chose insert、update、delete Rafraîchir le cache après avoir manipulé les données , Lecture sale si le cache de rafraîchissement n'est pas effectué .

ParamètresstatementEn configurationflushCache=“true” Propriétés,Par défauttrue Rafraîchir le cache ,Si ça devientfalse Ne pas rafraîchir . Si vous modifiez manuellement les données de requête dans une table de base de données lors de l'utilisation du cache, il y aura une lecture sale .

Comme suit:

<insert id="insertUser" parameterType=" User" flushCache="true">

Résumé: Normalement, l'exécution est terminée commit Toutes les opérations nécessitent une mise à jour du cache ,flushCache=true Pour rafraîchir le cache , Cela évite la lecture sale de la base de données .

2.7 Scénario d'application secondaire

Pour accéder à plus d'une demande de requête et l'utilisateur n'a pas besoin de résultats de requête en temps réel,Peut maintenant être utilisémybatisLa technologie de mise en cache secondaire réduit l'accès à la base de données,Accès plus rapide,Des scénarios d'affaires comme:Analyse statistique qui prend beaucoup de tempssql、Demande de facture de téléphonesqlAttendez..

La méthode de réalisation est la suivante::En réglant l'intervalle de rafraîchissement,ParmybatisVider automatiquement le cache à intervalles réguliers,.Définir l'intervalle de rafraîchissement du cache en fonction de la fréquence de changement des donnéesflushInterval,Par exemple, régler à30Minutes、60Minutes、24Heures, etc.,Selon les besoins.

2.8 Limites du cache L2

​ mybatis La mise en cache de niveau 2 n'est pas bonne pour la mise en cache de niveaux de données à grain fin ,Par exemple, les exigences suivantes:Mise en cache des informations sur les produits,En raison du grand nombre de demandes d'information sur les produits,Mais les utilisateurs sont tenus de consulter les dernières informations sur les produits à chaque fois,Si vous utilisezmybatisLa mise en cache de niveau 2 ne peut pas mettre à jour l'information du cache d'un article seulement lorsque l'article change, mais pas d'autres articles,Parce quemybaitsLa zone de cache secondaire demapperDivision par Unit é,Lorsqu'un changement d'information sur l'article Efface toutes les données mises en cache pour toutes les informations sur l'article.Pour résoudre ces problèmes, il faut mettre en cache les données en fonction des besoins au niveau opérationnel.

Dix.mybatisEtspringIntégration

1.Concept

Spring

 SpringC'est un cadre open source,SpringC'est à2003 Un légerJava Cadre de développement,ParRod Johnson Dans ses écritsExpert One-On-One J2EE Development and DesignCertaines des idées et des prototypes développés dans.Il a été créé pour résoudre la complexité du développement d'applications d'entreprise.SpringUtilisation de baseJavaBeanJusqu'à présent, cela ne pouvait être fait que parEJBCe qui est fait.Et pourtant,SpringL'utilisation de n'est pas limitée au développement côté serveur.De la simplicité、En termes de testabilité et d'angle de couplage lâche,N'importe quoiJavaLes applications peuvent être téléchargées à partir deSpringAvantages. En termes simples,SpringC'est une inversion de commande légère(IoC)Et face à la section(AOP)Cadre du conteneur pour.

MyBatis

 MyBatis Ben oui.apacheUn projet Open source pouriBatis, 2010Ce projet a été réalisé parapache software foundation A migré versgoogle code,Et renomméMyBatis .MyBatisEst basé surJavaCadre de la couche de persistance pour.iBATISLe cadre de la couche de persistance fourni comprendSQL MapsEtData Access Objects(DAO)MyBatis A éliminé presque tous lesJDBCRéglage manuel du Code et des paramètres et récupération des ensembles de résultats.MyBatis Simple à utiliser XMLOu annotation pour la configuration et la cartographie originale,Interface et Java DePOJOs(Plain Old Java Objects,Ordinaire JavaObjet)Cartographie des enregistrements dans la base de données.

2.Intégration des idées

BesoinSpringAdoptionIOCGestion modaleSqlSessionFactory.
springEtmybatisConsolider les objets proxy de construction,UtiliserSqlSessionFactoryCréationSqlSession.(SpingEtmybati Intégration automatique complète ).
Persistantmapper Tout est entre les mains de springGérer.

3.Travaux préparatoires

3.1 Créer un nouveauMavenDejavaIngénierie

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-O39YDZQB-1641215111338)(image/image-20210304200206857.png)]

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-YQEaNcRa-1641215111339)(image/image-20210304200316460.png)]

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-C9FaJyVX-1641215111339)(image/image-20210304200506823.png)]

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-ypkQnQFW-1641215111340)(image/image-20210304200542827.png)]

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-1oVANOZf-1641215111340)(image/image-20210304200615366.png)]

3.2 Nouveau fichier de propriétés

CréationresourcesDossiers,Clic droit pour sélectionnerMark Directory as PourResources root

Nouveaudb.propertiesDocumentation

#mysql
db.username = root
db.password = root
db.jdbcUrl = jdbc:mysql://localhost:3306/testmybatis?useUnicode=true&characterEncoding=utf8
db.driverClass = com.mysql.jdbc.Driver

Nouveaulog4j.propertiesDocumentation

# Global logging configuration
# Dans l'environnement de développement, le niveau de journalisation doit être défini à DEBUG, L'environnement de production est infoOuerror
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

3.3 Introduction de dépendances connexes

Maven Introduire les dépendances requises

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<spring.version>5.3.4</spring.version>
</properties>
<dependencies>
<!-- junit5 Cadre d'essai -->
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.7.0</version>
</dependency>
<!-- log4jLog -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!--mysqlDrive Pack -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!--c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!--mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- aspectj -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
<!--springPaquets connexes -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!--Introductionmybatis Rétroingénierie dépendante -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
</dependencies>

4.IntégrationSpringEtMyBatis XML+Version annotée

4.1 NouveauMyBatisProfil de base

InresourcesNouveau sous le dossierSqlMapConfig.xmlDocumentation

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- Configuration globale des paramètres:Nom de la bosse、Cache L2、Chargement différé, etc. -->
<settings>
<!-- Nom de la bosse ouverte -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- Activer la configuration du surnom -->
<typeAliases>
<package name="com.igeek.ssm.pojo"/>
</typeAliases>
</configuration>

4.2 NouveauSpringProfil pour

InresourcesSous le dossier,NouveauapplicationContext.xmlDocumentation

4.2.1 Configurer la source de données

InapplicationContext.xmlConfigurer la source de données、Chargement du fichier de propriétés externes

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 1.Importer un fichier de propriétés externes -->
<context:property-placeholder location="db.properties"></context:property-placeholder>
<!-- 2.Configurer la source de données -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${db.username}"></property>
<property name="password" value="${db.password}"></property>
<property name="jdbcUrl" value="${db.jdbcUrl}"></property>
<property name="driverClass" value="${db.driverClass}"></property>
</bean>
</beans>

4.2.2 ConfigurationSqlSessionFactory

InapplicationContext.xml Configurer une instance d'usine de session

<!-- 3.CréationSqlSessionFactoryDebeanExemple -->
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- ChargementMyBatisProfil de base -->
<property name="configLocation" value="mybatis/SqlMapConfig.xml"></property>
<!-- Charger la source de données -->
<property name="dataSource" ref="dataSource"></property>
</bean>

Attention!:

1.UtiliserIDEADemaven Au fur et à mesure que les outils sont développés ,Ça va arriver.spring L'agent ne peut pas lire mapperProfil XXXMaper.xmlLa question de—— org.apache.ibatis.binding.BindingException,Ça pourrait être danspom.xml Configurer la phrase suivante :

...
<build>
<resources>
<resource>
<directory>${basedir}/src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
</build>
...

2. Si la configuration ci - dessus n'est pas ajoutée ,Vous devezXxxMapper.xml Les documents sont resourcesSous le dossier, Et en configurant SqlSessionFactory Ajouter les attributs suivants si nécessaire :

<!-- ChargementMapper.xmlEmplacement du fichier de cartographie -->
<property name="mapperLocations">
<list>
<value>classpath:/mapper/*Mapper.xml</value>
</list>
</property>

4.2.3 ConfigurationMapperScan Pack

InapplicationContext.xmlConfigurationMapperScanner

<!-- 4.ConfigurationmapperScan pack for,GénérermapperAgent de -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- Spécifiez le chemin de numérisation -->
<property name="basePackage" value="com.igeek.ssm.mapper"></property>
<!-- MontageSqlSesisonFactory Exemple d'usine de session , Mais attention avec value -->
<property name="sqlSessionFactoryBeanName" value="factory"></property>
</bean>

4.2.4 Configurer la transaction

InapplicationContext.xmlConfigurer le gestionnaire de transactions

<!-- 5.Configurer le gestionnaire de transactions -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 6. Démarrer la transaction de gestion des annotations -->
<tx:annotation-driven transaction-manager="transactionManager"/>

4.3 Tests

4.3.1 CréationUserCatégorie

public class User{

// Le nom de l'attribut correspond au champ de la table de base de données 
private int id;
private String name;
private String gender;
private Date birthday;
private int age;
private String pic;
private String pwd;
private String state;
...
}

4.3.2 CréationUserMapperInterface avecUserMapper.xmlFichier de cartographie

public interface UserMapper {

public User findUserById(int id);
public void updateUser(User user);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.igeek.ssm.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="User">
select * from user where id = #{id}
</select>
<update id="updateUser" parameterType="User">
update user set name=#{name},gender=#{gender},age=#{age} where id=#{id}
</update>
</mapper>

4.3.3 CréationUserServiceClasse de logique d'entreprise

@Service
public class UserService {

//InIOCDans le récipient,Injection directeUserMapperDebeanExemple
@Autowired
private UserMapper userMapper;
//AdoptionidInterrogation des informations de l'utilisateur
@Transactional(readOnly = true)
public User findUserById(int id){

return userMapper.findUserById(id);
}
//Test transaction:Mettre à jour les informations de l'utilisateur
@Transactional
public void updateUser(int id){

User user = userMapper.findUserById(id);
//Modifier les informations
user.setName("aaa");
user.setAge(18);
userMapper.updateUser(user);
//En cas d'exception,Ou tout faire,Ou pas du tout
//int i = 10/0;
//Modifier les informations
user.setName("bbb");
user.setAge(20);
userMapper.updateUser(user);
}
}

4.3.4 CréationUserServiceTestCatégorie d'essai

//ChargementSpringProfil pour
@SpringJUnitConfig(locations = "classpath:applicationContext.xml")
class UserServiceTest {

//DeIOCObtenir dans le conteneurUserServiceExemplesbean
@Autowired(required = false)
private UserService userService;
@Test
void findUserById() {

User user = userService.findUserById(1);
System.out.println(user);
}
@Test
void updateUser() {

userService.updateUser(1);
}
}

5.IntégrationSpringEtMyBatis JavaConfig+Version annotée

5.1 Ajouter à la classe de configurationMyBatisConfiguration de

MyBatisConfig.java

package com.igeek.ssm.config;
import org.apache.ibatis.session.Configuration;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.HashSet;
//MyBatisConfig Substitution SqlMapConfig.xmlProfil de base
//@Configuration Déclarer que la classe actuelle est uneJava ConfigClasse de configuration pour
@org.springframework.context.annotation.Configuration
//Activer le scanMapperInterface, Générer des objets proxy pour 
@MapperScan(basePackages = "com.igeek.ssm.mapper")
//ImporterMySpringConfigInformations sur la classe de configuration pour
@Import(MySpringConfig.class)
public class MyBatisConfig {

// Ajouter une instance d'usine de session à IOCDans le récipient
@Bean
public SqlSessionFactoryBean factory(DataSource dataSource) throws IOException {

SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
//Définir la source de données
factory.setDataSource(dataSource);
// Surnom personnalisé 
factory.setTypeAliasesPackage("com.igeek.ssm.pojo");
//Configuration globale des paramètres
Configuration configuration = new Configuration();
// Définir le nom de la bosse ouverte 
configuration.setMapUnderscoreToCamelCase(true);
//Activer le chargement différé
configuration.setLazyLoadingEnabled(true);
configuration.setAggressiveLazyLoading(false);
configuration.setLazyLoadTriggerMethods(new HashSet<>());
//Activer le cache L2
configuration.setCacheEnabled(true);
// Configurer les informations du profil de base 
factory.setConfiguration(configuration);
//ChargementMapperFichier de cartographie pour
factory.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*.xml"));
return factory;
}
}

5.2 Ajouter à la classe de configurationSpringConfiguration de

MySpringConfig.java

package com.igeek.ssm.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.beans.PropertyVetoException;
//MySpringConfigSubstitution applicationContext.xmlProfil
@Configuration
@ComponentScan(basePackages = "com.igeek.ssm")
@PropertySource(value = "db.properties")
@EnableTransactionManagement
public class MySpringConfig {

// Ajouter une source de données à IOCConteneur
@Bean(destroyMethod = "")
public ComboPooledDataSource dataSource(
@Value("${db.username}") String user,
@Value("${db.password}") String password,
@Value("${db.jdbcUrl}") String jdbcUrl,
@Value("${db.driverClass}") String driverClass
) throws PropertyVetoException {

ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setDriverClass(driverClass);
return dataSource;
}
// Ajouter un gestionnaire de transaction à IOCConteneur
@Bean
public DataSourceTransactionManager transactionManager(DataSource dataSource){

DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource);
return transactionManager;
}
}

5.3 CréationOrdersCatégorie

public class Orders {

private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
...
}

5.4 CréationOrdersMapperInterfaces etOrdersMapper.xmlFichier de cartographie

public interface OrdersMapper {

public List<Orders> findOrders();
public void updateOrders(Orders orders);
}

InresourcesSous le dossier,mapperCréer dans le dossierOrdersMapper.xmlFichier de cartographie

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.igeek.ssm.mapper.OrdersMapper">
<select id="findOrders" resultType="Orders">
select * from orders
</select>
<update id="updateOrders" parameterType="Orders">
update orders set number=#{number} where id=#{id}
</update>
</mapper>

5.5 CréationOrderServiceCatégorie

@Service
public class OrderService {

@Autowired
private OrdersMapper ordersMapper;
@Transactional(readOnly = true)
public List<Orders> findAllOrders(){

return ordersMapper.findOrders();
}
@Transactional
public void updateOrders(){

Orders orders1 = new Orders();
orders1.setId(3);
orders1.setNumber(UUID.randomUUID().toString().replaceAll("-",""));
ordersMapper.updateOrders(orders1);
//En cas d'exception
//int i = 10/0;
Orders orders2 = new Orders();
orders2.setId(4);
orders2.setNumber(UUID.randomUUID().toString().replaceAll("-",""));
ordersMapper.updateOrders(orders2);
}
}

5.6 CréationOrderServiceTestCatégorie d'essai

import com.igeek.ssm.config.MyBatisConfig;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
@SpringJUnitConfig(classes = MyBatisConfig.class)
class OrderServiceTest {

@Autowired(required = false)
private OrderService orderService;
@Test
void findAllOrders() {

System.out.println(orderService.findAllOrders());
System.out.println(orderService.findAllOrders().size());
}
@Test
void updateOrders() {

orderService.updateOrders();
}
}

Onze.Rétroingénierie

1.Qu'est - ce que la rétroingénierie?

​ mybaitsIl faut que le programmeur l'écrive lui - mêmesqlDéclarations,mybatis La rétroingénierie officielle peut être générée automatiquement pour une seule table mybatisExécuter le Code requis(mapper.java,mapper.xml、pojo…)Développement réel de l'entreprise, Méthodes courantes de rétroingénierie : Généré à partir des tables de la base de données javaCode.

2. Utilisation de la rétroingénierie

2.1 Modifierpom.xml

<!--Introductionmybatis Rétroingénierie dépendante -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>

2.2 Inpom.xmlNouveaumybatis-generatorPlug - in,InpluginsAjouter à l'étiquette

Attention!:Voici notregeneratorConfig.xml Le fichier a besoin du bon chemin ,Devant${basedir} Correspond automatiquement au chemin actuel ,Pas besoin de modifier

<!-- mybatis generator Génération automatique de plug - ins de code -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.1</version>
<configuration>
<configurationFile>${basedir}/src/resources/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
</plugin>

2.3 Insrc/resourcesEn bas.,CréationgeneratorConfig.xmlDocumentation

Attention!: Les chemins dans le fichier sont tous absolus

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- Ajouter une connexion à la base de données jarEmplacement du sac, En bas à gauche du projet external libraries Copier le chemin complet trouvé dans -->
<classPathEntry location="E:\5.JSP+Servlet\project\repo\mysql\mysql-connector-java\5.1.38\mysql-connector-java-5.1.38.jar"/>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- Supprimer les commentaires générés automatiquement true:- Oui. : false:Non -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--Informations sur la connexion à la base de données:Classe de conduite、Adresse de connexion、Nom d'utilisateur、Mot de passe -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/testmybatis" userId="root" password="root">
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!-- Par défautfalse,Prends ça.JDBC DECIMAL Et NUMERIC Type résolu à Integer,Pour trueChronomètreJDBC DECIMAL Et NUMERIC Type résolu àjava.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:GénérerPOEmplacement de la classe -->
<javaModelGenerator targetPackage="com.igeek.ssm.pojo" targetProject=".\src\main\java">
<!-- enableSubPackages:Oui NonschemaComme suffixe du paquet -->
<property name="enableSubPackages" value="false" />
<!-- Espaces avant et après le nettoyage des valeurs retournées de la base de données -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapperEmplacement du fichier de cartographie généré -->
<sqlMapGenerator targetPackage="com.igeek.ssm.mapper" targetProject=".\src\main\java">
<!-- enableSubPackages:Oui NonschemaComme suffixe du paquet -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapperEmplacement généré par l'interface -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.igeek.ssm.mapper" targetProject=".\src\main\java">
<!-- enableSubPackages:Oui NonschemaComme suffixe du paquet -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- Spécifie le nom de la table qui existe déjà dans la base de données -->
<table tableName="user"></table>
<table tableName="orders"></table>
<table tableName="orderdetail"></table>
<table tableName="items"></table>
</context>
</generatorConfiguration>

Attention!:

​ In MySQL 8.0 Dans les versions précédentes,En générant User Lorsque la classe d'entité du tableau ,Mybatis Generator On trouvera plusieurs User Tableau,Y compris: MySQL information schemas Plusieurs User Tableau,Plusieurs User Classe d'entité associée.
​ Pour s'assurer que seuls ceux que vous avez spécifiés sont générés database Dans User Tableau,Il faut d'abord Dans connectionURL Nom de l'Instance de la base de données spécifiée dans ,Et après Ajouter des informations de configuration connexes,C'est - à - dire:

, Vous pouvez vous assurer que vous ne générez que ce dont vous avez besoin User Catégorie.

2.4 ConfigurationmavenConfiguration de démarrage pour

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-eWq3imz4-1641215111341)(image/image-20200714022927793.png)]

Modifier la configuration,Ajoutermaven,Ligne de commande ajouter mybatis-generator:generate -e

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-HgizsBrM-1641215111341)(image/image-20200714023238566.png)]

2.5 Cliquez sur le bouton exécuter

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-BJGUAm5o-1641215111341)(image/image-20210304203003209.png)]

Sera générécom.igeek.ssm.pojo、com.igeek.ssm.mapperSac,EtpojoCatégorie、mapper.java、mapper.xmlDocumentation.

2.6 Besoins: Requête floue basée sur le nom du produit

Catégorie d'essai

import com.igeek.ssm.pojo.Items;
import com.igeek.ssm.pojo.ItemsExample;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import java.util.List;
@SpringJUnitConfig(locations = "classpath:spring/applicationContext.xml")
class ItemsMapperTest {

@Autowired
private ItemsMapper itemsMapper;
@Test
void selectByExample() {

ItemsExample itemsExample = new ItemsExample();
ItemsExample.Criteria criteria = itemsExample.createCriteria();
criteria.andNameLike("%Machine%");
List<Items> itemsList = itemsMapper.selectByExample(itemsExample);
for (Items items : itemsList) {

System.out.println(items.getName()+" : "+items.getDetail());
}
}
@Test
void updateByExampleWithBLOBs() {

Items items = itemsMapper.selectByPrimaryKey(1);
System.out.println(items.getName()+" : "+items.getDetail());
items.setDetail("Pas mal.!");
itemsMapper.updateByPrimaryKeyWithBLOBs(items);
}
}

3.Structure du projet

[Impossible de transférer l'image de la chaîne externe,Il peut y avoir un mécanisme antivol à la station source,Il est recommandé de sauvegarder l'image et de la télécharger directement(img-GV9VaRqG-1641215111342)(image/image-20210304203733368.png)]

Douze.Opérations

1. Compléter les fonctions de modification et de suppression de l'utilisateur

2.Utilisersql Exigences relatives à la mise en oeuvre des fragments

Besoins: Rechercher la liste des utilisateurs par sexe et nom ,EtidLa valeur est15Ou20Ou25 PS: Sexe ou nom non autorisé nullOu une chaîne vide
select * from user where sex=1 and username like concat('%','Ming','%') and (id=15 or id=20 or id=25);

3. Terminer la cartographie avancée

Besoins:Demande de commande、 Informations sur les détails de la commande et les utilisateurs qui passent la commande

Interview:

1.mybatisEthibernate Différences essentielles et scénarios d'application

1.Différences essentielles:

hibernate:C'est une norme.ORMCadre(Cartographie des relations objet). Seuil d'entrée plus élevé , Pas besoin d'un programmeur pour écrire sql,sqlInstruction générée automatiquement.C'est exact.sqlInstruction optimisée、 Il est plus difficile de modifier .

mybatis: La concentration est sqlEn soi,Il faut que le programmeur l'écrive lui - mêmesqlDéclarations,sqlModifier、 L'optimisation est plus pratique .mybatisC'est incomplet.ORMCadre, Bien que les programmeurs écrivent eux - mêmes sql,mybatis La cartographie peut également être réalisée(Carte d'entrée、Cartographie des extrants).

2.Scénario d'application:

hibernateScénarios d'application pour:

Projets de petite et moyenne dimension adaptés à des besoins peu changeants ,Par exemple,:Background management system,erp、orm、oa.

mybatisScénarios d'application pour:

Projets qui s'appliquent à des besoins plus variés ,Par exemple,:Projets Internet(JD、Taobao..)

L'entreprise effectue la sélection technique , Le principe du choix de la technologie avec un faible coût et un rendement élevé , Sélection fondée sur la force technique de l'équipe de projet .

2.${}Et#{}La différence entre

<!-- Besoins2:Interrogation floue des informations de l'utilisateur par nom d'utilisateur resultTypePropriétés: Type correspondant au résultat de la requête ( Compléter automatiquement la cartographie ) Si les données trouvées sont plusieurs , C'est - à - dire que la collection est retournée , Remplir le type de données d'un seul enregistrement #{} équivalent au substituant précédent ?,SimilairePrepareStatementComment utiliser, Peut être efficacement évité SQLProblèmes d'injection S'il s'agit d'un type de données simple ,{} Les noms peuvent être écrits n'importe où ; Si le type de données de référence,{} Les noms à l'intérieur ne peuvent correspondre qu'aux noms d'attributs de ce type ${} épissagesqlDéclarations,Similaire àStatementComment utiliser,Peut causerSQLProblèmes d’injection S'il s'agit d'un type de données simple ,{}Ça ne peut être quevalue,C'est - à - dire:${value} Lors de la transmission du paramètre ,Similaire à' or 1=1 or 'Structure,Il en résulteSQLInjection -->
<!-- sqlépissage -->
<!--<select id="selectListByLikeName" parameterType="String" resultType="User"> select * from user where username like '%${value}%' </select>-->
<!-- Placeholder -->
<select id="selectListByLikeName" parameterType="String" resultType="User">
select * from user where username like concat('%',#{username},'%')
</select>
@Test
public void selectListByLikeName(){

//1.ObtenirSqlSessionObjet de session
SqlSession sqlSession = sqlSessionFactory.openSession();
//2.Obtenir des objets Proxy
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//3.Mise en œuvre
List<User> userList = userMapper.selectListByLikeName("Ming");
/* select * from user where username like '%${value}%' Après épissage,C'est arrivé.SQLInjection: select * from user where username like '%' or 1=1 or '%' */
//List<User> userList = userMapper.selectListByLikeName("' or 1=1 or '");
for (User user : userList) {

System.out.println(user);
}
//4.Fermer la ressource
sqlSession.close();
}
版权声明:本文为[Vers le Haut]所创,转载请带上原文链接,感谢。 https://javamana.com/2022/01/202201080601055952.html