What is the best way to go about referencing multiple tables using slick 2.0? - playframework-2.2

I have these tables: USERS, USER_ROLES, ROLES, PERMISSIONS, ROLE_PERMISSIONS
I am implementing the:
AssignedRoles (M): returns the set of roles assigned to a given user;
So, if I was going to write the query for this function it would like something like this:
SELECT role_id FROM USER_ROLES WHERE user_id = 'M'
where M is the given user id, then I would look up each role by their id and return the Role object, or I would use a join, but that is not relevant here.
so where is what my UserRole model looks like:
case class UserRole(id:Long, userID:Long, roleID:Long)
object UserRoles {
class UserRoles(tag: Tag) extends Table[UserRole](tag, "USER_ROLES") {
def id = column[Long]("ID", O.PrimaryKey, O.AutoInc)
def userID = column[Long]("USER_ID")
def roleID = column[Long]("ROLE_ID")
def user = foreignKey("USER_ID", userID, TableQuery[Users])(_.id)
def role = foreignKey("ROLE_ID", roleID, TableQuery[Roles])(_.id)
def * = (id, userID, roleID) <> (UserRole.tupled, UserRole.unapply)
}
def retrieveRoles(userID:Long) : List[Role] = {
DB.withSession { implicit session =>
userRoles.filter(_.userID === userID).list
}
}
As expected retrieveRoles returns a list of UserRoles, but I want a list of Roles, so I woulds have to write another query that will take UserRole.roleID and find it in the roles table for each of UserRole that is returned. That is a lot of queries and I feel like there is a way that will to do this in one query. Any help from the Slick experts?

userRoles.filter(_.userID === userID).flatMap(_.role)

Related

apply count on inner join in sql using sequelize

If i have Posts model and Likes model that PostsLikes model has postID as foreign key
How to create orm sequelize query to get post by id and number of likes on it
You should use a subquery in attributes options like this:
const posts = await Posts.findByPk(postId, {
attributes: {
include: [[Sequelize.literal('SELECT COUNT(*) FROM PostsLikes where PostsLikes.postID = Posts.ID)'), 'LikesCount']]
}
})

Grails joinTable query issue

I have a User domain and a Role domain and a working joinTable coded on the User side as
static hasMany = [ roles: Role ]
...
static mapping = {
table 'user_data'
id column: 'employee_number', name: 'employeeNumber', generator: 'assigned', type: 'int'
version false
sort 'lastName'
roles joinTable: [ name: 'user_role' ]
}
I am trying to query the database to pull all users with a security officer role with
def roleInstance = Role.find { name == 'security_officer' }
def secList = User.findAll("from User as u where u.roles = :roleInstance", [roleInstance:roleInstance])
But I am getting the error
Class: com.microsoft.sqlserver.jdbc.SQLServerException
Message: The value is not set for the parameter number 1.
What am I doing wrong?
I figured it out with a bunch of guess and checking.
def roleInstance = Role.findByName("security_officer")
def query = User.where {
roles {
id == roleInstance.id
}
}
def securityOfficerList = query.list()
Roles is a hasMany relationship so I think following should work.
def secList = User.findAll("from User as u where u.roles in (:roleInstance)", [roleInstance:[roleInstance]])
User has many roles, so in query you can't use u.roles = roleInstance.Try to use in [list of roles] or you can try the following query:
def secList = User.findAll("from User as u where u.roles in (from Role r where r.name=:roleInstance)", [roleInstance:roleInstance])

How to populate a collection inside a DAO object using MyBatis annotaions (or even without it)?

I have a DAO User :
class User{
int id,
int name,
List<Vehicle> vehicles;
}
In my UserMapper.java interface, I have a method that gives me User DAO :
#Select("select u.id, u.name, v.id, v.name from User u, Vehicle v where u.id=#{id} and v.user_id=u.id")
public User getUser(int id);
How to make sure that the above query fills the User object's vehicle collection properly ?
Please use annotations (and XML only as a last resort)
From Mybatis 3 User Guide,
Note: You will notice that join mapping is not supported via the Annotations
API. This is due to the limitation in Java Annotations that does not
allow for circular references.
Best you can do is something like this,
#Results({
#Result(property = "id", column = "id", id = true),
#Result(property = "name", column = "name"),
#Result(many=#Many(select="your select"), javaType=Vehicle.class)
})
#Select("select u.id, u.name, v.id, v.name from User u, Vehicle v where u.id=#{id} and v.user_id=u.id")
public User getUser(int id);
My advice, use the xml.

Grails criteria groupby object

Example grouping by name of the zones:
def result = User.createCriteria().list{
projections {
roles {
zones{
groupProperty("name")
}
}
}
}
but suppose I want to get the "id" or other attributes. the fact is that i want the object on the representing the group and not the string "name".
result.each{ println it.customFuncion() }
"zones" is a hasMany attribute and then i cant group by itself. What should be done, but doesnt works:
def result = User.createCriteria().list{
projections {
roles {
groupProperty("zones")
}
}
}
Is that possible? Thank you guys!
use hql for complex queries:
def result = User.executeQuery("select u.id, zone.name from User as u inner join u.roles as role inner join role.zones as zone group by u.id, zone.name")
Then you can access the result columns as follows:
result.each { row -> row[0] // u.id } // or access via defined column name
Imagine that i do not know your real hasMany collection names.

How to a write a Criteria query with multiple joins involved

I'm trying to code the following HQL query using the Criteria API:
var userList = _session
.CreateQuery("select u from User u where u.Role.ID=3 and u.Customer.ID=:cID")
.SetInt32("cID", 1)
.List<User>();
(3 NHibernate objects : User(ID, Name, Role, Customer), Role(ID, Name) and Customer(ID, Name).
I tried the following but it doesn't work because NHibernate tries to find a Customer associated with a Role:
var userList = _session
.CreateCriteria(typeof(User))
.CreateCriteria("Role")
.Add(Restrictions.Eq("ID", 3) )
.CreateCriteria("Customer")
.Add(Restrictions.Eq("ID", 1) )
.List<User>();
Any other way (that works!) of doing it?
You can use alias
var userList = _session
.CreateCriteria(typeof(User), "u")
.CreateAlias("u.Role", "r")
.Add(Restrictions.Eq("r.ID", 3) )
.CreateAlias("u.Customer", "c")
.Add(Restrictions.Eq("c.ID", 1) )
.List<User>();
Hope it helps