Prefacio
Este artículo cuenta principalmente la historia de SpringBoot que integra MyBatis, Druid y PageHelper e implementando múltiples fuentes de datos y paginación. Entre ellos, Springboot integra mybatis, que se ha descrito en un artículo anterior, por lo que no lo explicaré demasiado aquí. El enfoque se centra en cómo configurar Druid y PageHelper en múltiples fuentes de datos.
Introducción y uso de druidas
Antes de usar Druid, echemos un vistazo breve a Druid.
Druid es un grupo de conexión de base de datos. ¡Se puede decir que Druid es el mejor grupo de conexión de base de datos en la actualidad! Es muy favorecido por los desarrolladores por sus excelentes características, rendimiento y escalabilidad.
Druid ha implementado más de 600 aplicaciones en Alibaba, y ha pasado por la rigurosa prueba de implementación a gran escala en entornos de producción durante más de un año. ¡Druid es un grupo de conexión de base de datos desarrollado por Alibaba llamado monitoreo!
Al mismo tiempo, Druid no es solo un grupo de conexión de base de datos, el núcleo de Druid incluye principalmente tres partes:
Las funciones principales de Druid son las siguientes:
No hablaré sobre la introducción, consulte la documentación oficial para obtener más detalles.
Entonces comencemos a presentar cómo usar Druid.
En primer lugar, la dependencia de Maven, solo agregue el frasco de druidas.
<Spendency> <MoupRoD> com.alibaba </groupid> <artifactId> druid </artifactid> <versión> 1.1.8 </versión> </pendency>
En términos de configuración, lo principal es agregarlo en Application.Properties o Application.yml de la siguiente manera.
Nota: Debido a que uso dos fuentes de datos aquí, es solo un poco diferente. Las instrucciones para la configuración de Druid ya se detallan a continuación, por lo que no lo explicaré aquí.
## fuente de datos predeterminada maestro.datasource.url = jdbc: mysql: // localhost: 3306/springboot? useUnicode = true & caracterSencoding = utf8 & tamptMultiqueries = tru ERMASTER.DATASOURCE.USERNAME = RootMaster.DataSource.password = 123456master.datasource.drivulssname = com.mysql.jdbc.driver ## Otra fuente de datos cluster.dataSource.url = jdbc: mysql: // localhost: 3306/springboot_test? Useunicode = true & caracteresCoding = utf8cluster.datasource.username = rootcluster.datasource.password = 123456cluster.dataSource.driverClassName Información de configuración para el grupo de conexión # Inicializar el tamaño, mínimo, máximo spring.dataSource.type = com.alibaba.druid.pool.druiddatasourcespring.datasource.initialsize = 5 spring.dataSource.minidle = 5 spring.datasource.maxactive = 20 # Configurar el tiempo para obtener la conexión de espera en la conexión de espera en la espera de tiempo de espera de esperar el tiempo. spring.dataSource.maxwait = 60000 # Configure cuánto tiempo lleva realizar un intervalo de detección para detectar conexiones inactivas que deben cerrarse, en milisegundos Spring.dataSource.timebetweeVictionRunsmillis = 60000 # Configurar el tiempo de supervivencia para sobrevivir en el grupo, en la primavera. spring.dataSource.ValidationQuery = Seleccionar 1 de dual spring.dataSource.testwhileidle = true spring.datasource.testonborrow = false spring.dataSource.testonreturn = false # abre pscache y especifique el tamaño de pscache en cada conexión spring.dataSource.poolPreparedstatements = true Spring.datasource.maxPoolPreparedStatementPonnectsize = 20 # Configurar filtros para el monitoreo de estadísticas interceptadas. Después de eliminarlo, la interfaz de monitoreo SQL no se puede contar. 'Wall' se usa para Firewall Spring.datasource.filters = stat, wall, log4j # abrir la función mergesql a través de la propiedad ConnectProperties; Registros SQL lentos Spring.datasource.ConnectionProperties = Druid.stat.mergesql = true; druid.stat.slowsqlmillis = 5000
Después de agregar con éxito el archivo de configuración, escribamos clases relacionadas con Druid.
Primero, la clase MasterDataSourCeConfig.java, que es la clase de configuración de fuente de datos predeterminada.
@Configuration@mapperscan (basepackages = masterDataSourCeconfig.package, sqlsessionFactoryRef = "MastersqlSessionFactory") public class MasterDataSourCeconfig {paquete de cadena final estática = "com.pancm.dao.master"; String final estática mapper_location = "classpath: mapper/master/*. xml"; @Value ("$ {Master.DataSource.url}") URL de cadena privada; @Value ("$ {Master.DataSource.Username}") Nombre de usuario de cadena privada; @Value ("$ {Master.DataSource.password}") PRIVADA PASSACIÓN DE CADA; @Value ("$ {Master.dataSource.DrivClassName}") String private DriverClassName; @Value ("$ {spring.datasource.initialsize}") private int inicialSize; @Value ("$ {spring.dataSource.minidle}") private int minidle; @Value ("$ {spring.dataSource.maxactive}") private int maxactive; @Value ("$ {spring.dataSource.maxwait}") private int maxwait; @Value ("$ {spring.dataSource.timebetweenEvictionRunsmillis}") privado int timetweenEvictionRunsMillis; @Value ("$ {spring.dataSource.MinevictableIdletimemillis}") private int min mineVictableIdletImillis; @Value ("$ {spring.dataSource.ValidationQuery}") Private String ValidationQuery; @Value ("$ {spring.dataSource.test whelleidle}") Prueba booleana privada WhipleIdle; @Value ("$ {spring.datasource.testonborrow}") privado boolean testonborrow; @Value ("$ {spring.dataSource.testonreturn}") Private boolean testOnreturn; @Value ("$ {spring.dataSource.poolpreparedStatements}") privado boolean piscolpreparedStatements; @Value ("$ {spring.dataSource.maxPoolPreparedStatementConConnectsize}") private int maxPoolPreparedStatementPonConnectsize; @Value ("$ {spring.dataSource.filters}") filtros de cadena privada; @Value ("{Spring.DataSource.ConnectionProperties}") privado String ConnectionProperties; @Bean (name = "MasterDataSource") @Primary Public DataSource MasterDataSource () {DruidDataSource DataSource = new DruidDataSource (); dataSource.SetUrl (URL); dataSource.setUsername (nombre de usuario); dataSource.setPassword (contraseña); dataSource.setDrivClassName (DriverClassName); // Configuración específica DataSource.SetInitialSize (InitialSize); dataSource.setminidle (minidle); DataSource.SetMaxActive (MaxActive); DataSource.SetMaxWait (MaxWait); DataSource.SetTimeBetweenEvictionRunsMillis (TimetweenEvictionRunsMillis); dataSource.SetMinevictableIdletimemillis (minevictableidletimillis); DataSource.SetValidationQuery (ValidationQuery); dataSource.Settest WhipleIdle (test WhipleIdle); DataSource.SettonBorrow (testOnBorrow); dataSource.settestonreturn (testOnreturn); dataSource.setPoolPreparedStatements (PoolPreparedStatements); DataSource.SetMaxPoolPreparedStatementPonConnectsize (MaxPoolPreparedStatementPonnectsize); intente {dataSource.setFilters (filtros); } Catch (Sqlexception e) {E.PrintStackTrace (); } DataSource.SetConnectionProperties (ConnectionProperties); devolver datos de datos; } @Bean (name = "MasterTransactionManager") @Primary public dataSourCetransactionManager MasterTransactionManager () {return New DataSourCetransactionManager (MasterDataSource ()); } @Bean (name = "MastersqlSessionFactory") @Primary Public SQLSessionFactory MastersqlSessionFactory (@Qualifier ("MasterDataSource") DataSource MasterDataSource) lanza la excepción {final sqlSessionFactoryFactory = new sqlSessionFactoryBean (); SessionFactory.SetDataSource (MasterDataSource); SessionFactory.SetMapperLocations (New PathMatchEnseurCePternResolver () .getResources (MasterDataSourCeConfig.mapper_location)); return sessionFactory.getObject (); }}Estas dos anotaciones se explican a continuación:
**@primaria **: logotipo este frijol Si hay múltiples candidatos de frijol similares, el bean
Se considera la prioridad. Al configurar múltiples fuentes de datos, tenga cuidado de que debe haber una fuente de datos primaria y usar @Primary para marcar el bean.
**@mapperscan **: escanee la interfaz mapper y la administración de contenedores.
Cabe señalar que SQLSessionFactoryRef representa la definición de una instancia única de SQLSessionFactory.
Después de completar la configuración anterior, Druid se puede usar como un grupo de conexión. Sin embargo, Druid no es simplemente un grupo de conexión. También se puede decir que es una aplicación de monitoreo. Viene con una interfaz de monitoreo web, que puede ver claramente la información relacionada con SQL.
Utilizando la función de monitoreo de Druid en SpringBoot, solo necesita escribir clases de StatViewServlet y WebStatFilter para implementar servicios de registro y reglas de filtrado. Aquí podemos escribir estos dos juntos, usando **@Configuration ** y **@bean **.
En aras de una fácil comprensión, las instrucciones de configuración relevantes también se escriben en el código, por lo que no entraré en detalles aquí.
El código es el siguiente:
@ConfigurationPublic Class DruidConfiguration {@Bean Public ServletregistrationBean DruidStatViewServle () {// Servicio de registro ServletregistrationBean ServletregistrationBean = new ServletregistrationBean (nuevo statViewServlet (), "/druid/*"); // Whitelist (representa vacío, se puede acceder a todos, separados por comas para múltiples ips) servletregistrationBean.addinitParameter ("permitir", "127.0.0.1"); // Lista negra IP (Dony tiene prioridad sobre permitido cuando hay una existencia común) ServletregistrationBean.addinitParameter ("Deny", "127.0.0.2"); // Establecer el nombre de usuario de inicio de usuario y la contraseña servletregistrationBean.addinitParameter ("LoginUsername", "Pancm"); servletregistrationBean.addinitParameter ("LoginPassword", "123456"); // si es posible restablecer datos. servletregistrationBean.addinitParameter ("resetenible", "falso"); regreso servletregistrationbean; } @Bean public FilterRegistrationBean DruidStatFilter () {FilterRegistrationBean FilterRegistrationBean = new FilterRegistrationBean (new WebStatFilter ()); // Agregar reglas de filtrado FilterRregistrationBean.addurlPatterns ("/*"); // Agregar información de formato que no necesita ser ignorado FilterRegistrationBean.addinitParameter ("EXCLUSIONION", "*.js,*. Gif,*. Jpg,*. Png,*. Css,*. ICO,/Druid/*"); System.out.println ("¡Inicialización de Druid con éxito!"); return filtreRregistrationBean; }}Después de escribir, inicie el programa, ingrese: http://127.0.0.1:8084/druid/index.html en el navegador y luego ingrese el nombre de usuario y la contraseña establecer para acceder a la interfaz web.
Configuración de origen de múltiples datos
Antes de realizar la configuración de la fuente de múltiples datos, ejecute los siguientes scripts en las bases de datos MySQL de SpringBoot y SpringBoot_Test respectivamente.
-Script of SpringBoot Biblioteca Crear tabla `t_user` (` id` int (11) no nulo automo_increment comentario 'ID de autoincremento', `name` varchar (10) NULL NULL comment 'name',` Age` int (2) NULL NULL 'Age', Key (`id`` id`)) Engine = innodb Auto_increment = 15 predeterminado = UTF8-Scripe de scripe_tate de scripe_tate `t_student` (` id` int (11) no nulo auto_incement, `name` varchar (16) NULL predeterminado,` Age` int (11) NULL predeterminado, clave primaria (`id`)) motor = innodb Auto_Increment = 2 Charset predeterminado = UTF8)
Nota: ¡Para ser perezoso, la estructura de las dos tablas se hace igual! ¡Pero no afectará la prueba!
La información sobre estas dos fuentes de datos se ha configurado en Application.Properties, y la configuración se ha publicado una vez, por lo que no la publicaré aquí.
Aquí nos centraremos en la configuración de la segunda fuente de datos. Es similar al MasterDataSourCeconfig.java anterior, la diferencia es que es diferente de la anotación y el nombre **@primario ** sin usar la anotación **@primaria **. Cabe señalar que MasterDataSourCeconfig.java Scans Package y Mapper con precisión al directorio, y lo mismo es cierto para la segunda fuente de datos aquí. Entonces el código es el siguiente:
@Configuration@mapperscan (basepackages = clusterDataSourCeconfig.package, sqlsessionFactoryRef = "clustersqlsessionfactory") public classdataSourCeconfig {static final string paquete = "com.pancm.dao.cluster"; String final estática mapper_location = "classpath: mapper/cluster/*. xml"; @Value ("$ {cluster.datasource.url}") url de cadena privada; @Value ("$ {cluster.dataSource.username}") Nombre de usuario de cadena privada; @Value ("$ {cluster.dataSource.password}") contraseña de cadena privada; @Value ("$ {cluster.dataSource.driverClassName}") privado cadena controladora; // Al igual que MasterDataSourCeconfig, aquí @Bean (name = "ClusterDataSource") Public DataSource ClusterDataSource () {DruidDataSource DataSource = new DruidDataSource (); dataSource.SetUrl (URL); dataSource.setUsername (nombre de usuario); dataSource.setPassword (contraseña); dataSource.setDrivClassName (DriverClass); // como MasterDataSourCeconfig, aquí ... devuelve los datos de datos; } @Bean (name = "clusterTransactionManager") public dataSourCetransactionManager ClusterTransactionManager () {return New DataSourCetransactionManager (clusterDataSource ()); } @Bean (name = "ClustersqlSessionFactory") public sqlSessionFactory ClustersqlSessionFactory (@Qualifier ("ClusterDataSource") DataSource ClusterDataSource) lanza la excepción {final sqlSessionBeanFactory = new sqlSessionFactoryBean (); SessionFactory.SetDataSource (ClusterDataSource); SessionFactory.SetMapperLocations (New PathMatchingResourCePternResolver (). GetResources (ClusterDataSourCeconfig.mapper_location)); return sessionFactory.getObject (); }} Después de escribir con éxito la configuración, inicie el programa y realice pruebas.
Use interfaces para agregar datos en bibliotecas SpringBoot y SpringBoot_Test, respectivamente.
t_user
Post http: // localhost: 8084/api/user {"name": "zhang san", "edad": 25} {"nombre": "li si", "edad": 25} {"nombre": "wang wu", "edad": 25}: 25}t_studente
Post http: // localhost: 8084/api/student {"nombre": "estudiante a", "edad": 16} {"nombre": "estudiante b", "edad": 17} {"nombre": "estudiante c", "edad": 18}Después de agregar con éxito datos, llame a diferentes interfaces para consultar.
preguntar:
Obtener http: // localhost: 8084/api/user? Name = li si si
devolver:
{"id": 2, "nombre": "li si", "edad": 25}preguntar:
Obtener http: // localhost: 8084/API/Student? Name = Student C
devolver:
{"id": 1, "nombre": "estudiante c", "edad": 16}A partir de los datos, podemos ver que múltiples fuentes de datos se han configurado con éxito.
Implementación de paginación de PageHelper
PageHelper es un complemento de paginación para MyBatis, ¡lo cual es muy útil! ¡Muy recomendable aquí! ! !
PageHelper es muy simple de usar, solo necesita agregar la dependencia de PageHelper en Maven.
Las dependencias de Maven son las siguientes:
<Spendency> <MoupRoD> com.github.pagehelper </groupid> <artifactid> pageHelper-spring-boot-starter </artifactid> <versión> 1.2.3 </versión> </pendency>
Nota: ¡Uso la versión SpringBoot aquí! También se pueden usar otras versiones.
Después de agregar dependencias, solo necesita agregar la siguiente configuración o código.
El primer tipo se agrega en application.properties o application.yml
PageHelper: helperdialect: mysql offsetSpagenum: verdadero rowboundswithcount: verdadero razonable: falso
El segundo tipo se agrega en la configuración mybatis.xml
<bean id = "sqlSessionFactory"> <Property name = "dataSource" ref = "dataSource"/> <!-escanear el archivo mapping.xml-> <propiedad name = "mapperLocations" value = "classpath: mapper/*. xml"> </propiedad> <!-Configuración del complemento de Paging-> <Nombre de propiedad = "Nombre de la propiedad" <RAray <RARAYRAY <RARARATRAYRAY "<RACRAYRAYRAY> <RArizeShRiceS" <RArriz> <RArizi <value> helperdialect = mysql offsetSpagenum = True RowBoundSwithCount = True RAZENTABLE = FALSE </Value> </property> </bean> </array> </property> </bean>
El tercer tipo se agrega en el código y lo inicializa al comenzar el programa usando la anotación **@bean **.
@Bean public PageHelper PageHelper () {PageHelper PageHelper = new PageHelper (); Propiedades Propiedades = New Properties (); // propiedad de la base de datos.setProperty ("helperdialect", "mysql"); // si se debe usar el desplazamiento de parámetros como Pagenum Properties.SetProperty ("OffSetSpagenum", "True"); // si consultar las propiedades de recuento.setProperty ("rowboundswithcount", "verdadero"); // si racionalizar las propiedades de paginación.setProperty ("razonable", "falso"); PageHelper.SetProperties (Propiedades); }Debido a que estamos utilizando múltiples fuentes de datos aquí, la configuración aquí es ligeramente diferente. Necesitamos configurarlo en SessionFactory. Aquí hacemos modificaciones correspondientes a MasterDataSourCeconfig.java. En el método MastersQLSessionFactory, agregue el siguiente código.
@Bean (name = "MastersqlSessionFactory") @Primary Public SQLSessionFactory MastersqlSessionFactory (@Qualifier ("MasterDataSource") DataSource MasterDataSource) lanza la excepción {final sqlSessionFactory SessionFactory = new sqlSessionFactoryBean (); SessionFactory.SetDataSource (MasterDataSource); SessionFactory.SetMapperLocations (New PathMatchEnseurCePternResolver () .getResources (MasterDataSourCeConfig.mapper_location)); // Interceptor de interceptor de complemento de paginación = nuevo PageInterceptor (); Propiedades Propiedades = New Properties (); // propiedad de la base de datos.setProperty ("helperdialect", "mysql"); // si se debe usar el desplazamiento de parámetros como Pagenum Properties.SetProperty ("OffSetSpagenum", "True"); // si consultar las propiedades de recuento.setProperty ("rowboundswithcount", "verdadero"); // si racionalizar las propiedades de paginación.setProperty ("razonable", "falso"); interceptor.setProperties (propiedades); sessionFactory.setPlugins (nuevo interceptor [] {interceptor}); return sessionFactory.getObject (); }Nota: Cuando otras fuentes de datos también desean paginar, consulte el código anterior.
Lo que debe tener en cuenta aquí es el parámetro razonable, lo que significa racionalización de la paginación, y el valor predeterminado es falso. Si este parámetro se establece en True, la primera página se consultará cuando pagenum <= 0 y pagenum> páginas (cuando el número total exceda), se consultará la última página. Cuando falsa por defecto, la consulta se basa directamente en los parámetros.
Después de configurar PageHelper, si lo usa, solo necesita agregar PageHelper.startPage(pageNum,pageSize); Frente a la consulta SQL. Si desea saber el número total, cómprelo después de la instrucción SQL de consulta y agregue page.getTotal() .
Ejemplo de código:
Lista pública <T> findByListEntity (t entidad) {list <t> list = null; Pruebe {Page <?> Page = PageHelper.StartPage (1,2); System.out.println (getClassName (entidad)+"¡Establezca dos datos en la primera página!"); list = getMapper (). FindByListEntity (entidad); System.out.println ("Hay un total de:"+page.gettotal ()+"datos, y el retorno real es:"+list.size ()+"¡Dos datos!"); } catch (excepción e) {logger.error ("consulta"+getClassName (entidad)+"falló! La razón es:", e); } Lista de retorno; }Después de que se escribe el código, comienza la prueba final.
Consulte todos los datos en la tabla T_USER y pagatelos.
preguntar:
Obtener http: // localhost: 8084/API/usuario
devolver:
[{"id": 1, "nombre": "Zhang San", "edad": 25}, {"id": 2, "nombre": "li si", "edad": 25}]Impresión de consola:
Empiece a consultar ...
¡El usuario establece dos datos en la primera página!
2018-04-27 19: 55: 50.769 DEBUG 6152 --- [IO-8084-EXEC-10] CPDMUSERDAO.FINDBYLISTENTITY_COUNT: ==> Preparación: Seleccione recuento (0) de t_user donde 1 = 1 1
2018-04-27 19: 55: 50.770 DEBUG 6152 --- [IO-8084-EXEC-10] CPDMUSERDAO.FINDBYLISTENTITY_COUNT: ==> Parámetros:
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.findbyListEntity: ==> Preparación: seleccionar ID, nombre, edad de t_user donde 1 = 1 límite?
2018-04-27 19: 55: 50.773 DEBUG 6152 --- [IO-8084-EXEC-10] cpdao.master.userdao.findbyListEntity: ==> Parámetros: 2 (entero)
2018-04-27 19: 55: 50.774 DEBUG 6152 --- [IO-8084-EXEC-10] cpdao.master.userdao.findbyListEntity: <== Total: 2
Hay un total de: 3 piezas de datos, y el retorno real es: ¡2 dos datos!
Consulte todos los datos en la tabla T_Student y pagatelos.
preguntar:
Obtener http: // localhost: 8084/API/estudiante
devolver:
[{"id": 1, "nombre": "estudiante a", "edad": 16}, {"id": 2, "nombre": "estudiante b", "edad": 17}]Impresión de consola:
Empiece a consultar ...
¡Studnet establece dos datos en la primera página!
2018-04-27 19: 54: 56.155 Debug 6152 --- [NIO-8084-EXEC-8] CPDCSFINDBYLISTENTITY_COUNT: ==> Preparación: Seleccione Recuento (0) de T_Student Where 1 = 1
2018-04-27 19: 54: 56.155 Debug 6152 --- [NIO-8084-EXEC-8] CPDCSFINDBYLISTENTITY_COUNT: ==> Parámetros:
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.FindByListEntity: ==> Preparación: Seleccionar ID, nombre, edad de T_Student Where 1 = 1 Limit?
2018-04-27 19: 54: 56.157 DEBUG 6152 --- [NIO-8084-EXEC-8] CPDCStudentdao.FindByListEntity: ==> Parámetros: 2 (entero)
2018-04-27 19: 54: 56.157 DEBUG 6152 --- [NIO-8084-EXEC-8] CPDCStudentdao.FindByListEntity: <== Total: 2
Hay un total de: 3 piezas de datos, y el retorno real es: ¡2 dos datos!
Después de completar la consulta, echemos un vistazo a la interfaz de monitoreo de Druid. Ingrese en el navegador: http://127.0.0.1:8084/druid/index.html
¡Los registros de operación se pueden ver claramente!
Si desea saber más sobre Druid, ¡puede consultar la documentación oficial!
Conclusión
Este artículo finalmente se terminó. Al escribir el código, encontré muchos problemas, y luego intenté lentamente y encontré información para resolverlo. Este artículo solo presenta estos usos relacionados muy brevemente, y puede ser más complicado en las aplicaciones reales.
Artículo de referencia: https://www.bysocket.com/?p=1712
Dirección oficial de Durid: https://github.com/alibaba/druid
PageHelper Dirección oficial: https://github.com/pagehelper/mybatis-pagehelper
Puse el proyecto en GitHub: https://github.com/xuwujing/springboot, también puede descargarlo localmente: haga clic aquí
Resumir
Lo anterior es todo el contenido de este artículo. Espero que el contenido de este artículo tenga cierto valor de referencia para el estudio o el trabajo de todos. Si tiene alguna pregunta, puede dejar un mensaje para comunicarse. Gracias por su apoyo a Wulin.com.