Auto Macros
Avoid Boilerplate Code
If you want to avoid writing lots of boilerplate code, scalikejdbc-syntax-support-macro
can be greatly helpful for reducing such troublesome coding tasks.
Setup
In addition to the core library, you can add the following optional dependency in buid.sbt
:
libraryDependencies += "org.scalikejdbc" %% "scalikejdbc-syntax-support-macro" % "4.3.2"
Usage
autoConstruct for extracting entities from ResultSet
When you don’t use the macros, the usual code to extract data from ResultSet
should look like below:
case class Company(
id: Long,
name: String,
countryId: Option[Long],
country: Option[Country] = None
)
object Company extends SQLSyntaxSupport[Company] {
def apply(rs: WrappedResultSet, rn: ResultName[Company]): Company = new Company(
id = rs.get(rn.id),
name = rs.get(rn.name),
countryId = rs.get(rn.countryId)
)
}
When using scalikejdbc-syntax-support-macro, you can use #autoConstruct
macro instead. As you can see, now the code is significantly simpler and much easier to maintain for the future.
case class Company(
id: Long,
name: String,
countryId: Option[Long],
// This property never comes from ResultSet
country: Option[Country] = None
)
object Company extends SQLSyntaxSupport[Company] {
def apply(rs: WrappedResultSet, rn: ResultName[Company]): Company =
// "country" is execluded when binding values from ResultSet
// Note that the property neeeds to have the default `None` value
autoConstruct(rs, rn, "country")
}
The #autoConstruct
method binds all the fields defined at the primary constructor automatically.
The country
field in the above example class should be ignored. In such cases, you should specify an additional String parameter such as “country”. Of course, the “country” will be verified at Scala compilation time!
autoColumns to avoid accessing JDBC metadata
When your code loads ScalikeJDBC DAO objects, ScalikeJDBC automatically fetches all the column names for the table specified by SQLSyntaxSupport
‘s tableName
via the JDBC metadata API.
If you don’t prefer the behavior, you can choose to load column names from the entity class’s field names instead. The following code won’t access JDBC metadata and will resolve column names from the Company
class’s fields and primary constructor’s parameters by simply converting them to snake-cased ones or applying name converters to them.
case class Company(id: Long, name: String, countryId: Option[Long], country: Option[Country] = None)
object Company extends SQLSyntaxSupport[Company] {
override lazy val columns = autoColumns[Company]("country")
// this will be Seq("id", "name", "country_id")
}