I was wondering how to persist data to a hsqldb. For example I am trying to save a simple name to a database but I cant seem to figure out how to persist it.
The recommended approach is to create a domain class with a String name property. Then you can save it, and you're done. First, create the domain class:
$ grails create-domain-class com.foo.Person
Then edit the grails-app/domain/com/foo/Person.groovy:
package com.foo
class Person {
String name
}
In controller actions or service methods you can create, save, and retrieve data:
def heMan = new Person(name: 'He Man')
if ( !heMan.save() ) {
// Handle problems saving (e.g. constraint violations)
}
def h = Person.findByName('He Man')
println h.name
An alternative approach is to work with JDBC directly. You can have dataSource bean automatically injected into your controller, then use the groovy.sql.Sql class to query that dataSource. Check out this stackoverflow.com question.
Two ways:
GORM
raw JDBC (via spring's JdbcTemplate)
I would suggest starting with a good Grails tutorial such as this one at IBM or one of these. Learn to use GORM. It will make your life better.
Related
Friends:
In the service class I am trying to query the DB and get result to populate my domain class. I am not sure if I thinking this correctly or I have to use the find methods approach to fill my domain classes ?
The understanding I have is:
Grails thru URLMappings will call my controller and inside that I can do a direct instantiation of Service class.
I am then using SQL directly there inside Service class to iterate thru the Resultset and populate the Domain class list and return that to controller class which will then return a list back to the REST call user.
Is this the right approach or I have to call Service from controller but using the find method and that will fill the list and that should be used to return the list ?
In all cases I am using the H2 db itself.
Regards and Thank you for your time.
-Narahari
As per the standards, Flow goes from controller > Service > DAO.
All the business logic should be written in the service class only.
As you are using DAO layer is hidden through GORM.
Grails is very powerful and productive language. You use GORM for database activity. For your scenario, you could use findAll, createCriteria, HQL or native SQL query approach, but the flow should not be broken. It means that if write database related code in the controller then in future it will be difficult to maintain debug code.
I understand that the standard way to use bootstrap.groovy and a controller is to create the data and save them to DB in the bootstrap init()
The controller can then read the data, so the "middle man" between the two is the database.
But, what if I want to create data in bootstrap.groovy and not save them in the database (let's assume these data don't need to be saved), how can I inject the data into the controller so they could be used for views rendering ?
Let's take a simple example with a domain class Book. Simply in bootstrap I just want to crete a dummy list of 100 books:
class BootStrap {
def grailsApplication
def List<Book> books
def init = { servletContext ->
books = new ArrayList<>()
for (int i=0; i<100; i++) {
books.add(new Book(numPages: 20))
}
}
def destroy = {
}
}
The goal is now to expose/inject he list of books to a BookController.
How would I do that? I could not find a simple way or an answer anywhere about this
Services are singleton in Grails by default, so you could store that data in a service. But you have to be careful, because a service could be used concurrently.
https://docs.grails.org/latest/guide/services.html
To generalize the problem I have posted above (after reading the answer from quindimildev) generally every framework should have a way to perform initialization operations ... such as initializing a cache from a file or database or 3rd party services. By the time the application has started those data are in memory ready to be used by controllers, etc...
The typical applications/examples I have seen for grails don't take this into consideration, and they assume your database is populated and read through controllers actions. This is fine for most applications, but I would be surprise if grails doesn't provide a mechanism to build a cache at start up (one time operation that could take a few seconds) that can be available to all controllers once the application has started.
I hope this clarifies the scenario I am trying to address
For example I've been written a simple domain-class:
class Book{
String bookName
}
I've done some records of this instance. And now I wanna update one of them, to realize it, I've an idea to write a setter for bookName. But may be is more elegant method to do this via GORM-methods?
Here is an example. For example, in a service method.
Book bookInstance = Book.get(id) //id is the primary key
bookInstance.bookName = "new book name"
bookInstance.save(flush : true)
Grails uses the Groovy method - getter and setters are created for you and you can take it that they are available for your use on each property of a domain class that you create. See http://www.groovy-lang.org/style-guide.html section 7.
Alfredo suggested one way in which you can get one instance of the Book class, but to use this you need a mechanism in place to obtain the id so that you can use the get() method.
If you want to get an instance of book by its name, you can use dynamic finders. See 6.4.1 Dynamic Finders of http://grails.github.io/grails-doc/latest/guide/GORM.html#finders.
The simplest one to use would be to use this to get your book instance:
def bookInstance= Book.findByBookName('the book name that you want to change')
You can then update it as has already been described.
I have a domain class in grails... How do I get gorm to leave out this entity when it create the db? Just leave it alone.
If i understood, u want not create table from domain class? If yes, use this code inside domain class:
static mapWith = "none" // disable persisting into database
Sounds like you don't need it to be a domain class then. You could just make it a POGO in the src/groovy file. If my assumptions here are wrong please explain further what you're trying to accomplish.
You could use Command Objects.
http://grails.org/doc/latest/guide/single.html#commandObjects
They provide the data binding and validation of domain classes, but do not map to the database.
Just a few high-level, hopefully very quick questions:
1) If I have a class A with a single field x, is constructing it
def A = new A(x:someVal, y:someVal)
totally fine?
2) Related, is the following a good way to copy relevant parts of a command object into a domain object?
def domainObject = new DomainObject(commandObject.properties).
Where command object has extra properties. Or should it be done instead:
def domainObject = new DomainObject()
domainObject.properties['prop1', 'prop2', ...] = commandObject.properties
or ?
Thanks
For the first question, it's important to distinguish between a vanilla groovy object, and a grails domain object. Groovy objects with throw a MissingPropertyException. Grails domain objects will silently ignore extra properties.
Regarding the second question, initializing grails domain objects with a command object is a common pattern, and generally ok. Params can be a little bit more dangerous. A malicious user can put anything into params so it's best to explicitly spell out what properties you want to assign. Otherwise, things like timestamps and users, or even non-mapped columns like injected spring beans could be affected.