Préface
Cet article raconte principalement l'histoire de Springboot intégrant Mybatis, Druid et PageHelper et implémentant plusieurs sources de données et pagination. Parmi eux, Springboot intègre Mybatis, qui a été décrit dans un article précédent, donc je ne l'expliquerai pas trop ici. L'accent est mis sur la façon de configurer Druid et PageHelper dans plusieurs sources de données.
Introduction et utilisation du druide
Avant d'utiliser Druid, jetons un bref aperçu de Druid.
Druid est un pool de connexions de base de données. On peut dire que Druid est le meilleur pool de connexions de base de données actuellement! Il est très favorisé par les développeurs pour ses excellentes fonctionnalités, ses performances et son évolutivité.
Druid a déployé plus de 600 applications sur Alibaba et passe par le test rigoureux du déploiement à grande échelle dans des environnements de production depuis plus d'un an. Druid est un pool de connexions de base de données développé par Alibaba appelé surveillance!
Dans le même temps, Druid n'est pas seulement un pool de connexions de base de données, le cœur de Druid comprend principalement trois parties:
Les principales fonctions du druide sont les suivantes:
Je ne parlerai pas de l'introduction, veuillez vous référer à la documentation officielle pour plus de détails.
Commençons ensuite à introduire comment utiliser Druid.
Tout d'abord, la dépendance Maven, ajoutez simplement le pot Druid.
<dependency> <proupId> com.alibaba </rom groupeid> <Ertifactid> druid </ artifactid> <version> 1.1.8 </-version> </dependency>
En termes de configuration, l'essentiel est de l'ajouter dans application.properties ou application.yml comme suit.
Remarque: Parce que j'utilise deux sources de données ici, c'est juste un peu différent. Les instructions pour la configuration Druid sont déjà détaillées ci-dessous, donc je ne l'expliquerai pas ici.
## Source de données par défaut maître.datasource.url = jdbc: mysql: // localhost: 3306 / springboot? useunicode = true & worseencoding = utf8 & allowMultiqueries = tru emaster.datasource.username = rootmaster.datasource.password = 123456master.datasource.driverClassName = com.mysql.jdbc.driver ## Une autre source de données cluster.datasource.url = jdbc: mysql: // localhost: 3306 / springboot_test? useunicode = true & worseencoding = utf8cluster.datasource.usename = rootcluster.datasource.password = 123456cluster.datasource.DriverClassname = com.mysqlun. Informations de configuration pour le pool de connexion # Initialize Size, minimum, maximum spring.datasource.type = com.alibaba.druid.pool.druiddatasourcespring.datasource.initialsize = 5 spring.datasource.minidle = 5 spring.datasource.maxactive = 20 # configurer le temps pour obtenir le temps d'attente de connexion printemps.datasource.maxwait = 60000 # Configurez le temps qu'il faut pour effectuer un intervalle de détection pour détecter les connexions inactives qui doivent être fermées, en millisecondes printemps.datasource.TimebetweenvictionRunsmillis = 60000 # Configurez le temps minimum pour survivre dans la piscine, en milliseconds Spring.datasource.MinevitableIdlemillis = 300000.Datasource.MinevitableIdlemillis = 300000eds. Spring.Datasource.ValidationQuery = Sélectionnez 1 dans Dual Spring.Datasource.Test WhiteIdle = True Spring.Datasource.TestonBorrow = False Spring.Datasource.Testonreturn = False # Open PSCACHE et Spécifiez la taille de PSCACH printemps.datasource.maxpoolPreparedStatementPerConnectionSize = 20 # Configurez les filtres pour la surveillance des statistiques interceptées. Après l'avoir retiré, l'interface de surveillance SQL ne peut pas être comptée. 'wall' est utilisé pour le pare-feu printemps.datasource.filters = stat, wall, log4j # ouvre la fonction Mergesql via la propriété ConnectProperties; Slow SQL Records Spring.DataSource.ConnectionProperties = Druid.stat.Mergesql = TRUE; Druid.stat.slowsqlmillis = 5000
Après avoir réussi à ajouter le fichier de configuration, écrivons des classes liées à Druid.
Tout d'abord, la classe MasterdatasourceConfig.java, qui est la classe de configuration de la source de données par défaut.
@ Configuration @ MAPPERSCAN (BASEPACKAGES = MasterDataSourceConfig.Package, SqlSessionFactoryRef = "MastersQlSessionFactory") Public Class MasterDataSourceConfig {Static Final String Package = "com.pancm.dao.master"; Statique finale finale MAPPER_LOCATION = "CLASSPATH: MAPTER / MASTER / *. XML"; @Value ("$ {maître.datasource.url}") URL de chaîne privée; @Value ("$ {maître.datasource.username}") Private String Username; @Value ("$ {maître.datasource.password}") Mot de passe de chaîne privée; @Value ("$ {maître.datasource.driverClassName}") String private DriverClassName; @Value ("$ {printemps.datasource.initialSize}") private int initialSize; @Value ("$ {printemps.datasource.minidle}") private int MinIdle; @Value ("$ {printemps.datasource.maxactive}") private int maxactive; @Value ("$ {printemps.datasource.maxwait}") private int maxwait; @Value ("$ {printemps.datasource.timebetweenvictionrunsmillis}") private int timebetweenvictionrunsmillis; @Value ("$ {printemps.datasource.minevictableidleMemillis}") private int minevictableidlememillis; @Value ("$ {printemps.datasource.validationQuery}") private String ValidationQuery; @Value ("$ {printemps.datasource.test WhileIdle}") Test booléen privé WHERIDLE; @Value ("$ {printemps.datasource.testonborrow}") Boolean Private TestOnBorrow; @Value ("$ {printemps.datasource.testonreturn}") Boolean private Testonreturn; @Value ("$ {printemps.datasource.poolPreparedStatements}") Boolean PoolPreparedStatements privé; @Value ("$ {printemps.datasource.maxpoolPreparedStatementPerConnectionsize}") private int maxpoolPreparedStatementPerConnectionsize; @Value ("$ {printemps.datasource.filters}") Filtres de chaîne privés; @Value ("{printemps.datasource.connectionProperties}") Connection Private ConnectionProperties; @Bean (name = "MasterDataSource") @primary public dataSource masterdatasource () {druidDataSource dataSource = new DruidDataSource (); DataSource.setUrl (URL); DataSource.SetUsername (nom d'utilisateur); DataSource.SetPassword (mot de passe); DataSource.setDriverClassName (DriverClassName); // Configuration spécifique DataSource.SetInitialSize (initialSize); DataSource.setMinIdle (minidle); dataSource.setMaxActive (maxactive); DataSource.setMaxWait (Maxwait); dataSource.setTimeBetweenvictionRunsmillis (TimeBetweenEvictionRunsMillis); DataSource.setMinevictableIdleMemillis (MineVictableIdleMemillis); DataSource.SetValidationQuery (validationQuery); DataSource.SetTest WhileIdle (Test WhenIdle); DataSource.setTestonBorrow (TestOnBorrow); DataSource.setTestonreturn (testonreturn); DataSource.SetPoolPreparedStatements (PoolPreparedStatements); DataSource.SetMaxPoolPreparedStatementPerConnectionsize (MaxPoolPreparedStatementPerConnectionsize); essayez {dataSource.setFilters (filtres); } catch (sqlexception e) {e.printStackTrace (); } dataSource.setConnectionProperties (ConnectionProperties); return dataSource; } @Bean (name = "MasterTransactionManager") @Primary public DataSourceTransactionManager MasterTransactionManager () {return new DataSourceTransactionManager (MasterDataSource ()); } @Bean (name = "MastersQlSessionFactory") @primary public sqlSessionFactory MastersQLSessionFactory (@Qualifier ("MasterDataSource") DataSource MasterDataSource) lance une exception {final sqlSessionFactoryBean SessionFactory = new SQLSessionFactoryBean (); SessionFactory.SetDataSource (MasterDataSource); sessionfactory.setMapperLocations (new PathMatchingResourcePatterNResolver () .getResources (masterdatasourceconfig.mapper_location)); return sessionfactory.getObject (); }}Ces deux annotations sont expliquées ci-dessous:
** @ primaire **: logo ce haricot s'il y a plusieurs candidats de haricots similaires, le haricot
La priorité est considérée. Lors de la configuration de plusieurs sources de données, veillez à ce qu'il y ait une source de données principale et utilisez @Primary pour marquer le bean.
** @ MAPPERSCAN **: Scannez l'interface du mappeur et la gestion des conteneurs.
Il convient de noter que SQLSessionFactoryRef représente la définition d'une instance unique de SQLSessionFactory.
Une fois la configuration ci-dessus terminée, Druid peut être utilisé comme pool de connexion. Cependant, Druid n'est pas simplement un pool de connexion. On peut également dire qu'il s'agit d'une demande de surveillance. Il est livré avec une interface de surveillance Web, qui peut clairement voir des informations liées à SQL.
En utilisant la fonction de surveillance de Druid dans Springboot, il vous suffit d'écrire des classes StatViewServlet et WebStatFilter pour implémenter les services d'enregistrement et le filtrage des règles. Ici, nous pouvons écrire ces deux ensemble, en utilisant ** @ configuration ** et ** @ bean **.
Dans un souci de compréhension facile, les instructions de configuration pertinentes sont également écrites dans le code, donc je n'entrerai pas dans les détails ici.
Le code est le suivant:
@ConfigurationPublic class DruidConfiguration {@Bean public ServletRegistrationBean DruidStatViewServle () {// Registre Service ServletRegistrationBean ServletRegistrationBean = new ServletRegistrationBean (new StatViewServlet (), "/ druid / *"); // la liste blanche (représente vide, tout est accessible, séparé par des virgules pour plusieurs IP) ServletRegistrationBean.addinitAramètre ("Autoriser", "127.0.0.1"); // IP Blacklist (Dony a priorité sur Autoriser quand il y a une existence commune) ServletRegistrationBean.addinitAramètre ("Deny", "127.0.0.2"); // Définissez le nom d'utilisateur et le mot de passe de connexion servletRegistrationBean.AddInitParameter ("LoginUsername", "Pancm"); ServletRegistrationBean.AddInitParameter ("LoginPassword", "123456"); // s'il est possible de réinitialiser les données. ServletRegistrationBean.AddInitParameter ("Réinitiable", "false"); Return ServletRegistrationBean; } @Bean Public FilterRegistrationBean DruidStatFilter () {FilterRegistrationBean FilterRegistrationBean = new FilterRegistrationBean (new WebStatFilter ()); // Ajouter des règles de filtrage filterRegistrationBean.addurlPatterns ("/ *"); // Ajouter des informations de format qui n'ont pas besoin d'être ignorées FilterRegistrationBean.AdDinitParameter ("exclusions", "* .js, *. Gif, *. Jpg, *. Png, *. Css, *. Ico, / druid / *"); System.out.println ("Druid Initialisation avec succès!"); Return FilterRegistrationBean; }}Après avoir écrit, démarrez le programme, entrez: http://127.0.0.1:8084/druid/index.html dans le navigateur, puis entrez le nom d'utilisateur et le mot de passe défini pour accéder à l'interface Web.
Configuration de la source multi-données
Avant d'effectuer une configuration source multi-données, exécutez les scripts suivants dans les bases de données MySQL de Springboot et Springboot_Test respectivement.
- Script de la bibliothèque Springboot Créer un tableau `t_user` (` id` int (11) non null auto_increment commentaire `` ID d'auto-incrément '', `name` varchar (10) commentaire null par défaut` `name '',` `` `` int (2) commentaire null 'par défaut' Âge ', clés primaire (`id`)) moteur = innodb auto_increment = 15 charset par défaut = utf8 - script de spring_ liseth Tableau `t_student` (` id` int (11) pas null auto_increment, `name` varchar (16) par défaut null,` `` `` `int (11) par défaut null, clé primaire (` id`)) moteur = innodb auto_increment = 2 charset par défaut = utf8
Remarque: Pour être paresseux, la structure des deux tables est la même! Mais cela n'affectera pas le test!
Les informations sur ces deux sources de données ont été configurées dans Application.Properties, et la configuration a été publiée une fois dessus, donc je ne la publierai pas ici.
Ici, nous nous concentrerons sur la configuration de la deuxième source de données. Il est similaire à la MasterdatasourceConfig.java ci-dessus, la différence est qu'elle est différente de l'annotation ** @ primaire ** et du nom sans utiliser l'annotation ** @ primaire **. Il convient de noter que MasterdatasourceConfig.java analyse le package et le mappeur avec précision au répertoire, et il en va de même pour la deuxième source de données ici. Alors le code est le suivant:
@ Configuration @ MAPPERSCAN (BASEPACKAGES = CLUSTERDATASOURCECONFIG.PACKAGE, SQLSESSESSEFACTORYREF = "CLUSTERSQLSESSESSFACTORY") CLASS PUBLIQUE CLUSTERDATASOURCECONFIG {Static Final String package = "Com.pancm.dao.cluster"; Statique finale finale MAPPER_LOCATION = "CLASSPATH: MAPTER / CLUSTER / *. XML"; @Value ("$ {Cluster.Datasource.url}") URL de chaîne privée; @Value ("$ {Cluster.Datasource.Username}") Private String Username; @Value ("$ {cluster.datasource.password}") Mot de passe de chaîne privée; @Value ("$ {Cluster.Datasource.DriverClassName}") Private String DriverClass; // comme masterdatasourceconfig, ici @bean (name = "clusterDataSource") public dataSource ClusterDataSource () {druidDataSource dataSource = new DruidDataSource (); DataSource.setUrl (URL); DataSource.SetUsername (nom d'utilisateur); DataSource.SetPassword (mot de passe); DataSource.setDriverClassName (DriverClass); // comme masterdatasourceconfig, ici ... return dataSource; } @Bean (name = "ClusterTransactionManager") public DataSourceTransactionManager ClusterTransactionManager () {return new DataSourceTransactionManager (ClusterDataSource ()); } @Bean (name = "ClustersQlSessionFactory") public sqlSessionFactory ClustersQlSessionFactory (@Qualifier ("ClusterDataSource") DataSource ClusterDataSource) lance exception {final sqlSessionFactoryBean SessionFactory = new SQLSessionFactoryBean (); SessionFactory.SetDataSource (ClusterDataSource); sessionfactory.setMapperLocations (new PathMatchingResourcePatterNResolver (). GetResources (ClusterDataSourceConfig.mapper_location)); return sessionfactory.getObject (); }} Après avoir réussi à écrire la configuration, démarrez le programme et effectué des tests.
Utilisez des interfaces pour ajouter des données dans les bibliothèques Springboot et Springboot_Test, respectivement.
t_user
Post http: // localhost: 8084 / api / user {"name": "zhang san", "age": 25} {"name": "li si", "age": 25} {"name": "wang wu", "age": 25}t_student
Post http: // localhost: 8084 / api / étudiant {"name": "Student a", "Âge": 16} {"name": "Student B", "Age": 17} {"name": "Student C", "Age": 18}Après avoir réussi à ajouter des données, appelez différentes interfaces pour la requête.
demander:
Obtenir http: // localhost: 8084 / api / utilisateur? Name = li si
retour:
{"id": 2, "nom": "li si", "âge": 25}demander:
Obtenir http: // localhost: 8084 / api / étudiant? Name = étudiant C
retour:
{"id": 1, "nom": "Student C", "Age": 16}À partir des données, nous pouvons voir que plusieurs sources de données ont été configurées avec succès.
Implémentation de pagination de Pagehelper
PageHelper est un plugin de pagination pour Mybatis, ce qui est très utile! Hautement recommandé ici! ! !
PageHelper est très simple à utiliser, il vous suffit d'ajouter la dépendance de PageHelper dans Maven.
Les dépendances de Maven sont les suivantes:
<dependency> <proupId> com.github.pagehelper </rombasid> <ArtifactId> PageHelper-Spring-Boot-starter </ artifactId> <version> 1.2.3 </ version> </ Dependency>
Remarque: j'utilise la version Springboot ici! D'autres versions peuvent également être utilisées.
Après avoir ajouté des dépendances, il vous suffit d'ajouter la configuration ou le code suivant.
Le premier type est ajouté dans application.properties ou application.yml
PageHelper: HelperDialect: MySQL Offsetaspagenum: True RowboundsWithCount: Vrai raisonnable: Faux
Le deuxième type est ajouté dans la configuration mybatis.xml
<bean id = "sqlSessionFactory"> <propriété name = "dataSource" ref = "dataSource" /> <! - Scan the mapping.xml fichier -> <propriété name = "Mappelocations" value = "ClassPath: Mapper / *. name = "Properties"> <value> helperDialect = mysql offSetSpageNum = true rowboundswithCount = true raisonnable = false </value> </ propriété> </ bean> </ray> </ propriété> </ bean>
Le troisième type est ajouté dans le code et l'initialise lors du démarrage du programme à l'aide de l'annotation ** @ bean **.
@Bean public PageHelper PageHelper () {PageHelper PageHelper = new PageHelper (); Propriétés Properties = New Properties (); // database properties.setProperty ("helperdialect", "mysql"); // s'il faut utiliser le décalage du paramètre comme propriétés de pagenum.setProperty ("offsetaspagenum", "true"); // Interroger les propriétés de nombre.SetProperty ("RowBoundsWithCount", "True"); // s'il faut rationaliser les propriétés de pagination.SetProperty ("raisonnable", "false"); PageHelper.SetProperties (propriétés); }Parce que nous utilisons ici plusieurs sources de données, la configuration ici est légèrement différente. Nous devons le configurer dans SessionFactory. Ici, nous apportons des modifications correspondantes à MasterdatasourceConfig.java. Dans la méthode MastersQLSessionFactory, ajoutez le code suivant.
@Bean (name = "MastersQlSessionFactory") @primary public SqlSessionFactory MastersQLSessionFactory (@qualifier ("MasterDataSource") DataSource MasterDataSource) lance une exception {final sqlSessionFactoryBean SessionFactory = New SqlSessionFactoryBean (); SessionFactory.SetDataSource (MasterDataSource); sessionfactory.setMapperLocations (new PathMatchingResourcePatterNResolver () .getResources (masterdatasourceconfig.mapper_location)); // Pagination plug-in interceptor interceptor = new PageInterceptor (); Propriétés Properties = New Properties (); // database properties.setProperty ("helperdialect", "mysql"); // s'il faut utiliser le décalage du paramètre comme propriétés de pagenum.setProperty ("offsetaspagenum", "true"); // Interroger les propriétés de nombre.SetProperty ("RowBoundsWithCount", "True"); // s'il faut rationaliser les propriétés de pagination.SetProperty ("raisonnable", "false"); interceptor.setproperties (propriétés); sessionFactory.setPlugins (new interceptor [] {interceptor}); return sessionfactory.getObject (); }Remarque: Lorsque d'autres sources de données souhaitent également paginer, veuillez vous référer au code ci-dessus.
Ce que vous devez noter ici est le paramètre raisonnable, ce qui signifie la pagination de rationalisation, et la valeur par défaut est fausse. Si ce paramètre est défini sur true, la première page sera interrogée lors du pagenum <= 0 et des pages Pagenum> (lorsque le nombre total dépasse), la dernière page sera interrogé. Lorsqu'il est faux par défaut, la requête est directement basée sur les paramètres.
Après la définition de PageHelper, si vous l'utilisez, il vous suffit d'ajouter PageHelper.startPage(pageNum,pageSize); Devant la requête SQL. Si vous souhaitez connaître le nombre total, achetez-le après l'instruction SQL Query et ajoutez page.getTotal() .
Exemple de code:
public list <T> findByListEntity (t entité) {list <t> list = null; essayez {page <?> page = pagehelper.startPage (1,2); System.out.println (getClassName (entité) + "Définissez deux données sur la première page!"); list = getMapper (). findByListEntity (entité); System.out.println ("Il y a un total de:" + page.getTotal () + "Données, et le retour réel est:" + list.size () + "Two Data!"); } catch (exception e) {logger.error ("requête" + getClassName (entité) + "a échoué! La raison en est:", e); } Retour List; }Une fois le code écrit, le test final commence.
Interrogez toutes les données de la table T_User et paginez-la.
demander:
Obtenir http: // localhost: 8084 / API / utilisateur
retour:
[{"id": 1, "name": "Zhang San", "Age": 25}, {"id": 2, "name": "li si", "age": 25}]Impression de console:
Commencez à interroger ...
L'utilisateur définit deux données sur la première page!
2018-04-27 19: 55: 50.769 DEBUG 6152 --- [IO-8084-EXEC-10] CPDMUSERDAO.FINDBYLISTENTITY_COUNT: ==> Préparation: Sélectionnez Count (0) FROM T_USER où 1 = 1
2018-04-27 19: 55: 50.770 DEBUG 6152 --- [IO-8084-EXEC-10] CPDMUSERDAO.FINDBYLISTENTITY_COUNT: ==> Paramètres:
2018-04-27 19: 55: 50.771 DEBUG 6152 --- [IO-8084-EXEC-10] CPDMUSERDAO.FINDBYLISTENTITY_COUNT: <== Total: 1
2018-04-27 19: 55: 50.772 DEBUG 6152 --- [IO-8084-EXEC-10] cpdao.master.userdao.findByliSentity: ==> Préparation: Sélectionnez ID, nom, âge de T_User où 1 = 1 limite?
2018-04-27 19: 55: 50.773 DEBUG 6152 --- [IO-8084-EXEC-10] CPDAO.Master.Userdao.FindBylistEntity: ==> Paramètres: 2 (Integer)
2018-04-27 19: 55: 50.774 DEBUG 6152 --- [IO-8084-EXEC-10] CPDAO.Master.Userdao.FindByListentity: <== Total: 2
Il y a un total de: 3 éléments de données, et le retour réel est: 2 deux éléments de données!
Interrogez toutes les données de la table T_Student et paginez-la.
demander:
Obtenez http: // localhost: 8084 / API / Student
retour:
[{"id": 1, "nom": "Student A", "Age": 16}, {"id": 2, "nom": "Student B", "Age": 17}]Impression de console:
Commencez à interroger ...
Studnet définit deux données sur la première page!
2018-04-27 19: 54: 56.155 DEBUG 6152 --- [NIO-8084-EXEC-8] CPDCSFINDBYLISTENTITY_COUNT: ==> Préparation: sélectionnez Count (0) From t_student Where 1 = 1
2018-04-27 19: 54: 56.155 DEBUG 6152 --- [NIO-8084-EXEC-8] CPDCSFINDBYLISTENTITY_COUNT: ==> Paramètres:
2018-04-27 19: 54: 56.156 DEBUG 6152 --- [NIO-8084-EXEC-8] CPDCSFINDBYLISTENTITY_COUNT: <== Total: 1
2018-04-27 19: 54: 56.157 DEBUG 6152 --- [NIO-8084-EXEC-8] CPDCSTUDENTDAO.
2018-04-27 19: 54: 56.157 DEBUG 6152 --- [NIO-8084-EXEC-8] CPDCSTUDENTDAO.FINDBYLISTENTITY: ==> Paramètres: 2 (entier)
2018-04-27 19: 54: 56.157 DEBUG 6152 --- [NIO-8084-EXEC-8] CPDCSTUDENTDAO.FINDBYLISTENTITY: <== Total: 2
Il y a un total de: 3 éléments de données, et le retour réel est: 2 deux éléments de données!
Une fois la requête terminée, jetons un coup d'œil à l'interface de surveillance de Druid. Entrez dans le navigateur: http://127.0.0.1:8084/druid/index.html
Les enregistrements d'opération peuvent être clairement vus!
Si vous voulez en savoir plus sur Druid, vous pouvez consulter la documentation officielle!
Conclusion
Cet article a finalement été terminé. Lors de l'écriture du code, j'ai rencontré de nombreux problèmes, puis j'ai lentement essayé et trouvé des informations pour les résoudre. Cet article ne présente que ces utilisations connexes très brièvement et peut être plus compliquée dans les applications réelles.
Article de référence: https://www.bysocket.com/?p=1712
Adresse officielle de Durid: https://github.com/alibaba/druid
Adresse officielle de Pagehelper: https://github.com/pagehelper/mybatis-pagehelper
J'ai mis le projet sur github: https://github.com/xuwujing/springboot, vous pouvez également le télécharger localement: cliquez ici
Résumer
Ce qui précède est l'intégralité du contenu de cet article. J'espère que le contenu de cet article a une certaine valeur de référence pour l'étude ou le travail de chacun. Si vous avez des questions, vous pouvez laisser un message pour communiquer. Merci pour votre soutien à wulin.com.