Use spring AOP and Annotation to simplify DAO implementation

Source: Internet
Author: User

We usually define a DAO interface in the database DAO layer query. in the implementation, we just splice the query parameters and specify the sqlid in an ibatis sqlmap for query, the implementation of Dao is very similar and very simple. In fact, this implementation can be simplified without the implementation code. Next we will simplify this implementation through the annotation mechanism. For example, [java] 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-BRANDMEM BERID ", map) ;}...... first, we use a spring project to establish the dependency as follows: [java] <? 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> <d Ependencies> <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> we define two annotationDAO is the annotaion used to add the DAO interface method, you can use nam E. Specify the SQL id in ibatis. This annotation can be used to add parameters such as type to specify the types of dao queries, such as inserti, update, query, and delete. [Java] 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]";} DaoPara pa Ckage 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 {Strin G name () default "paramName";} then defines a DAO interface, which contains a method, [java] 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);} Let's write an empty DAO implementation class, [java] package mySpringWeb; import java. util. list; public class MyDaoImpl implements MyDao {@ Override public List <Object> qu Ery (@ DaoParam (name = "param1") String param1, @ DaoParam (name = "param2") int param2) {// TODO Auto-generated method stub return null ;}} then I wrote a spring AOP interceptor class. [java] 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. findAnn Otation (invocation. getMethod (), Dao. class); // recursively finds whether the annotation if (dao! = Null) {List <String> list = new ArrayList <String> (); list. add (dao. name (); System. out. println (dao. name (); // method name is ibatis sqlid. Here you can inject a dao, input the sqlid, and then return the System. out. println (invocation. getMethod (). getName (); Map <String, Object> paraMap = new HashMap <String, Object> (); Annotation [] [] annotations = invocation. getMethod (). getParameterAnnotations (); Object [] object = invocation. getArguments (); f Or (int I = 0; I <annotations. length; I ++) {for (Annotation an: annotations [I]) {if (. annotationType (). isAssignableFrom (DaoParam. class) {System. out. println (. toString (); paraMap. put (DaoParam) ). name (), object [I]) ;}// dao query parameter map System. out. println (paraMap. toString (); // here ibatis sqlid and query parameter map both know, then you can query the database and then return, for the return type, you can also define several definitions of the return parameter types by defining the returned annotation. // currently, You need to inject a spring DAO implementation. Here, according to annot You can query the database by the type, parameter, and sqlid of ation, and then return the result. This is relatively simple. Return list;} System. out. println ("go to here error"); return null ;}} then configure bean xml in spring, bean. xml. You can configure the same interceptor for multiple DAO statements, and then you can process them in a unified manner. [Java] <? 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" class = "mySpringWeb. MyDaoImpl" /> <Bean id = "myintercept" class = "mySpringWeb. myIntercept "/> <bean id =" mydaobean "class =" org. springframework. aop. framework. proxyFactoryBean "> <property name =" proxyInterfaces "> <value> mySpringWeb. myDao </value> </property> <property name = "interceptorNames"> <list> <value> myintercept </value> <value> mydao </value> </list> </property> </bean> </beans> write a test class: [java] 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 ClassPathXmlAppl IcationContext ("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 (); //} output: MyDaoAnnotataion query @ mySpringWeb. daoParam (name = param1) @ mySpringWeb. daoParam (name = param2) {param1 = test1, param2 = 1} [MyDaoAnnotataion] This method can simplify a bunch of repetitive logic implemented by DAO, you can define annotation in the DAO interface. However, there is an optimization. I don't know if there is any way to define the empty implementation class of every DAO. There should be a way. The details will be further studied later. Also, if annotation is directly passed through invocation. getMethod (). getAnnotation () cannot obtain the annotation defined in the interface. It must be passed through AnnotationUtils. findAnnotation (invocation. getMethod (), Dao. class); annotation of this method.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.