Permalink
Browse files

First Commit

  • Loading branch information...
0 parents commit 663a36af8bec4256882260e1ffa190343788c498 @idleworx committed Sep 24, 2011
@@ -0,0 +1,9 @@
+The MIT License (MIT)
+
+Copyright (c) 2011 http://www.idleworx.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,9 @@
+A helper framework for using MyBatis with the DAO pattern.
+Created by http://www.idleworx.com http://blog.idleworx.com http://twitter.com/idleworx
+
+Dependencies (available in the lib folder):
+=========================================
+- mybatis(latest).jar
+- slf4j | logback
+- junit4 for running the tests
+- mysql jdbc driver
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,18 @@
+package com.idleworx.mybatisdao;
+
+import java.util.ArrayList;
+
+import org.apache.ibatis.exceptions.PersistenceException;
+
+/**
+ * Generic implementation of DAO pattern
+ * http://www.ibm.com/developerworks/java/library/j-genericdao.html
+ */
+public interface IParentDAO<T, PK>{
+ public T get(PK id) throws PersistenceException;//get obj of type T by the primary key 'id'
+ public T getByName(String name) throws PersistenceException;//get obj of type T by the 'name' field, if one exists for that table
+ public ArrayList<T> getAll() throws PersistenceException;//get all objects of type T
+ public int create(T objInstance) throws PersistenceException;//insert an object of type T into the database
+ int update(T transientObject) throws PersistenceException; //update an object of type T
+ int delete(PK id) throws PersistenceException;//delete an object of type T
+}
@@ -0,0 +1,229 @@
+package com.idleworx.mybatisdao;
+
+import java.util.ArrayList;
+
+import org.apache.ibatis.exceptions.PersistenceException;
+import org.apache.ibatis.session.SqlSession;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class contains all the basic CRUD related methods which are inherited by all objects.
+ * Children daos should generally not overwrite these method but add extra ones as needed.
+ */
+public abstract class MyBatisDAO<T, PK> implements IParentDAO<T, PK>{
+
+ private static Logger log = LoggerFactory.getLogger(MyBatisDAO.class);
+ private static final String NAMESPACE = "mappers";
+
+ private SqlSessionFactory sf; //reference to mybatis session factory
+ private Class<T> type;
+
+ /**
+ * Define prefixes for easier naming convetions between XML mapper files and the DAO class
+ **/
+ public static final String PREFIX_SELECT_QUERY = "get"; //prefix of select queries in mapper files (eg. getAddressType)
+ public static final String PREFIX_INSERT_QUERY = "create"; //prefix of create queries in mapper files (eg. createAddressType)
+ public static final String PREFIX_UPDATE_QUERY = "update"; //prefix of update queries in mapper files (eg. updateAddressType)
+ public static final String PREFIX_DELETE_QUERY = "delete"; //prefix of delete queries in mapper files (eg. deleteAddressType)
+
+ /** Default Constructor */
+ public MyBatisDAO(Class<T> type,SqlSessionFactory sf) {
+ this.type = type;
+ this.sf = sf;
+ if(sf==null)
+ log.error("Error: Could not instantiate MyBatisDAO. Loading myBatis sessionFactory failed.");
+ }
+
+ /** Use this method to get a session factory for using in any methods impelmented in child dao classes */
+ protected SqlSessionFactory getSessionFactory() {
+ return sf;
+ }
+
+ /**
+ * Default get by id method.
+ * </br></br>
+ * Almost all objects in the db will
+ * need this (except mapping tables for multiple joins, which you
+ * probably shouldn't even have as objects in your model, since proper
+ * MyBatis mappings can take care of that).
+ * </br></br>
+ * Example:
+ * </br>
+ * If your DAO object is called CarInfo.java,
+ * the corresponding mapper query id should be: &lt;select id="getCarInfo" ...
+ */
+ public T get(PK id) throws PersistenceException {
+
+ SqlSession session = sf.openSession();
+ T obj = null;
+ try
+ {
+ String query = NAMESPACE+"."+PREFIX_SELECT_QUERY+this.type.getSimpleName(); //If the object's calls name is AddressType.java, this matches the mapper query id: "namespace.getAddressType"
+ obj = (T)session.selectOne(query,id);
+ }
+ finally
+ {
+ session.close();
+ }
+ return obj;
+ }
+
+ /**
+ * Method returns all rows for this object.
+ * </br></br>
+ * Example:
+ * </br>
+ * If your DAO object is called CarInfo.java,
+ * the corresponding mapper query id should be: &lt;select id="getAllCarInfo" ...
+ * </br></br>
+ * SQL Executed: select * from [tablename]
+ * </br></br>
+ * Notes:
+ * </br>
+ * Consider overdiding this method in order to handle large numbers of objects
+ * with multiple references.
+ * LAZY LOADING should be enabled in this case, otherwise you might run out of memory (eg. get all UserAccounts if the table has 1,000,000 rows)
+ * look into the aggresiveLazyLoading property
+ * */
+ public ArrayList<T> getAll() throws PersistenceException {
+
+ SqlSession session = sf.openSession();
+ ArrayList<T> list = null;
+ try
+ {
+ String query = NAMESPACE+"."+PREFIX_SELECT_QUERY+"All"+this.type.getSimpleName();
+ list = (ArrayList<T>)session.selectList(query);
+ }
+ finally
+ {
+ session.close();
+ }
+ return list;
+ }
+
+ /**
+ * Method returns first object which matches the given name (exact match).
+ * </br></br>
+ * It's up to you to decide what constitutes an object's name. Typically you would have a
+ * NAME column in the table, but not all objects have this. Generally this method should be overriden (if you need it at all)
+ * in the child dao class.
+ * </br></br>
+ * Example:
+ * </br>
+ * If your DAO object is called CarInfo.java,
+ * the corresponding mapper query id should be: &lt;select id="getCarInfoByName" ...
+ * </br></br>
+ * SQL Executed (example): select * from [tablename] where NAME = ?
+ *
+ */
+ public T getByName(String name) throws PersistenceException {
+
+ SqlSession session = sf.openSession();
+ T obj = null;
+ try
+ {
+ String query = NAMESPACE+"."+PREFIX_SELECT_QUERY+this.type.getSimpleName()+"ByName";
+ obj = (T)session.selectOne(query,name);
+ }
+ finally
+ {
+ session.close();
+ }
+ return obj;
+ }
+
+
+ /**
+ * Method inserts the object into the table.
+ * </br></br>
+ * You will usually override this method, especially if you're inserting associated objects.
+ * </br>
+ * Example:
+ * </br>
+ * If your DAO object is called CarInfo.java,
+ * the corresponding mapper query id should be: &lt;insert id="createCarInfo" ...
+ * </br></br>
+ * SQL Executed (example): insert into [tablename] (fieldname1,fieldname2,...) values(value1,value2...) ...
+ *
+ */
+ public int create(T o) throws PersistenceException{
+ SqlSession session = sf.openSession();
+ Integer status = null;
+ try
+ {
+ String query = NAMESPACE+"."+PREFIX_INSERT_QUERY+o.getClass().getSimpleName();
+ status = (Integer)session.insert(query,o);
+ session.commit();
+ }
+ finally
+ {
+ session.close();
+ }
+ return status;
+ }
+
+
+ /**
+ * Method updates the object by id.
+ * </br></br>
+ * You will usually override this method. But it can be used for simple objects.
+ * </br>
+ * Example:
+ * </br>
+ * If your DAO object is called CarInfo.java,
+ * the corresponding mapper query id should be: &lt;update id="updateCarInfo" ...
+ * </br></br>
+ * SQL Executed (example): update [tablename] set fieldname1 = value1 where id = #{id}
+ *
+ */
+ public int update(T o)throws PersistenceException {
+
+ SqlSession session = sf.openSession();
+ Integer status = null;
+ try
+ {
+ String query = NAMESPACE+"."+PREFIX_UPDATE_QUERY+o.getClass().getSimpleName();
+ status = session.update(query,o);
+ session.commit();
+
+ }
+ finally
+ {
+ session.close();
+ }
+ return status;
+
+ }
+
+
+ /**
+ * Method deletes the object by id.
+ * </br></br>
+ * Example:
+ * </br>
+ * If your DAO object is called CarInfo.java,
+ * the corresponding mapper query id should be: &lt;delete id="deleteCarInfo" ...
+ * </br></br>
+ * SQL Executed (example): update [tablename] set fieldname1 = value1 where id = #{id}
+ *
+ */
+ public int delete(PK id) throws PersistenceException{
+ SqlSession session = sf.openSession();
+ Integer status = null;
+ try
+ {
+ String query = NAMESPACE+"."+PREFIX_DELETE_QUERY+this.type.getSimpleName();
+ status = session.delete(query,id);
+ session.commit();
+ }
+ finally
+ {
+ session.close();
+ }
+ return status;
+
+ }
+}
+
@@ -0,0 +1,101 @@
+package com.idleworx.mybatisdao.tests;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.Reader;
+import java.util.ArrayList;
+
+import org.apache.ibatis.io.Resources;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.session.SqlSessionFactoryBuilder;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.idleworx.mybatisdao.tests.dao.StatusDAO;
+import com.idleworx.mybatisdao.tests.objects.Status;
+
+
+public class TestStatusDAO {
+
+ private static Logger log = LoggerFactory.getLogger(TestStatusDAO.class);
+ private static SqlSessionFactory sf;
+ private static StatusDAO statusDao;
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ log.info("starting up myBatis tests");
+ String resource = "mybatis.config.xml";
+ Reader reader = Resources.getResourceAsReader(resource);
+ sf = new SqlSessionFactoryBuilder().build(reader,"testing");
+ statusDao = new StatusDAO(Status.class,sf);
+ }
+
+ @Test
+ public void getStatus(){
+ log.debug("getStatus()");
+ Status s = statusDao.get(1);
+ assertNotNull(s);
+ log.info("Status: " + s.toString());
+ }
+
+ @Test
+ public void getStatusByName(){
+ log.debug("getStatusByName()");
+
+ Status s = statusDao.getByName("Done");
+ assertNotNull(s);
+ log.info("Status: " + s.toString());
+ }
+
+ @Test
+ public void getAllStatuses(){
+ log.debug("getAllStatuses()");
+
+ ArrayList<Status> list = statusDao.getAll();
+ assertNotNull(list);
+ printToStringArray(list);
+
+ }
+
+ @Test
+ public void createStatus(){
+ log.debug("createStatus()");
+
+ Status s = new Status();
+ s.setName("TestStatus");
+ Integer result = statusDao.create(s);
+ assertNotNull(result);
+ log.info("insert result: " + result);
+
+ }
+
+ @Test
+ public void updateStatus(){
+ log.debug("updateStatus()");
+
+ Status s = new Status();
+ s.setId(4);//the status id to update
+ s.setName("TestStatusUpdated");
+ Integer result = statusDao.update(s);
+ assertNotNull(result);
+ log.info("update result: " + result);
+ }
+
+ @Test
+ public void deleteStatus(){
+ log.debug("deleteStatus()");
+ Integer result = statusDao.delete(5);
+ assertNotNull(result);
+ log.info("delete result: " + result);
+
+ }
+
+ private static void printToStringArray(ArrayList<?> a){
+ for(int i = 0;i<a.size();i++){
+ log.info(a.get(i).toString());
+ }
+ }
+
+}
@@ -0,0 +1,17 @@
+package com.idleworx.mybatisdao.tests.dao;
+
+import org.apache.ibatis.session.SqlSessionFactory;
+
+import com.idleworx.mybatisdao.MyBatisDAO;
+import com.idleworx.mybatisdao.tests.objects.Status;
+
+/** Simple example DAO which uses the MyBatisDAO Helper Framework */
+public class StatusDAO extends MyBatisDAO<Status,Integer>{
+
+ //Don't forget to define the default custom constructor when implementing a new
+ //child DAO class, and set the class type accordingly
+ public StatusDAO(Class<Status> type,SqlSessionFactory containerSessionFactory) {
+ super(type,containerSessionFactory);
+ }
+
+}
Oops, something went wrong.

0 comments on commit 663a36a

Please sign in to comment.