通常在数据库DAO层的查询中,我们会定义一个DAO接口,而在实现中我们只是拼接查询参数并且指定一个ibatis的sqlmap中的sqlid进行查询,
Dao的实现很类似,而且非常简单,其实可以简化这种的实现,不需要这些实现代码,下面我们通过annotation机制来简化这块的实现。
比如
public class TestDaoImpl extends SqlMapClientDaoSupport implements TestDao { @Override public int updateBrandOfferStatusByBrandMemberId(Long brandMemberId, String operator, String status) { Map<String, Object> map = new HashMap<String, Object>(); map.put("brandMemberId", brandMemberId); map.put("operator", operator); map.put("status", status); return this.getSqlMapClientTemplate().update("BRANDOFFER.UPDATE-BRANDOFFER-BY-BRANDMEMBERID", map); } @Override public List<Long> queryOfferIdsByBrandMemberId(Long brandMemberId, Integer start, Integer end) { Map<String, Object> map = new HashMap<String, Object>(); map.put("brandMemberId", brandMemberId); map.put("start", start); map.put("end", end); return this.getSqlMapClientTemplate().queryForList("BRANDOFFER.SELECT-OFFERIDLIST-BY-BRANDMEMBERID", map); } ...... }
首先,我们使用建立一个spring的工程,依赖如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>mySpringWeb</groupId> <artifactId>springDemo</artifactId> <packaging>jar</packaging> <version>1.0.0-SNAPSHOT</version> <name>Started with Laurel</name> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>3.2.0.RELEASE</version> </dependency> </dependencies> <repositories> <repository> <id>springsource-repo</id> <name>SpringSource Repository</name> <url>http://repo.springsource.org/release</url> </repository> </repositories> </project>
我们定义两个annotation
DAO是用来加在DAO接口的方法上的annotaion,可以通过name指定ibatis中的sql id,这个annotation可以添加type之类的参数,可以用来指定dao查询的类型,inserti,update,query,delete等类型。
package mySpringWeb; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Inherited @Target({ ElementType.METHOD, ElementType.TYPE}) public @interface Dao { String name() default "[defaultMethod]"; }
DaoParam是用来在DAO方法的参数上加的annotation,用来指定ibatis查询map参数的构造,map的key名称
package mySpringWeb; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Inherited @Target({ElementType.FIELD, ElementType.METHOD, ElementType.LOCAL_VARIABLE, ElementType.PARAMETER}) public @interface DaoParam { String name() default "paramName"; }
然后定义一个DAO接口,里面有一个方法,
package mySpringWeb; import java.util.List; public interface MyDao { @Dao(name="MyDaoAnnotataion") public List<Object> query(@DaoParam(name="param1")String param1, @DaoParam(name="param2")int param2); }
我们写一个空的DAO实现类,
package mySpringWeb; import java.util.List; public class MyDaoImpl implements MyDao{ @Override public List<Object> query(@DaoParam(name="param1")String param1, @DaoParam(name="param2")int param2) { // TODO Auto-generated method stub return null; } }
然后就是写一个spring AOP的 拦截器类了,
package mySpringWeb; import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.core.annotation.AnnotationUtils; public class MyIntercept implements MethodInterceptor{ static{ try { Class.forName("mySpringWeb.Dao"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public Object invoke(MethodInvocation invocation) throws Throwable { Dao dao = AnnotationUtils.findAnnotation(invocation.getMethod(), Dao.class);//递归查找该方法是否定义了这个annotation if(dao != null){ List<String> list = new ArrayList<String>(); list.add(dao.name()); System.out.println(dao.name()); //method name就是ibatis sqlid,这里可以注入一个dao,然后传入sqlid,执行返回 System.out.println(invocation.getMethod().getName()); Map<String,Object> paraMap = new HashMap<String,Object>(); Annotation[][] annotations = invocation.getMethod().getParameterAnnotations(); Object[] object = invocation.getArguments(); for(int i = 0; i < annotations.length;i++){ for(Annotation an: annotations[i]){ if(an.annotationType().isAssignableFrom(DaoParam.class)){ System.out.println(an.toString()); paraMap.put(((DaoParam)an).name(), object[i]); } } } //dao查询参数map System.out.println(paraMap.toString()); //这里ibatis sqlid和查询参数map都知道,那么就可以进行数据库查询,然后返回了,对于返回类型也可以通过定义返回的annotation进行返回参数类型的几种定义 //当前这里需要注入spring的DAO的一个实现,这里根据annotation的类型和参数以及sqlid就可以进行数据库查询,然后返回,这里就比较简单了。 return list; } System.out.println("go to here error"); return null; } }
再进行spring的bean xml配置,bean.xml,这里可以对多个DAO进行配置同一个拦截器,然后就可以统一处理了。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <bean id="mydao" /> <bean id="myintercept" /> <bean id="mydaobean" > <property name="proxyInterfaces"> <value>mySpringWeb.MyDao</value> </property> <property name="interceptorNames"> <list> <value>myintercept</value> <value>mydao</value> </list> </property> </bean> </beans>
写一个测试类:
package mySpringWeb; import java.util.List; import org.springframework.context.support.ClassPathXmlApplicationContext; public class MyTest { // @Resource // private MyDao myDao; // // public void test(){ // List<Object> list = myDao.query(); // System.out.println(list); // } public static void main(String[] args) throws InstantiationException, IllegalAccessException, ClassNotFoundException { MyDao myDao = (MyDao) new ClassPathXmlApplicationContext("bean.xml").getBean("mydaobean"); List<Object> list = myDao.query("test1", 1); System.out.println(list); // System.out.println(myDao.toString()); // MyDao myDao1 = (MyDao) Class.forName("mySpringWeb.MyDaoImpl").newInstance(); // Method[] methods = myDao1.getClass().getMethods(); // for(Method method: methods){ // Annotation[] annos = method.getAnnotations(); // for(Annotation anno: annos){ // System.out.println(anno.getClass().getName()); // } // } } }
输出:
MyDaoAnnotataion query @mySpringWeb.DaoParam(name=param1) @mySpringWeb.DaoParam(name=param2) {param1=test1, param2=1} [MyDaoAnnotataion]
这种方式就可以简化DAO实现的一堆重复逻辑,通过在DAO 的interface中annotation定义好就可以了。
不过有个优化,不知道有没有办法不用定义每一个DAO的空实现类,应该是有办法的。具体的后面再研究。还有annotation如果直接通过invocation.getMethod().getAnnotation()是获取不到接口中定义的annotation的,必须得通过AnnotationUtils.findAnnotation(invocation.getMethod(), Dao.class);这个方法查询方法的annotation。
已有 0 人发表留言,猛击->>这里<<-参与讨论
public class User implements Serializable{ private String id;
@Controller @SessionAttributes(Constants.USER_INFO_SESSION) public class LoginControll { @RequestMapping(value = "login.html", method = RequestMethod.POST) public String login( @RequestParam(value = "username", required = false) String username, @RequestParam(value = "password", required = false) String password, @ModelAttribute(Constants.USER_INFO_SESSION)SysUser user, HttpSession session Model model) { SysUser user = userService.validateLogin(username, password); System.out.println(user.getId()); model.addAttribute(Constants.USER_INFO_SESSION); return Constants.RESULT_SUCCESS; } }
输出:11000
@Controller @RequestMapping("/User") @SessionAttributes(Constants.USER_INFO_SESSION) public class UserControll { public @ResponseBody List<?> list( @RequestParam(value = "node", required = false)String node, @ModelAttribute(Constants.USER_INFO_SESSION)SysUser user, HttpSession session ) { System.out.println("user.getId():"+user.getId()); User u = (User)session.getAttribute(Constants.USER_INFO_SESSION); System.out.println("u.getId():"+u.getId());
输出:
user.getId():00
u.getId():00
session去USER对象id值变成了'00'
发现请求参数中有同名id,值是'00'
@Controller @RequestMapping("/User") @SessionAttributes(Constants.USER_INFO_SESSION) public class UserControll { public @ResponseBody List<?> list( @RequestParam(value = "node", required = false)String node, @RequestParam(value = "id", required = false)String id, @ModelAttribute(Constants.USER_INFO_SESSION)SysUser user, HttpSession session ) { System.out.println("id:" + id); System.out.println("user.getId():"+user.getId()); User u = (User)session.getAttribute(Constants.USER_INFO_SESSION); System.out.println("u.getId():"+u.getId());
输出:
id:00
user.getId():00
u.getId():00
请求中参数有同名id,会覆盖session中所有对象同名属性值
改成如下
@Controller @RequestMapping("/User") public class UserControll { public @ResponseBody List<?> list( @RequestParam(value = "node", required = false)String node, @RequestParam(value = "id", required = false)String id, HttpSession session ) { System.out.println("id:" + id); User u = (User)session.getAttribute(Constants.USER_INFO_SESSION); System.out.println("u.getId():"+u.getId());
输出:
id:00
u.getId():11000
已有 0 人发表留言,猛击->>这里<<-参与讨论
ITeye推荐
- —软件人才免语言低担保 赴美带薪读研!—
本系列文章由zhmxy555(毛星云)编写,转载请注明出处。
文章链接: http://blog.csdn.net/zhmxy555/article/details/8475261
作者:毛星云(浅墨) 邮箱: happylifemxy@163.com
本篇文章里,我们对Direct3D之中几种几何体的简洁绘制方法进行了详细的剖析,最后依旧是提供文章配套的详细注释的demo源代码的欣赏,并在文章末尾提供了源代码下载。(这标题有些歧义的,这个几种是修饰几何体的,而绘制的方法只有一种 :D)
首先需要跟大家道声歉,上个周末因为浅墨个人的原因。没把想写的内容的思路整理好,所以就停更了一次。
好了,别的废话咱不说了,下面直奔本周主题~
一、D3D中内置的几何体概述
通过前面的讲解大家应该会发现,使用顶点缓存和索引缓存通过绘制三角形单元来绘制图形还是有一点复杂的,需要一定的想象力和大量顶点和索引的设置,我们一般很少去这样通过逐个设置顶点缓存和索引缓存来进行画面上几何体的绘制的。而比较人性化的是,Direct3D为我们提供了几种特殊的生成简单3D几何体的网格数据的方法。可以说是在我们学习从文件载入网格数据之前,为我们创建了很多便利,丰富了我们的学习时的图形素材。下面我们就来看看这几个快捷的几何体绘制函数,他们分别是立方体(Cube),圆环体(Torus),多边形(Polygon),球面体(Sphere),茶壶(Teapot)和圆柱体(Cylinder)。
我们可以在DirectX SDK(以目前最新的Microsoft DirectX SDK (June 2010)为例)的Windows DirectX Graphics.chm文档中依次展开【Windows DirectX Graphics Documentation】->【Direct3D 9 Graphics】->【Reference for Direct3D 9】->【D3DX Reference】->【D3DX Functions】->【Shape Drawing Functions】找到这些函数的说明文档,这是这些函数最官方最原始的参考地址了。
不过显然这些DirectX SDK Document都是纯英文的,和大众之间的距离还是比较疏远。
先给大家看看这几个函数的全家福,后面我们会全部详细介绍使用方法的:
D3DXCreateBox 用于创建一个盒子,立方体
D3DXCreateSphere 用于创建一个球面体
D3DXCreateCylinder 用于创建一个柱体
D3DXCreateTeapot 用于创建一个茶壶
D3DXCreatePolygon 用于创建一个多边形
D3DXCreateTorus 用于创建一个圆环体
我们可以看到这些函数的名字取的都非常的憨厚老实,一开始是D3DX,然后紧跟其后一个Create,表示是在创建某东西,最后跟上对应的几何体名,比如Teapot茶壶,这样连起来就非常好记忆了,D3DXCreateTeapot。
二、D3D中几种内置的几何体绘制四步曲
首先需要说明的是下面提到的ID3DXMesh接口类型是后面我们在讲解网格相关知识的时候重点讲解的内容,这里大家先对其有一个大概的印象就可以了。
想要通过这几个函数快捷绘制出一个几何体,需要以下几步:
1.定义一个ID3DXMesh接口类型的对象。
2.调用这六个函数的其中一个对我们在第一步里面定义的这个对象进行初始化,也就是把创建好的网格存储在我们定义好的ID3DXMesh类型的对象中
3.在Direct3D渲染五步曲的第三步,也就是在BeginScene之后调用DrawSubset方法进行网格图形的绘制,即是拿着第二步里面初始化好的ID3DXMesh接口类型的对象指一下DrawSubset(0)方法就好了
4.绘制完成之后,调用ID3DMesh接口的Release方法,或者我们自定义的COM接口释放宏进行资源的释放。