Spanish Conexion remota con base de datos ¿ Cual es la opción más rápida/ cómoda de programar en la App ?

amminf

Active Member
Licensed User
Longtime User
Buenos días,

Como me comentan, abro un nuevo hilo

Me dispongo a emprender el desarrollo de una app b4a para control de almacen con smartphones.
Mi duda es la del compañero que inició el posteo: Usar PHP o usar JRDC2
Parece que el hilo terminó con la victoria de PHP.

Al ser una App que funciona en un unico almacen, tendra acceso al server local, por lo cual no es problema el tipo de server y el software necesario

¿ Es PHP lo más apropiado ? En mi caso, me gustaria que la programacion b4a fuese lo más b4a posible, es decir, manejada con objetos comunmente usados

Agradezco cualquier opinión
 

Gabino A. de la Gala

Well-Known Member
Licensed User
Longtime User
Eso como todo, depende de los conocimientos y medios de cada uno.
En mi caso, como php no controlo demasiado y el entorno B4X me gusta bastante, yo me he decantado por el JRDC2.
Hay ejemplos en el foro muy completos que puedes tomar como punto de partida.

Un ejemplo que creo te puede resultar interesante es el siguiente: TUTORIAL JRDC2
 

Duque

Active Member
Licensed User
Longtime User
Se recomienda JRDC, pero he tenido malas experiencias con JRDC sobre todo por la instalación en VPS o servidores dedicados, casi siempre hay un error de memoria u otro.

No voy a recomendar PHP, pero para mis proyectos que necesitan una conexión a maria, MySQL o cualquier otra BD, siempre uso php y conecto con PDO.

Si JRDC no me hubiera dado tantos problemas para correr en vps y dedicado, sin duda fuera la mejor opción: es más rápido y 100% lenguaje b4x
 

josejad

Expert
Licensed User
Longtime User
Hola:

No es que sea más o menos apropiado, simplemente son soluciones distintas y dependerán de tus recursos.

Si tienes un host php+mysql, por ejemplo, tendrás que decantarte por php.
Si por el contrario tienes un VPS, podrás usar jRDC2 y usar una solución totalmente B4X

Los problemas que puedes encontrar con jRDC2, son solucionables, igual que los que puedas encontrar con PHP.

¿Dispones de algún tipo de servidor?
 

EnriqueGonzalez

Well-Known Member
Licensed User
Longtime User
Hola! si quires usar JRDC2 sin las complicaciones que implica tener un VPS te puedo recomendar mi servicio de hosting especializado en soluciones b4x.
 

TILogistic

Expert
Licensed User
Longtime User
Por el costo (30USD Anual) es mejor un hosting, en estos ya tienen pre-instalados PHP, Pyton y otos, Node o Apache, Base de datos MySQL y PostgreSQL
y puedes usar como tu desees.
Eje.
Php + Apace + MySQL + RestFull api (Slim, laravel, etc)
JavaScripts + Node + Restful Api (Express,etc)

Es decir, Tus App se comunicaran con tu base de datos con llamadas a API Rest.

Además.
No tendrás problemas con los certificados SSL.
Múltiples Correros , dominios, Subdominios, etc.
Otra ventaja es la administración.

1727116820572.png

1727116880605.png

1727116937750.png

1727117035592.png
 
Last edited:
Hola @amminf yo lo he hecho con el JDBC de Mysql via TCP/IP com.mysql.jdbc.Driver


1) Funciona bien! pero tiene unos trucos, para empezar hay que indicar unas cosas en el "manifest" asi:
B4X:
     'Permisos para poder acceder al server mysql
         AddPermission("android.permission.INTERNET")
         AddPermission("android.permission.ACCESS_NETWORK_STATE")

2) En la sección o pestaña "Starter" hay que agregar el modulo, y no en "main" como lo indica en el tutorial ya que no te funcionara en "run build"
Starter

B4X:
Sub Process_Globals
    Public mysql As JdbcSQL Private driver As String = "com.mysql.jdbc.Driver"
    Private Username As String = "RED"
    Private Password As String = "-- tu clave --"
End Sub


3) debes crear todo en forma de funciones dentro del "starter" para poder usar la libreria y llamarlo desde el "main" y pasar parametros via "map" por ejemplo:

-> En "starter"

