1 2 3 4 5 Previous Next 66 Replies Latest reply on Jan 24, 2011 2:40 PM by asookazian Go to original post
      • 45. Re: Selling Weld and EE6
        asookazian

        Gavin King wrote on Nov 26, 2009 21:12:


        OK, so with a couple of tweaks to my API, I discovered a nice pattern, where you can define your query in a subclass of Query. This gives your SQL query a nice typesafe interface, as well as letting the Java compiler check your SQL syntax:

        class LoginQuery extends Query {
             
             From<users> user = from(users.table);
             
             Expression<String> name = user.get(users.name);
             Expression<Integer> age = user.get(users.age);
             
             Parameter<String> username = parameter(String.class);
             Parameter<String> password = parameter(String.class);
             
             {
                  select(name, age);
                  where( and( eq( user.get(users.username), username ), 
                            eq( user.get(users.password), password ) ) );
                  orderBy(name, age);
             }
             
        }



        To execute this query is really easy:

             public void testLoginQuery(Session session) {
                  
                  LoginQuery loginQuery = new LoginQuery();
                  
                  Iterable<Tuple> result = session.prepare(loginQuery)
                       .set(loginQuery.username, "gavin")
                       .set(loginQuery.password, "foobar")
                       .result();
                  
                  for (Tuple tuple: result) {
                       String name = tuple.get(loginQuery.name);
                                int age = tuple.get(loginQuery.age);
                  }
             }



        Of course, the calls to set() and get() are completely typesafe.



        this was a good idea.  I like that.  now if I have 1000 queries in my app, does that mean I must write 1000 classes just for my queries?  seems excessive.

        • 46. Re: Selling Weld and EE6
          gavin.king

          William Draï wrote on Nov 27, 2009 00:57:


          I don't know why, but I remembered Spring templates as constructs with lots of strange inner classes. I must have mixed this up with something else.


          Exactly. I'm finding Francisco's comments very hard to square with the fact that all the examples I've seen of Spring JDBC show off the use of all kinds of weird inner classes, and for some reason require the use of some special Spring DAO class. I don't envisage any need for DAOs or inner classes with this API that I'm proposing.

          • 47. Re: Selling Weld and EE6
            gavin.king
            I totally agree on the value of typesafe queries when all the application uses raw SQL. But for JPA-mostly apps with a few highly optimized SQL queries (like most JEE apps now) it is plain overkill.


            OK, fine, but there are a bunch of people who don't want to use JPA. They don't understand, or see the value of, using managed objects to represent their persistent data. I'm interested in seeing what we could do to improve their lives.


            Moreover this typesafe query language will never be able to express database-specific SQL queries or manually optimized queries (you know, the one query for which you need an Oracle expert DBA for 2 days).


            Sure, but of course any framework we write is going to allow you to fall back to writing the SQL by hand. That's an obvious hard requirement. Even JPA lets you do that. However, in the common case, you should use straight standard ANI SQL. No more than one query in 100 really needs to use vendor-proprietary features. Seriously.


            For the very few cases where I have needed raw SQL, I can say that I just didn't care of having one or two more try/catch statements.


            Sure, but you're thinking only of your usecase.


            Maybe I'm absolutely wrong but I don't think a JDBC extension can be the killer feature for CDI. Seam does not have it but I don't think its relatively low adoption has anything to do with this.


            No, however, designing this was fun. And I think it might appeal to a handful of people. Do I really have to make a business case?

            • 48. Re: Selling Weld and EE6
              gavin.king

              now if I have 1000 queries in my app, does that mean I must write 1000 classes just for my queries? seems excessive.

              Um. Why? Why would that be a bad thing? I imagine that any app with 1000 queries has tens of thousands of classes already. What's the problem? Why is defining a class worse than writing a method? Are you working from some totally bizarre metric where you measure code quality by number of classes?

              • 49. Re: Selling Weld and EE6
                nickarls

                That's like saying What?! Chrome doesn't support the <blink/> tag, I'm going back to Mosaic! ;-)

                • 50. Re: Selling Weld and EE6

                  Gavin King wrote on Nov 27, 2009 01:41:



                  William Draï wrote on Nov 27, 2009 00:57:


                  I don't know why, but I remembered Spring templates as constructs with lots of strange inner classes. I must have mixed this up with something else.


                  Exactly. I'm finding Francisco's comments very hard to square with the fact that all the examples I've seen of Spring JDBC show off the use of all kinds of weird inner classes


                  You cant use the weird inner classes if you want, but you do not have to.



                  , and for some reason require the use of some special Spring DAO class.


                  Yes, the same reason that  you need to use EntityHome/List in all your Seam applications (so that you do not have to write that very common code again yourself), but that does not mean you have to inherit from org.jboss.seam.framework.EntityHome/List to create a Seam component. Same thing with Spring DAO classes, they are there to save time in case you like the DAO pattern, but you can use JdbcTemplate without them.



                  I don't envisage any need for DAOs or inner classes with this API that I'm proposing.


                  JdbcTemplate also does not require DAOs... inner classes are available, in case you want to do some advanced semi-low-level stuff, but you are not forced to use them either.


                  Here is a translation of William proposal to Spring's JdbcTemplate (as I use it Seam projects):


                  @In("#{jdbcTemplate}")     
                  private transient SimpleJdbcTemplate jdbcTemplate;
                  
                  public void login(String un, String pw) {
                      Map<String, Object> parameters = new HashMap<String,Object>();
                      parameters.put("username",un);
                      parameters.put("password",pw);
                      Map tuple<String, Object> = jdbcTemplate.queryForMap("select name from user where username = :username and password = :password",parameters)                        
                     String name = tuple.get("name").toString();
                     user = new User(un, name, pw);
                  }
                  



                  I do not see a big difference... do you? (And note that I could have written this code in a much shorter/simpler way, but what I was attempting here was to make as similar as possible to William proposal)

                  • 51. Re: Selling Weld and EE6

                    Gavin King wrote on Nov 27, 2009 01:52:


                    now if I have 1000 queries in my app, does that mean I must write 1000 classes just for my queries? seems excessive.

                    Um. Why? Why would that be a bad thing? I imagine that any app with 1000 queries has tens of thousands of classes already. What's the problem? Why is defining a class worse than writing a method? Are you working from some totally bizarre metric where you measure code quality by number of classes?


                    It is fear of adding classes. I know the feeling, I use to feel that fear years ago... experience sometimes cures it ;-)

                    • 52. Re: Selling Weld and EE6

                      Arbi Sookazian wrote on Nov 27, 2009 01:06:


                      I like that.  now if I have 1000 queries in my app, does that mean I must write 1000 classes just for my queries?  seems excessive.


                      While I believe one should learn to resist to the fear of adding classes, I can also understand that having 1000 files one with each query can be uncomfortable to manage: Why not be able to group related queries in one file? well, there is a way to do that... weird inner classes! ;-)

                      • 53. Re: Selling Weld and EE6
                        asookazian

                        Gavin King wrote on Nov 27, 2009 01:52:


                        now if I have 1000 queries in my app, does that mean I must write 1000 classes just for my queries? seems excessive.

                        Um. Why? Why would that be a bad thing? I imagine that any app with 1000 queries has tens of thousands of classes already. What's the problem? Why is defining a class worse than writing a method? Are you working from some totally bizarre metric where you measure code quality by number of classes?


                        perhaps you and Francisco are right.  just thought from a maintenance perspective too many classes may not be a good idea but i guess i don't have any data/proof to back up that novice statement.  as long  as they're reusable that's good.  it would be nice to know what martin fowler or ted neward have to say on this subject.


                        anyways....


                        in the Main class from V2 of the API/prototype, the start() method observes Weld container init; this package org.jboss.weld.environment.se.events.ContainerInitialized


                        void start(@Observes ContainerInitialized ci, Session session) {
                                  createTable(session);
                                  testInsert(session);
                                  testUpdate(session);
                                  testLoginQuery(session);
                                  testQuery2(session);
                             }
                             
                             /*public static void main(String[] args) throws Exception {
                                  ConnectionFactory cf = new TestConnectionFactory();
                                  PreparedStatementFactory psf = new DefaultPreparedStatementFactory();
                                  Session session = new Session( new AnnotationLiteral<Default>() {}, cf, psf );
                                  
                                  createTable(session);
                                  testInsert(session);
                                  testUpdate(session);
                                  testQuery(session);
                             }*/



                        package org.jboss.weld.environment.se.events;
                        
                        /**
                         * The event that is fired when the Weld CDI container is initialized and
                         * ready for applications to take control, which it may do by observing this
                         * event.
                         *
                         * @author Peter Royle
                         */
                        public class ContainerInitialized {
                        
                        }
                        



                        So how do I run the app this way rather than using public static void main()?


                        • 54. Re: Selling Weld and EE6

                          Arbi Sookazian wrote on Nov 27, 2009 18:54:


                          perhaps you and Francisco are right.  just thought from a maintenance perspective too many classes may not be a good idea but i guess i don't have any data/proof to back up that novice statement.


                          Have you read about GodClasses? They are the evil gods that dominate your soul if you are dominated by the fear of adding classes.



                            as long  as they're reusable that's good.  it would be nice to know what martin fowler or ted neward have to say on this subject.


                          AFAIK, GodClass is a widely recognized anti-pattern...




                          So how do I run the app this way rather than using public static void main()?



                          You are asking about this?

                          • 55. Re: Selling Weld and EE6
                            gavin.king

                            OK, Francisco, fair enough. But then I'm finding it kinda difficult to understand how this API is a template. Isn't it a simple facade?

                            • 56. Re: Selling Weld and EE6
                              asookazian

                              Gavin King wrote on Nov 27, 2009 21:33:


                              OK, Francisco, fair enough. But then I'm finding it kinda difficult to understand how this API is a template. Isn't it a simple facade?


                              by facade are you referring to something like session facade from pre-EJB3 design patterns?

                              • 57. Re: Selling Weld and EE6
                                gavin.king

                                Arbi Sookazian wrote on Nov 27, 2009 21:49:



                                Gavin King wrote on Nov 27, 2009 21:33:


                                OK, Francisco, fair enough. But then I'm finding it kinda difficult to understand how this API is a template. Isn't it a simple facade?


                                by facade are you referring to something like session facade from pre-EJB3 design patterns?

                                No, I am referring to the facade pattern.

                                • 58. Re: Selling Weld and EE6

                                  Gavin King wrote on Nov 27, 2009 21:33:


                                  OK, Francisco, fair enough. But then I'm finding it kinda difficult to understand how this API is a template. Isn't it a simple facade?


                                  Yes, I have always thought it could be named JdbcFacade instead of JdbcTemplate ;-). But well, only academics worry about having classes named exactly as GoF patterns... no? ;-).

                                  • 59. Re: Selling Weld and EE6
                                    asookazian

                                    where/what exactly is serving as facade in the API? sorry, haven't detected it yet...