DAO in Scala with class types

Let my application contain the business classes Order , Product , Customer , etc., and I would like to store / retrieve them from / from the database.

Usually for this purpose we use the DAO pattern. That is, we define the DAO interface and implementation for each business class: OrderDAO , ProductDAO , etc. Now I would like to use a template of type type:

 trait DAO[T] { def create(t:T) ... // other CRUD operations } ... // DAO implementations for specific business objects implicit object OrderDAO extends DAO[Order] { def create(o:Order) {...} ... // other CRUD operations } ... // create a business object in the database def create[T](t:T)(implicit dao:DAO[T]) {dao.create(t)} 

Now my problem is that all DAOs use an instance of DataSource (a factory of database connections), so I cannot define DAOs as objects . I have to create a single instance of the DataSource and pass it to all DAOs when they are initialized.

Let's say we have a function to create a DataSource :

 def dataSource():DataSource = {...} 
How do you implement DAOs with class classes?
+4
source share
3 answers

I don't think class type is the way to go here. Type classes are intended to describe features, not to replace DIs.

For example, if your DAO writes to the keystore, it may need to be able to convert the class into a map of keys and values.

In this case, a class like:

 trait KeyValuable[T] { def toMap(t: T): Map[String, String] } 

And it’s obvious that you can provide each business class with the right implementation regardless of environment. This is a type inheritance ability that is not related to how you use it.

+2
source

How to create an object that contains all your DAOs and initializes them using your DataSource? Extra indirection, but it will work.

I don't know (yet) the best practice related to Injection Dependency in Scala, but it might work for you too: http://www.assembla.com/wiki/show/liftweb/Dependency_Injection

+1
source

Agree with Sasha. Lift mode should work:

 trait DataSource class MyDataSource extends DataSource object DataSources { @volatile var dataSource: () => DataSource = () => new MyDataSource } 

With this approach, you can use object without losing the ability to test.

+1
source

Source: https://habr.com/ru/post/1347743/


All Articles