En "Starter":
      Sub mysql_ejec_consulta_resultado(mysql_datos As Map) As ResumableSub
          Dim mysql_user = mysql_datos.Get("mysql_user_map") As String
          Dim mysql_ip = mysql_datos.Get("mysql_ip_map") As String
          Dim mysql_db = mysql_datos.Get("mysql_db_map") As String
          Dim mysql_consulta = mysql_datos.Get("mysql_consulta_map") As String
          Dim mysql_consulta_contar = mysql_datos.Get("mysql_consulta_contar_map") As String
          
          Log("MYSQL JDBC: User: " & mysql_user)
          Log("MYSQL JDBC: Ip: " & mysql_ip)
          Log("MYSQL JDBC: Db: " & mysql_db)
          Log("MYSQL JDBC: Consulta: " & mysql_consulta)
          Log("MYSQL JDBC: Consulta contar: " & mysql_consulta_contar)
      
          'Se define el resultado a devolver
          Dim mysql_resultado As Map
          mysql_resultado.Initialize
              
          Log ("MYSQL JDBC: mysql_resultado As Map Inicializado")
          
          mysql.InitializeAsync("mysql", driver, "jdbc:mysql://"& mysql_ip &"/"& mysql_db &"", mysql_user, Password)
          Wait For MySQL_Ready (Success As Boolean)
          Log ("MYSQL JDBC: Success: " & Success)
          mysql_resultado.Put("Success", Success)
          If Success = False Then
              Log("MYSQL JDBC: Check unfiltered logs for JDBC errors.")
          Else
              Log ("MYSQL JDBC: Try se ejecuta consulta")
              'Se ejecuta la consulta
              Try
                  Dim cursor As JdbcResultSet
                  'Dim cursor As ResultSet
                  cursor = mysql.ExecQuery(mysql_consulta)
                  Log ("MYSQL JDBC: Se ejecuta consulta")
                  'Log ("MYSQL JDBC: Encontrado: " & cursor.NextRow)
                  
                  'Se almacena el resultado
                      mysql_resultado.Put("Cursor_ResultSet", cursor)
                      If cursor.NextRow Then
                          Log ("MYSQL JDBC: Encontrado: " & "Si")
                          mysql_resultado.Put("Encontrado", "Si")
                      Else
                          Log ("MYSQL JDBC: Encontrado: " & "No")
                          mysql_resultado.Put("Encontrado", "No")
                      End If
                      
                  'Se cuenta si es posible
                      Dim cursor_cont As JdbcResultSet
                      'Dim cursor As ResultSet
                      Log ("MYSQL JDBC: Se ejecuta consulta contar")
                      cursor_cont = mysql.ExecQuery(mysql_consulta_contar)
                      If (cursor_cont.NextRow = False) Then
                          'Se almacena el resultado
                              mysql_resultado.Put("contar", 0)
                      Else                   
                          'cursor_cont.NextRow
                          'Se almacena el resultado
      '                        If (cursor_cont.GetInt("CONTAR") = Null) Then                   
      '                            mysql_resultado.Put("contar", 0)
      '                        Else
                                  mysql_resultado.Put("contar", cursor_cont.GetInt("CONTAR"))
      '                        End If
      '                    If cursor_cont.GetInt("CONTAR") > 0 Then
      '                        mysql_resultado.Put("Encontrado", "Si")
      '                    Else
      '                        mysql_resultado.Put("Encontrado", "No")
      '                    End If
                      End If
              Catch
                  Log(LastException)
                  Log("error de mysql_ejec_consulta_resultado")
                  mysql_resultado.Put("Encontrado", "No")
              End Try
          End If
          
      
          Return mysql_resultado
      End Sub

*** Si te das cuenta el resultado de la consulta se devuelve como un mapa de datos -> mysql_resultado As Map ..... entonces ese mapa se captura en el main

-> en "main" como se hace para realizar una consulta

B4X:
                    'Se generan los parametros
                        Dim Mysql_consulta As Map
                        Mysql_consulta.Initialize
                        Mysql_consulta.Put("mysql_user_map", "RED")
                        Mysql_consulta.Put("mysql_ip_map", ip_server_local)
                        Mysql_consulta.Put("mysql_db_map", "productos_2")
'                        If lista_precios_nro <> 0 Then
                            Mysql_consulta.Put("mysql_consulta_map", "SELECT CATEGORIA AS CATEGORIAS FROM Lista WHERE CATEGORIA IS NOT NULL GROUP BY CATEGORIA")
                            Mysql_consulta.Put("mysql_consulta_contar_map", "SELECT COUNT( N.CATEGORIA ) AS CONTAR FROM (SELECT CATEGORIA FROM Lista WHERE CATEGORIA IS NOT NULL GROUP BY CATEGORIA) AS N")
'                        Else
'                            Mysql_consulta.Put("mysql_consulta_map", "Select VALOR AS VALOR FROM Conteos WHERE TIPO = 'AUTOCOD_TEL' AND DATO = '"& agregar_editar_server_autocodigo_edittext.Text)
'                            Mysql_consulta.Put("mysql_consulta_contar_map", "SELECT 1 as CONTAR")           
'                        End If
                    'Se intenta la consulta
                        Wait For (CallSub2(Starter, "mysql_ejec_consulta_resultado", Mysql_consulta)) Complete (resultado_consulta As Map)

                    'Log(Success)
                    'Se extrae el Success del mapa
                    Dim Success = resultado_consulta.Get("Success") As Boolean

