I am trying to leverage TypeSafe
's slick library to interface with a MySQL server. All the gettingstarted/tutorial examples use withSession{}
where the framework will automatically create a session, execute the queries within the {}
's, then terminate the session at the end of the block.
My program is rather chatty, and I would like to maintain a persistent connection throughout the execution of the script. So far I have pieced together this code to explicitly create and close sessions.
val db = Database.forURL("jdbc:mysql://localhost/sandbox", user = "root", password="***", driver = "com.mysql.jdbc.Driver")
val s = db.createSession()
...
s.close()
Where I can execute queries in between. However, when I try to execute a command, such as
(Q.u + "insert into TEST (name) values('"+name+"')").execute
It crashes because it cannot find the implicit session. I don't completely understand the syntax of the execute definition in the documentation, but it seems like there might be an optional parameter to pass an explicit session. I've tried using .execute(s), but that spits out a warning that (s) doesn't do anything in a pure expession.
How do I explicitly specify a pre-existing session to run a query on?
Appended: Trial code for JAB's solution
class ActorMinion(name: String) extends Actor
{
Database.forURL("jdbc:mysql://localhost/sandbox", user = "root", password="****", driver = "com.mysql.jdbc.Driver") withSession
{
def receive =
{
case Execute =>
{
(Q.u + "insert into TEST (name) values('"+name+"')").execute
sender ! DoneExecuting(name,output,err.toString)
}
}
}
}
Which returns compile error
[error] /home/ubuntu/helloworld/src/main/scala/hw.scala:41: missing parameter type for expanded function
[error] The argument types of an anonymous function must be fully known. (SLS 8.5)
[error] Expected type was: ?
[error] {
[error] ^
[error] one error found
For fast response time and high throughput, it's actually best to keep database connections open and reuse them for subsequent requests. Most database frameworks offer some kind of connection pool mechanism where a request handler can get a database connection for its work and return it to the pool afterwards.
It will stay open in memory, clogging that address until the system times it out and closes it. There was a time that this was a real problem even on small websites. People would open a connection, and it would stay open for weeks. As more users hit that same page, more and more connections would open.
Persistent connections are SQL links that do not close when the execution of your script ends. When a persistent connection is requested, PHP checks if there's already an identical persistent connection (that remained open from earlier) - and if it exists, it uses it. If it does not exist, it creates the link.
I was able derive what I needed from this answer
//imports at top of file
//import Database.threadLocalSession <--this should be commented/removed
import scala.slick.session.Session // <-- this should be added
......
//These two lines in actor constructor
val db = Database.forURL("jdbc:mysql://localhost/sandbox", user = "root", password="****", driver = "com.mysql.jdbc.Driver")
implicit var session: Session = db.createSession()
......
session.close() //This line in actor destructor
Just enclose the relevant part of your script in withSession{}
. Note that if you are keeping the session open for a while/are performing lots of database manipulation queries, you should also look into taking advantage of transactions.
And you should really be using prepared statements for inserts if the data has a potentially external source.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With