论坛首页 Java企业应用论坛

Spring集成MyBatis进行项目开发(三)

浏览 7583 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2013-12-27  

 

     Spring集成MyBatis进行项目开发(一)

     Spring集成MyBatis进行项目开发(二)

    上两章进行了相关环境的配置和测试,接下来是将继续这个样例系统的Dao层,service层和controller层。

    AppDao.java

package com.pinche.statistic.dao;

import java.util.List;

import com.pinche.statistic.domain.Application;

public interface AppDao {
	boolean add(Application app);

	boolean delete(String appAccount);

	boolean update(Application app);

	Application findByAppAccount(String appAccount);
	
	List<Application> findAll();
}

 AppDaoImpl.java

package com.pinche.statistic.dao.impl;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;

import com.pinche.statistic.dao.AppDao;
import com.pinche.statistic.domain.Application;
import com.pinche.statistic.mapper.ApplicationsMapper;

@Repository
public class AppDaoImpl implements AppDao {

	@Autowired
	private ApplicationsMapper mapper;
	
	@Override
	public boolean add(Application app) {
		try {
			mapper.add(app);
			return true;
		} catch (DataAccessException e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public boolean delete(String appAccount) {
		try {
			mapper.delete(appAccount);
			return true;
		} catch (DataAccessException e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public boolean update(Application app) {
		try {
			mapper.update(app);
			return true;
		} catch (DataAccessException e) {
			e.printStackTrace();
		}
		return false;
	}

	@Override
	public Application findByAppAccount(String appAccount) {
		try {
			Application findByAppAccount = mapper.findByAppAccount(appAccount);
			return findByAppAccount;
		} catch (DataAccessException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public List<Application> findAll() {
		try {
			return mapper.findAll();
		} catch (DataAccessException e) {
			e.printStackTrace();
		}
		return null;
	}
}

 

    自行设计的DAO层对象容器(在DAO对象很多时,如果在service层要调用对应的DAO还得手动注入,通过引用这个DAO层对象容器,可以实现在需要使用DAO时迅速找需要的DAO,省去了繁杂的手动注入,而且spring默认的bean都是单例的,无论在何处注入一个实体bean其实都是同一个。这样做更方便):

package com.pinche.statistic.dao;

import java.lang.reflect.Field;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

@Repository
public class BaseDAL {

	private static final Logger logger = LoggerFactory.getLogger(BaseDAL.class);
	
	@Autowired
	private AppDao _appDao;
	public static AppDao appDao;

	@Autowired
	private MetaDataDao _metaDataDao;
	public static MetaDataDao metaDataDao;

	@Autowired
	private DDLManager _DDLManager;
	public static DDLManager DDLManager;
	
	@Autowired
	private AnalyzeDao _analyzeDao;
	public static AnalyzeDao analyzeDao;
	
	@Autowired
	private DialstatisticsDao _dialstatisticsDao;
	public static DialstatisticsDao dialstatisticsDao;

	@PostConstruct
	public void init() {
		long start = System.currentTimeMillis();
		logger.debug("start init BaseDAL ...");
		try {

			Field[] fields = this.getClass().getDeclaredFields();

			for (int i = 0; i < fields.length; i++) {
				String fieldname = fields[i].getName();
				if (fieldname.startsWith("_")) {
					String sfieldname = fieldname.substring(1);
					Field sfield = this.getClass().getDeclaredField(sfieldname);
					sfield.setAccessible(true);
					sfield.set(this, fields[i].get(this));
				}
			}
			logger.debug("init BaseDAL OVER, consume = {}ms",
					System.currentTimeMillis() - start);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}

 

如果使用了以上的层管理容器,如果要在容器中添加一个DAO(例如:DemoDao),只需在这个容器中添加一个这样的声明:

	@Autowired
	private DemoDao _demoDao;
	public static DemoDao demoDao;

 

    好了下面是service层定义的接口:

    AppService.java

package com.pinche.statistic.service;

import java.util.List;

import com.pinche.statistic.domain.Application;

/**
 * @author JACKWANG
 * @since Dec 23, 2013
 */
public interface AppService {
	
	Application find(String appAccount);
	
	boolean update(Application app);
	
	boolean setDisable(String appAccount);
	
	boolean setEnable(String appAccount);
	
	List<Application> findAll();
	
}

 

    AppServiceImpl.java : AppService的实现类:

package com.pinche.statistic.service.impl;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.pinche.statistic.dao.BaseDAL;
import com.pinche.statistic.domain.Application;
import com.pinche.statistic.service.AppService;
import com.pinche.statistic.utils.SystemUtils;

/**
 * @author JACKWANG
 * @since Dec 23, 2013
 */
@Service
public class AppServiceImpl implements AppService {

	private static final Logger logger = LoggerFactory
			.getLogger(AppServiceImpl.class);

	@Override
	public Application find(String appAccount) {
		return BaseDAL.appDao.findByAppAccount(appAccount);
	}

	
	@Override
	public boolean update(Application app) {
		String appAccount = app.getAppAccount();
		if (appAccount == null && "".equals(appAccount)) {
			return true;
		}
		return BaseDAL.appDao.update(app);
	}

	@Override
	public boolean setDisable(String appAccount) {
		Application app = new Application();
		app.setAppAccount(appAccount);
		app.setIsDisable(Application.APP_DISABLE);
		return BaseDAL.appDao.update(app);
	}

	@Override
	public boolean setEnable(String appAccount) {
		Application app = new Application();
		app.setAppAccount(appAccount);
		app.setIsDisable(Application.APP_ENABLE);
		return BaseDAL.appDao.update(app);
	}

	@Override
	public List<Application> findAll() {
		return BaseDAL.appDao.findAll();
	}
}

   哈哈,使用层对象管理容器是不是很方便。通过一个引用就能获得所有的DAO支持。所以我在service层也构建了一个service层对象管理容器BaseBLL:

BaseBLL.java:

package com.pinche.statistic.service;

import java.lang.reflect.Field;

import javax.annotation.PostConstruct;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @author JACKWANG
 * @since Dec 23, 2013
 */
@Service
public class BaseBLL {
	
	private static final Logger logger = LoggerFactory.getLogger(BaseBLL.class);
	
	@Autowired
	private AnalyzeService _analyzeService;
	public static AnalyzeService analyzeService;

	@Autowired
	private AppService _appService;
	public static AppService appService;

	@Autowired
	private MetaDataService _metaDataService;
	public static MetaDataService metaDataService;

	@PostConstruct
	public void init() {
		long start = System.currentTimeMillis();
		logger.debug("start init BaseBLL ...");
		try {

			Field[] fields = this.getClass().getDeclaredFields();

			for (int i = 0; i < fields.length; i++) {
				String fieldname = fields[i].getName();
				if (fieldname.startsWith("_")) {
					String sfieldname = fieldname.substring(1);
					Field sfield = this.getClass().getDeclaredField(sfieldname);
					sfield.setAccessible(true);
					sfield.set(this, fields[i].get(this));
				}
			}
			logger.debug("init BaseBLL OVER, consume = {}ms",
					System.currentTimeMillis() - start);
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

}

   

    好了下面应该是controller层的编写了,但是由于笔者以上的代码只是摘录了系统中的部分,而在controller中涉及到其他的内容,如果直接摘录可能和以上的代码衔接不上。所以这里就不进行了controller层的具体介绍了。本系统controller层使用的是SpringMVC,开发效率一级赞。

   发表时间:2013-12-30  
Mapper可以自动实例化了,你还非得再加个DAO层,有人DAO层今天用mybatis,明天用hibernate吗?除了像你这种DEMO才会折腾,惯性思维在作怪……
0 请登录后投票
   发表时间:2013-12-30  
根本不需要DAO层了
0 请登录后投票
   发表时间:2014-01-02  
作者的写法应该是沿袭了ibatis的写法。在mybatis中dao只需要定义接口就可以了,框架默认实现mapper。个人认为作者的写法复杂化了。
0 请登录后投票
   发表时间:2014-01-02  
huzhenyu 写道
作者的写法应该是沿袭了ibatis的写法。在mybatis中dao只需要定义接口就可以了,框架默认实现mapper。个人认为作者的写法复杂化了。

这个dao层吧,看具体情况了,没有肯定的不需要之说,再需要的系统里面那会让系统结构更加清晰,再其他系统里面又会变得累赘,比如 大家都感觉spring的注解很好用把,省去了编写配置文件的功夫,但是这也是要分情况的呀,如果在一个庞大的系统中,你使用spring的注解模式管理Bean,那么在后期如果你要找一个特定的bean,那么要从整个系统中找到也是挺费劲呀。
再说说我为什么写dao层,如果业务简单真的感觉太多余。但是我在dao层里面做的主要是将service传递过来的对象参数封装成map,然后再用mybatis实现好的mapper对象进行查询。mybatis的parameterType属性只能传递一个参数,在查询条件比较复杂的时候用map最合适了,我可以将多个没有联系的参数存放到map中,并且向service层屏蔽了map的key到底应该怎么设置的问题。
比如:
Dao中的一个方法:  
List query(Teacher teach,Student stu,String year,String month){
    Map map = bean2Map(teach,stu)
    map.put("YEAR",year);
    map.put("MONTH",month);
    return mapper.query(map);
}
0 请登录后投票
   发表时间:2014-01-03  
wangjie2013 写道
huzhenyu 写道
作者的写法应该是沿袭了ibatis的写法。在mybatis中dao只需要定义接口就可以了,框架默认实现mapper。个人认为作者的写法复杂化了。

这个dao层吧,看具体情况了,没有肯定的不需要之说,再需要的系统里面那会让系统结构更加清晰,再其他系统里面又会变得累赘,比如 大家都感觉spring的注解很好用把,省去了编写配置文件的功夫,但是这也是要分情况的呀,如果在一个庞大的系统中,你使用spring的注解模式管理Bean,那么在后期如果你要找一个特定的bean,那么要从整个系统中找到也是挺费劲呀。
再说说我为什么写dao层,如果业务简单真的感觉太多余。但是我在dao层里面做的主要是将service传递过来的对象参数封装成map,然后再用mybatis实现好的mapper对象进行查询。mybatis的parameterType属性只能传递一个参数,在查询条件比较复杂的时候用map最合适了,我可以将多个没有联系的参数存放到map中,并且向service层屏蔽了map的key到底应该怎么设置的问题。
比如:
Dao中的一个方法:  
List query(Teacher teach,Student stu,String year,String month){
    Map map = bean2Map(teach,stu)
    map.put("YEAR",year);
    map.put("MONTH",month);
    return mapper.query(map);
}

Dao应该尽量避免业务逻辑,楼主想法很好
不过想问的是bean2Map这个方法是如何实现的,如果Teacher和Student里有相同的属性名叫name,会不会产生冲突.谢谢了!
0 请登录后投票
   发表时间:2014-01-03  
qi_w2006 写道
wangjie2013 写道
huzhenyu 写道
作者的写法应该是沿袭了ibatis的写法。在mybatis中dao只需要定义接口就可以了,框架默认实现mapper。个人认为作者的写法复杂化了。

这个dao层吧,看具体情况了,没有肯定的不需要之说,再需要的系统里面那会让系统结构更加清晰,再其他系统里面又会变得累赘,比如 大家都感觉spring的注解很好用把,省去了编写配置文件的功夫,但是这也是要分情况的呀,如果在一个庞大的系统中,你使用spring的注解模式管理Bean,那么在后期如果你要找一个特定的bean,那么要从整个系统中找到也是挺费劲呀。
再说说我为什么写dao层,如果业务简单真的感觉太多余。但是我在dao层里面做的主要是将service传递过来的对象参数封装成map,然后再用mybatis实现好的mapper对象进行查询。mybatis的parameterType属性只能传递一个参数,在查询条件比较复杂的时候用map最合适了,我可以将多个没有联系的参数存放到map中,并且向service层屏蔽了map的key到底应该怎么设置的问题。
比如:
Dao中的一个方法:  
List query(Teacher teach,Student stu,String year,String month){
    Map map = bean2Map(teach,stu)
    map.put("YEAR",year);
    map.put("MONTH",month);
    return mapper.query(map);
}

Dao应该尽量避免业务逻辑,楼主想法很好
不过想问的是bean2Map这个方法是如何实现的,如果Teacher和Student里有相同的属性名叫name,会不会产生冲突.谢谢了!

哥们儿 挺执着,teacher用key:teacher.name  student用key:student.name
0 请登录后投票
   发表时间:2014-01-06   最后修改:2014-01-06
wangjie2013 写道
huzhenyu 写道
作者的写法应该是沿袭了ibatis的写法。在mybatis中dao只需要定义接口就可以了,框架默认实现mapper。个人认为作者的写法复杂化了。

这个dao层吧,看具体情况了,没有肯定的不需要之说,再需要的系统里面那会让系统结构更加清晰,再其他系统里面又会变得累赘,比如 大家都感觉spring的注解很好用把,省去了编写配置文件的功夫,但是这也是要分情况的呀,如果在一个庞大的系统中,你使用spring的注解模式管理Bean,那么在后期如果你要找一个特定的bean,那么要从整个系统中找到也是挺费劲呀。
再说说我为什么写dao层,如果业务简单真的感觉太多余。但是我在dao层里面做的主要是将service传递过来的对象参数封装成map,然后再用mybatis实现好的mapper对象进行查询。mybatis的parameterType属性只能传递一个参数,在查询条件比较复杂的时候用map最合适了,我可以将多个没有联系的参数存放到map中,并且向service层屏蔽了map的key到底应该怎么设置的问题。
比如:
Dao中的一个方法:  
List query(Teacher teach,Student stu,String year,String month){
    Map map = bean2Map(teach,stu)
    map.put("YEAR",year);
    map.put("MONTH",month);
    return mapper.query(map);
}



人家说你是“是沿袭了ibatis的写法”,这句话一点也没错啊!

更要命的是,你的反驳竟然进一步支持了他的观点!

因为你不知道Mybatis可以支持多个参数,包括相同类型的参数!相反,你继续沿用ibatis的方法:用Map来实现!

在Mybatis中用注解@Param就可以实现,具体用法可以上网学习下!





 

0 请登录后投票
   发表时间:2014-01-06   最后修改:2014-01-06
hellostory 写道
wangjie2013 写道
huzhenyu 写道
作者的写法应该是沿袭了ibatis的写法。在mybatis中dao只需要定义接口就可以了,框架默认实现mapper。个人认为作者的写法复杂化了。

这个dao层吧,看具体情况了,没有肯定的不需要之说,再需要的系统里面那会让系统结构更加清晰,再其他系统里面又会变得累赘,比如 大家都感觉spring的注解很好用把,省去了编写配置文件的功夫,但是这也是要分情况的呀,如果在一个庞大的系统中,你使用spring的注解模式管理Bean,那么在后期如果你要找一个特定的bean,那么要从整个系统中找到也是挺费劲呀。
再说说我为什么写dao层,如果业务简单真的感觉太多余。但是我在dao层里面做的主要是将service传递过来的对象参数封装成map,然后再用mybatis实现好的mapper对象进行查询。mybatis的parameterType属性只能传递一个参数,在查询条件比较复杂的时候用map最合适了,我可以将多个没有联系的参数存放到map中,并且向service层屏蔽了map的key到底应该怎么设置的问题。
比如:
Dao中的一个方法:  
List query(Teacher teach,Student stu,String year,String month){
    Map map = bean2Map(teach,stu)
    map.put("YEAR",year);
    map.put("MONTH",month);
    return mapper.query(map);
}



人家说你是“是沿袭了ibatis的写法”,这句话一点也没错啊!

更要命的是,你的反驳竟然进一步支持了他的观点!

因为你不知道Mybatis可以支持多个参数,包括相同类型的参数!相反,你继续沿用ibatis的方法:用Map来实现!

在Mybatis中用注解@Param就可以实现,具体用法可以上网学习下!





 

没用过mybatis的注解,的确是刚知道用注解可以实现多参数的传递,谢谢提醒,学习了

0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics