source: trunk/fmgVen/src/com/fmguler/ven/Ven.java @ 28

Last change on this file since 28 was 28, checked in by fmguler, 13 years ago

Refs #3 - Ven.get() is converted to the new format. QueryGenerator and QueryMapper are mostly OK, generateRecursively and mapRecursively are converted and checked. Handles joins (includes/associations) many to one and one to many. For one to many, the reverse join field can be determined in a couple of ways. First way is (prefereed) having VenList as the list implementation which specifies the element class and the join field. Second way is using Java 1.5 generic type to detect element class (not yet implemented) and guessing join field by convention (if multiple joins exist, this won't work). The last way is to have some kind of annotation or configuration, which is of course the least preferred way. VenList has a static method to determine the element class in the object list, which currently calls getElementClass if the list is an instance of VenList. In the future other options can be implemented.

Getting object using joins (includes/associations) are tested using dummy assocations between SomeDomainObject and AnotherDomainObject. The Sample class builds the database, tests the operations and rolls back to the initial state. Database refactoring operations are moved to the LiquibaseUtil for clarity.

In the future, the generated queries will be shortened using hashed aliases, and the criteria subsystem will be implemented.

File size: 5.1 KB
Line 
1/*
2 *  fmgVen - A Convention over Configuration Java ORM Tool
3 *  Copyright 2010 Fatih Mehmet Güler
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *  under the License.
17 */
18package com.fmguler.ven;
19
20import com.fmguler.ven.util.Convert;
21import java.util.HashMap;
22import java.util.List;
23import java.util.Map;
24import java.util.Set;
25import javax.sql.DataSource;
26import org.springframework.beans.BeanWrapper;
27import org.springframework.beans.BeanWrapperImpl;
28import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
29import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
30import org.springframework.jdbc.core.namedparam.SqlParameterSource;
31
32/**
33 * The main class for data access
34 * @author Fatih Mehmet Güler
35 */
36public class Ven {
37    private NamedParameterJdbcTemplate template;
38    private QueryGenerator generator;
39    private QueryMapper mapper;
40    private boolean debug = true;
41
42    public Ven() {
43        generator = new QueryGenerator();
44        mapper = new QueryMapper();
45    }
46
47    public List list(Class objectClass) {
48        return null;
49    }
50
51    public int count() {
52        return 0;
53    }
54
55    public Object get(int id, Class objectClass, Set joins) {
56        String query = generator.generateSelectQuery(objectClass, joins);
57        query += " where 1=1 and " + Convert.toDB(Convert.toSimpleName(objectClass.getName())) + ".id = :___id ";
58
59        Map paramMap = new HashMap();
60        paramMap.put("___id", new Integer(id));
61        if (debug) System.out.println("Ven - SQL: " + query);
62
63        List result = mapper.list(query, paramMap, objectClass);
64        if (result.isEmpty()) return null;
65        if (result.size() > 1) System.out.println("Ven - WARNING >> get(id) returns more than one row");
66        return result.get(0);
67    }
68
69    /**
70     * Save the object. If it has a non null (or non zero) "id" property it will be updated.
71     * It will be inserted otherwise.
72     * <p>
73     * The object will be saved to a table with the same name as the object,
74     * The fields of object will be mapped to the table fields.
75     *
76     * @param object the object to be saved
77     */
78    public void save(Object object) {
79        String query = null;
80
81        if (isObjectNew(object)) {
82            //if this is a new object assign a new id first
83            generateId(object);
84            query = generator.generateInsertQuery(object);
85        } else {
86            query = generator.generateUpdateQuery(object);
87        }
88
89        //execute the insert/update query
90        SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(object);
91        template.update(query, parameterSource);
92    }
93
94    /**
95     * Delete the the object with the specified id of the specified objectClass type
96     * @param id the id of the object to be deleted
97     * @param objectClass the class of the object to be deleted
98     */
99    public void delete(int id, Class objectClass) {
100        String query = generator.generateDeleteQuery(objectClass);
101        Map parameterMap = new HashMap();
102        parameterMap.put("id", new Integer(id));
103        template.update(query, parameterMap);
104    }
105
106    //--------------------------------------------------------------------------
107    //PRIVATE METHODS
108    //return true if the object id is zero or null false otherwise
109    private boolean isObjectNew(Object object) throws VenException {
110        BeanWrapper beanWrapper = new BeanWrapperImpl(object);
111        Object objectId = beanWrapper.getPropertyValue("id");
112        if (objectId == null) return true;
113        if (!(objectId instanceof Integer)) throw new VenException(VenException.EC_GENERATOR_OBJECT_ID_TYPE_INVALID);
114        return ((Integer)objectId).intValue() == 0;
115    }
116
117    //set new object id
118    private void generateId(Object object) {
119        Integer newObjectId = new Integer(template.queryForInt(generator.generateSequenceQuery(object), new HashMap()));
120        BeanWrapper beanWrapper = new BeanWrapperImpl(object);
121        beanWrapper.setPropertyValue("id", newObjectId);
122    }
123
124    //--------------------------------------------------------------------------
125    //SETTERS
126    public void setDataSource(DataSource dataSource) {
127        if (dataSource == null) throw new RuntimeException("fmgVen - DataSource cannot be null");
128        this.template = new NamedParameterJdbcTemplate(dataSource);
129        mapper.setDataSource(dataSource);
130    }
131
132    public Ven addDomainPackage(String domainPackage) {
133        generator.addDomainPackage(domainPackage);
134        mapper.addDomainPackage(domainPackage);
135        return this;
136    }
137}
Note: See TracBrowser for help on using the repository browser.