Comments (16)
I can implement the simple List<T> findAll()
method.
I see this line in examples:
// select * from products
List<Product> allProducts = db.from(p).select();
but I don't know what is p
and in my generic context (<T>
) how can I create a such object.
from iciql.
DAOs are (currently) interfaces with annotated methods.
public interface CustomerDao extends Dao {
@SqlQuery("select * from customers where email = :email")
public Customer findByEmail(String email);
}
Db db.open(url, username, password);
CustomerDao dao = db.open(DbCustomerDao.class);
Customer customer = dao.findByEmail("[email protected]");
On your other example...
Product productsTable = new Product();
List<Product> allProducts = db.from(productsTable).select();
Iciql is heavily reflection-driven. Reviewing the documentation @ http://iciql.com might be helpful.
from iciql.
That example requires Java 8 with -parameters
flag (sound familiar? ;) ). Java 7 alternative would be:
@SqlQuery("select * from customers where email = :1")
OR
@SqlQuery("select * from customers where email = :email")
public Customer findByEmail(@BindBean("email") String email);
from iciql.
The section on aliases might be helpful in understanding what p
is in your question:
http://iciql.com/usage.html#H16
from iciql.
- Is it ok this implementation?
public T findById(ID id) {
T alias = getAlias();
return (alias != null) ? db.from(alias).where(alias.getId()).is(id).selectFirst() : null;
}
because I received an error:
Exception in thread "main" com.iciql.IciqlException: unmapped field in statement!
SELECT id, name, fiscalCode FROM Company WHERE ? = ?
- Other problem:
@Iciql.IQTable
public class Company extends Entity {
@Iciql.IQColumn
private String name;
@Iciql.IQColumn
private String fiscalCode; // CUI or CIF
// getters and setters
}
public abstract class Entity implements Identifiable<Long> {
@Iciql.IQColumn(primaryKey = true, autoIncrement = true)
protected Long id;
// getters and setters
}
with this code:
companyDao.save(new Company().setName("test").setFiscalCode("1"));
db.merge(entity);
give me an exception:
java.lang.IllegalStateException: No primary key columns defined for table class ro.fortsoft.matilda.domain.Company - no update possible
from iciql.
public T findById(ID id) {
return ... where(alias.getId()).is(id) ...
}
This would only work if you are using a custom TypeAdapter
on the ID type and TBH it's not a use-case I've needed so I'm not sure if it will work. I always use ints, longs, or UUIDs for identifiers.
On your other problem you need to...
@Iciql.IQTable(inheritColumns = true)
public class Company extends Entity {
from iciql.
Actually, the custom ID type should work just fine. It's basically the same as an UUID case which I currently handle with a custom TypeAdapter.
.
from iciql.
It's ok for now. I made some progress but now I have another problem.
I try to implement a findByExample
. The implementation is ok in InMemory
and Csv
and I wish to preserve this method for Iciql
.
Map<String, Method> getters = BeanUtils.findGetters(example);
Map<String, Object> exampleProperties = BeanUtils.getProperties(example, getters);
T alias = getAlias();
Query<T> query = getDb().from(alias);
for (Map.Entry<String, Object> property : exampleProperties.entrySet()) {
String propertyName = property.getKey();
Object propertyValue = property.getValue();
// >> WHERE (companyId = 1 AND name = 'IBM')
// query.where(propertyName, propertyValue); // << HERE
}
System.out.println("query = " + query.toSQL());
return query.select();
My problem is that I don't know how I create the where
clause in Iciql
.
Can you help me?
from iciql.
Best-match (I think) for your approach:
List<String> clauses = new ArrayList<>();
List<Object> parameters = new ArrayList<>();
for (Map.Entry<String, Object> property : exampleProperties.entrySet()) {
String propertyName = property.getKey();
clauses.add(propertyName + "=?");
parameters.add(property.getValue());
}
String clause = Joiner.on(" AND ").join(clauses);
List<T> list = db.from(alias).where(clause, parameters).select();
return list;
from iciql.
Actually that could be written more succinctly - but I think you get the general idea.
from iciql.
Something like this is cleaner although the values()
bit is still clunky but that's because Iciql does not accept a Collection
.
Object [] parameters = exampleProperties.values().toArray();
String clause = exampleProperties.keySet().stream()
.map(name -> name + "=?")
.collect(Collectors.joining(" AND "));
return db.from(alias).where(clause, parameters).select();
from iciql.
Brilliant. I am almost ready 😄
Maybe the last issue is the non generic dao methods (findByXYZ
).
For example:
public interface CustomerDao extends EntityDao<Customer> {
public Customer findByEmail(String email);
}
public class IciqlCustomerDao extends IciqlEntityDao<Customer> implements CustomerDao {
public Customer findByEmail(String email) {
// HERE annotation or an elegant/simple code
}
}
My actual implementation is:
public class IciqlCustomerDao extends IciqlDao<Customer> implements CustomerDao {
@Override
public Customer findByEmail(String email) {
Customer alias = getAlias();
return getDb().from(alias).where(alias.getEmailAddress()).is(email).selectFirst();
}
}
I don't know if I can use annotations (SqlStatement, ...) for a more simple, declarative approach.
For now in Iciql
a generic MyDao
must extends Dao
and for my purpose I want to extends EntityDao
. I see in JDBI that is not a such constrain. If I want to use the default (Generic)Dao provided by iciql then fine, I will extends that interface but I'd rather not have this constraint.
In this scenario my IciqlDao
must be something like DaoProxy
from iciql, maybe help me if actual DaoProxy
is spited in two: BaseDaoProxy
and CrudDaoProxy
(or other better names) then my IciqlDao extends BaseDaoProxy
.
I must recognize that the current workflow from iciql is straightforward and it's very simple to use this library in a web application developed with Pippo web framework but I wish to push the things ahead.
I implemented with success in my pippo based application the open session in view pattern using a generic dao and iciql.
The core class is:
public class DbUtils {
private static final Logger log = LoggerFactory.getLogger(DbUtils.class);
// private static final String url = "jdbc:h2:mem:matilda";
private static final String url = "jdbc:h2:./data/matilda";
private static final String username = "";
private static final String password = "";
private static DataSource dataSource;
private static Db genericDb;
private static Map<Request, Db> cache = new ConcurrentHashMap<>();
static {
dataSource = JdbcConnectionPool.create(url, username, password);
}
public static Db getDb() {
Request request = getRequest();
if (request == null) {
if (genericDb == null) {
log.debug("Create generic Db instance");
genericDb = Db.open(dataSource);
}
return genericDb;
}
if (!cache.containsKey(request)) {
log.debug("Create request Db instance");
cache.put(request, Db.open(dataSource));
}
return cache.get(request);
}
public static void closeDb() {
Request request = getRequest();
if (request == null) {
if (genericDb != null) {
log.debug("Close generic Db instance");
genericDb.close();
}
} else if (cache.containsKey(request)) {
log.debug("Close request Db instance");
cache.remove(request).close();
}
}
private static Request getRequest() {
// TODO fix this in pippo
// return Request.get();
RouteContext routeContext = RouteDispatcher.getRouteContext();
return (routeContext != null) ? routeContext.getRequest() : null;
}
}
and in my base iciql dao (this class is extended by all my dao classes):
public class IciqlDao<T extends Entity> extends IciqlEntityDao<T> {
public IciqlDao() {
this(DbUtils::getDb);
}
// I use this constructor in DaoTest class (use in memory h2)
public IciqlDao(IciqlDbFactory dbFactory) {
super(dbFactory);
}
}
all I do in my PippoApplication class is to add an after filter that calls DbUtils.closeDb()
It is an experimental approach and the result (the generic-dao library with inmemory, csv, iciql implementations as modules, plus the real application) will be available as open source projects when I finished the work.
from iciql.
For now in Iciql a generic MyDao must extends Dao and for my purpose I want to extends EntityDao.
The way the Iciql DAO feature is implemented you can not provide a Class
you can only provide an Interface
and your interface must extend Dao
. Your class hierarchy is incompatible with the current DAO feature. I'm open to refactoring DaoProxy
to be more useful but for now I think you are stuck with the DSL approach for findByEmail
.
from iciql.
I pushed a first commit of my tiny generic dao project. The iciql implementation is here. Sure is not perfect but it's a start.
I see that I have a problem with iciql repository. Maybe it's time to upload it on sonatype 😄
from iciql.
Thanks for your support!
from iciql.
Iciql will get to MavenCentral eventually. It's on my todo list, low on my list, but on the list nontheless.
I think the main problem you have is that you didn't specify the Iciql repo in the POM.
from iciql.
Related Issues (18)
- Class loading issue with dao interface proxy HOT 1
- IQTable.inheritColumns works only for depth 3 HOT 2
- IQColumn length with trim not working for DSL HOT 2
- imcomplete maven description HOT 1
- Database & Table Versioning HOT 1
- Unable to set null in some statements HOT 1
- Need groupBy methods
- Order by desc does not like primitives
- Unable to insert data which all column's value is null HOT 1
- Postgres 9.5 Upsert syntax is wrong
- The "where" compile-time statement did not work with "String" type field HOT 3
- Error building app in Android Studio HOT 10
- JdbcUtils.DRIVERS.db2: "COM.ibm.db2.jdbc.net.DB2Driver" ??? HOT 3
- Activate Console Logger not function HOT 5
- Generation of classes via command line HOT 1
- SamplesTest method testSelectManyCompoundFrom2()
- Can't create a table for model HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from iciql.