4) Como vez, se puede desglosar los datos almacenados en el "resultado_consulta As Map" con la funcion "Get", entonces es hora de operar con ese mapa del resultado, te dejo un ejemplo. Ten en cuenta que lo que almacenes en el "mapa" de datos en la funcion "Starter" lo podras leer desde "main", por ejemplo en el "map" resultado_consulta, hay un dato llamado "Cursor_ResultSet" que se llena de datos desde la funcion "mysql_ejec_consulta_resultado" en el "Starter" la cual se usa para almacenar los datos... la misma se extrae por medio de :

B4X:
Dim cursor = resultado_consulta.Get("Cursor_ResultSet") As JdbcResultSet

Te dejo el ejemplo del proceso de uso del mapa de resultado:

B4X:
                    If Success = False Then
                        Msgbox("No se ha encontrado el servidor, por favor verifique su conexión al wifi del local y la configuración. Entrando en -Configuración- encontrará una herramienta para obtener la IP correspondiente al Server Local.","Servidor no encontrado.") 'ignore
                        conectar_server_agregar_editar
                    Else
                    'Conexion establecida

                        'Se extraen los valores del mapa
                            Dim Encontrado = resultado_consulta.Get("Encontrado") As String
            Log("resultado_consulta.Get('Encontrado'): " & resultado_consulta.Get("Encontrado"))
                        'Se verifica si se encontro
                            If Encontrado = "Si" Then
                                Dim cursor = resultado_consulta.Get("Cursor_ResultSet") As JdbcResultSet
                                'Dim cantidad_existente = resultado_consulta.Get("CANTIDAD_EXISTENTE") As Float
                                'Se crea la lista
                                    Dim l As List
                                    l.Initialize                               
                                'Se recorre y agregan las categorias
                                    Dim cant = 0 As Int
                                    Dim ultimo_leido = "-12122#" As String
                                    Do While cursor.GetString("CATEGORIAS") <> ultimo_leido
                                        If cursor.GetString("CATEGORIAS") <> "" Then l.Add(cursor.GetString("CATEGORIAS"))
                                        
                                        'Log(cursor.GetString("CATEGORIAS"))

                                        cant = cant + 1
                                        ultimo_leido = cursor.GetString("CATEGORIAS")
                                            If cursor.NextRow Then
                                            Else
                                                Exit   
                                            End If
                                    Loop
                                'Se muestra la lista de seleccion
                                    Dim Res As Int
                                    Res = InputList(l, "Seleccione la categoria...(" & l.Size & ")", -1) 'Ignore
                                    If Res <> DialogResponse.CANCEL Then
                                        'Se asigna el valor
                                            agregar_editar_server_categoria_edittext.Text = l.Get(Res)
                                    End If
                            End If
                    End If
 

TILogistic

Expert
Licensed User
Longtime User
conectarse a la base de datos remota desde tu app móvil es peligroso, quedan expuestas tus credenciales de conexión.
 
conectarse a la base de datos remota desde tu app móvil es peligroso, quedan expuestas tus credenciales de conexión.
Eso es cierto, pero si no es para uso poco riesgoso te saca del apuro, porque el desarrollo/testeo es mucho mucho mas rápido, y a menos de que seas objetivo de un grupo de hackers el uso del Jdbc es totalmente lógico, pero, siempre que se hable del uso en intranet (red interna), y no tanto de internet. De todas formas depende mucho del proyecto y de lo critico que sea la infraestructura o al organización. Para uso crítico no se debe usar JDBC. Yo lo uso, tengo 2 apps que se conectan al servidor local via ip del server, 1 app que se conecta online via internet por remoto, pero solo para descargar datos, que eso es otro tema, la descarga de datos via JDBC remoto es mucho más rápido si se hace con 1 sola consulta. Pero el envio de datos al server remoto siempre lo hago via JSON/PHP porque es más rápido (pero lleva mucho más trabajo).


Volviendo al asunto de seguridad informática, todo va a depender de cuantas capas de seguridad se tengan y de que tan expuesto sea la entidad y el usuario;;;... y si es lo suficientemente util para el hacker que gasta tiempo y recursos en romper claves y realizar ejercicios de hackeo. Siempre hay que estar muy atento, no descargar contenido sin verificar, y ver bien bien bien las fuentes de los correos electronicos, el RansomWare esta muy de moda, y es tan simple el caer como el abrir un correo electronico y descargar un archivo del mismo, y en ese tipo de ataque de cifrado de datos no hay objetivo real como el código fuente o claves de acceso, simplemente te secuestran toda la informacion, en mi caso tengo triple respaldo de datos, y grabo dvds fisicos cada año.
 
Top