利用反射搭建项目的dao层,从此可以告别被人的dao层框架了(spring+反射)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用反射搭建项目的dao层,从此可以告别被人的dao层框架了(spring+反射)相关的知识,希望对你有一定的参考价值。

作为一名刚入手的小白程序猿,不但"TA"不懂我们,就连自己都不懂自己,苦逼的程序猿,只能每天都是在给自己充电了。让"TA"和自己更了解。今天笔者又来吹吹水了,各位客官请买好零食咯,好了废话不多说了。
在以前做项目的时候,一般想到搭项目都是用别人的框架来做,但是别人的框架都是别人封装好的很多东西,对不太熟源码的码农来说就是苦逼呀,所以像笔者这种小白又不甘心,所以笔者就用反射来自己封装一个操作dao层的框架(不算一个框架,就是这么称呼吧),说起反射可能是很多像笔者这样的小白都不了解吧(不过好在笔者有点小聪明,自己学习一下)。其实大家在做项目时用的框架都是用反射来搭起来的,所以反射我们并不陌生,先不说太多了,怎么搭建自己dao层,笔者今天的实例子是用(spring+反射)搭建的Webapp,怎么入手呢 ,如下:
①:首先我们搭建springmvc的配置吧(笔者喜欢这样的方式呢),先创建一个springmvc.xml的文件吧:配置文件如下:

 <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">

		<!--自动注解,扫描如下包 -->
        <mvc:annotation-driven/>
        <context:component-scan base-package="com.yw.Contrlloer"/>
        <bean class="org.springframework.web.servlet.mvc.support.ControllerBeanNameHandlerMapping"></bean>
</beans>

  没错springmvc的配置文件就是这样简单就行了。

② 配好springmvc 接下来就是配置spring了 ,配spring的配置之前我们创建数据库的配置文件先 jdbc.properties。jdbc.properties的配置如下:

validationQuery=SELECT 1
	jdbc_URL=jdbc:mysql://127.0.0.1:3306/testredis?useUnicode=true&characterEncoding=UTF-8
	jdbc_username=root
	jdbc_password=123456
	initialSize=0
	maxActive=20
	maxIdle=20
	minIdle=0
	maxWait=6000
	timeBetweenEvictionRunsMillis=60000
	minEvictableIdleTimeMillis=25200000
	removeAbandonedTimeout=1800

  然后就是spring的配置的文件了,对了笔者这里用的是阿里的连接池哦,为什么用阿里的,因为是阿里的(哈哈,是因为它强大呢) 配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd">
   
  <context:annotation-config/>
  <context:component-scan base-package="com.yw.dao"/>
   <context:component-scan base-package="com.yw.service"/>
  <!-- 引入属性文件 -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="locations" value="classpath:com/yw/conf/config.properties"></property>
    </bean>
    

    <!-- 配置数据源 -->
    <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
		<property name="url" value="${jdbc_URL}" />
		<property name="username" value="${jdbc_username}" />
		<property name="password" value="${jdbc_password}" />
		<!-- 初始化连接大小 -->
		<property name="initialSize" value="${initialSize}" />
		<!-- 连接池最大使用连接数量 -->
		<property name="maxActive" value="${maxActive}" />
		<!-- 连接池最大空闲 -->
		<property name="maxIdle" value="${maxIdle}" />
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="${minIdle}" />
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="${maxWait}" />

		<!-- <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="33" /> -->

		<property name="validationQuery" value="${validationQuery}" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
		<property name="testWhileIdle" value="true" />

		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="${timeBetweenEvictionRunsMillis}" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="${minEvictableIdleTimeMillis}" />

		<!-- 打开removeAbandoned功能 -->
		<property name="removeAbandoned" value="true" />
		<!-- 1800秒,也就是30分钟 -->
		<property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}" />
		<!-- 关闭abanded连接时输出错误日志 -->
		<property name="logAbandoned" value="true" />

		<!-- 监控数据库 -->
		<!-- <property name="filters" value="stat" /> -->
		<property name="filters" value="mergeStat" />
    </bean>
   <!-- 配置Jdbc模板  --> 
  <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" >
    <constructor-arg ref="dataSource"></constructor-arg>
  </bean> 

    <bean id="baseDao" class="com.yw.dao.BaseDao" abstract="true">
    	 <property name="jdbcTemplate" ref="jdbcTemplate"/>  
    </bean>
    <bean id="userDAo" class="com.yw.dao.UserDao" parent="baseDao"/>  
    
    <!-- 配置事务管理器 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	<tx:advice id="transactionAdvice" transaction-manager="transactionManager">
		<tx:attributes>
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="append*" propagation="REQUIRED" />
			<tx:method name="insert*" propagation="REQUIRED" />
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="modify*" propagation="REQUIRED" />
			<tx:method name="edit*" propagation="REQUIRED" />
			<tx:method name="delete*" propagation="REQUIRED" />
			<tx:method name="remove*" propagation="REQUIRED" />
			<tx:method name="repair" propagation="REQUIRED" />
			<tx:method name="delAndRepair" propagation="REQUIRED" />
			<tx:method name="get*" propagation="SUPPORTS" />
			<tx:method name="find*" propagation="SUPPORTS" />
			<tx:method name="load*" propagation="SUPPORTS" />
			<tx:method name="search*" propagation="SUPPORTS" />
			<tx:method name="datagrid*" propagation="SUPPORTS"  />
			<tx:method name="*" propagation="SUPPORTS" />
		</tx:attributes>
	</tx:advice>
	<aop:config>
		<aop:pointcut id="transactionPointcut" expression="execution(* com.yw.service..*(..))" />
		<aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
	</aop:config>
</beans>

  

好了配置文件就这样可以了。
③ 接来下就是配置web.xml 的文件了:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>WebApp</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
   <!-- spring的配置 开始 -->
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath*:com/yw/conf/spring.xml</param-value>
  </context-param>
  <listener>
  	 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>  
   <!-- spring的配置 结束 -->
   
  <!-- springmvc的配置 开始  -->
  <servlet>
    <servlet-name>SpringMvc</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
    	<param-name>contextConfigLocation</param-name>
    	<param-value>classpath*:com/yw/conf/springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
  	<servlet-name>SpringMvc</servlet-name>
  	<url-pattern>*.do</url-pattern>
  </servlet-mapping>
  <!-- springmvc的配置  结束 -->
  
  <!-- 字符的过滤器 -->
  <filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>

  

④ 创建包的结构了:

⑤创建一个base类dao了, 代码如下:

package com.yw.dao;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.Types;
import java.util.List;

import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

/**
 * 有一个规则哦 ,所有model 的字段属性 id这个属性必须放在第一位,
 * 因为了后来数组拷贝用的
 * @author yw
 *
 * @param <T>
 * @param <Tb>
 */
public class BaseDao<T,Tb> {
	
	public static final String SQL_INSERT="insert";
	public static final String SQL_UPDATE="update";
	public static final String SQL_DELETE="delete";
	
    private Class<T> entityClass;
	private Class<Tb> pClass;
	protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;
	protected JdbcTemplate jdbcTemplate;

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}
	 
	public BaseDao(){
		ParameterizedType type=(ParameterizedType) getClass().getGenericSuperclass();
		entityClass=(Class<T>) type.getActualTypeArguments()[0];
	    ParameterizedType  typep=(ParameterizedType) getClass().getGenericSuperclass();
	    pClass=(Class<Tb>) typep.getActualTypeArguments()[0];
	}
	//封装一下简单的组装sql语句,就是常用的哦
    public String SQl(String sqlFla){
		StringBuffer sb=new StringBuffer();
		//获取改bean所有的字段
		Field[] field=entityClass.getDeclaredFields();
		if(SQL_INSERT.equals(sqlFla)){
			sb.append("INSERT INTO ").append(entityClass.getSimpleName())
			.append(" (");
			for(int i=0;i<field.length;i++){
				field[i].setAccessible(true);//暴露反射
				sb.append(field[i].getName()).append(",");
			}
			sb.deleteCharAt(sb.length()-1);
			sb.append(" ) ").append("VALUES (");
			for(int i=0;i<field.length;i++){
				sb.append("?,");
			}
			sb.deleteCharAt(sb.length()-1);
			sb.append(" ) ");
		}
		else if(SQL_UPDATE.equals(sqlFla)){
			sb.append("UPDATE ").append(entityClass.getSimpleName()+" SET ");
			for(int i=0;i<field.length;i++){
				field[i].setAccessible(true);
				if(field[i].getName().equalsIgnoreCase("id")){
					continue;
				}
				sb.append(field[i].getName()).append(" = ").append("?,");
			}
			sb.deleteCharAt(sb.length()-1);
			sb.append(" WHERE id=?");
		}
		else if(SQL_DELETE.equals(sqlFla)){
			sb.append("DELETE FROM ").append(entityClass.getSimpleName());
			sb.append(" WHERE id=?");
		}
    	return sb.toString();
    }
    //设置值
    private Object[] setArgs(T entity,String sqlFla){
 		Field[] fields=entityClass.getDeclaredFields();
 		if(SQL_INSERT.equals(sqlFla)){
 			Object []obj=new Object[fields.length];
 			for (int i = 0; i < obj.length; i++) {
 				fields[i].setAccessible(true);
 				try {
					obj[i]=fields[i].get(entity);
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
			}
 			return obj;
 		}
 		else if(SQL_UPDATE.equals(sqlFla)){
 			Object []obj=new Object[fields.length];
 			int id=0;
 			for (int i = 0; i < obj.length; i++) {
 				fields[i].setAccessible(true);
 				try {
					obj[i]=fields[i].get(entity);
				} catch (IllegalArgumentException | IllegalAccessException e) {
					e.printStackTrace();
				}
			}
 			Object []objArr=new Object[fields.length];
 		    System.arraycopy(obj, 1, objArr, 0, fields.length-1);
 		    objArr[obj.length - 1]=obj[0];
 		    return objArr;
 		}else if(SQL_DELETE.equals("delete")){
 			Object[] obj=new  Object[1];
 			fields[0].setAccessible(true);
 			try {
				obj[0]=fields[0].get(entity);
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
 			return obj;
 		}
 		return null;
 	}
    //设置值对应的类型
 	private  int [] setArgsTypes(T entity,String sqlFlag){
 		 Field[] fields = entityClass.getDeclaredFields();  
         if (sqlFlag.equals(SQL_INSERT)) {  
             int[] argTypes = new int[fields.length];  
             try {  
                 for (int i = 0; argTypes != null && i < argTypes.length; i++) {  
                     fields[i].setAccessible(true); // 暴力反射  
                     if (fields[i].get(entity).getClass().getName().equals("java.lang.String")) {  
                         argTypes[i] = Types.VARCHAR;  
                     } else if (fields[i].get(entity).getClass().getName().equals("java.lang.Double")) {  
                         argTypes[i] = Types.DECIMAL;  
                     } else if (fields[i].get(entity).getClass().getName().equals("java.lang.Integer")) {  
                         argTypes[i] = Types.INTEGER;  
                     } else if (fields[i].get(entity).getClass().getName().equals("java.util.Date")) {  
                         argTypes[i] = Types.DATE;  
                     }  else if (fields[i].get(entity).getClass().getName().equals("java.sql.Timestamp")) {  
                         argTypes[i] = Types.TIMESTAMP;
                     } else if (fields[i].get(entity).getClass().getName().equals("java.math.BigDecimal")) {  
                         argTypes[i] = Types.DECIMAL;
                     }
                 }  
             } catch (Exception e) {  
                 e.printStackTrace();  
             }  
             return argTypes;  
         } else if (sqlFlag.equals(SQL_UPDATE)) {  
             int[] tempArgTypes = new int[fields.length];  
             int[] argTypes = new int[fields.length];  
             try {  
                 for (int i = 0; tempArgTypes != null && i < tempArgTypes.length; i++) {  
                     fields[i].setAccessible(true); // 暴力反射  
                     if (fields[i].get(entity).getClass().getName().equals("java.lang.String")) {  
                         tempArgTypes[i] = Types.VARCHAR;  
                     } else if (fields[i].get(entity).getClass().getName().equals("java.lang.Double")) {  
                         tempArgTypes[i] = Types.DECIMAL;  
                     } else if (fields[i].get(entity).getClass().getName().equals("java.lang.Integer")) {  
                         tempArgTypes[i] = Types.INTEGER;  
                     } else if (fields[i].get(entity).getClass().getName().equals("java.util.Date")) {  
                         tempArgTypes[i] = Types.DATE;  
                     } else if (fields[i].get(entity).getClass().getName().equals("java.sql.Timestamp")) {  
                     	tempArgTypes[i] = Types.TIMESTAMP;
                     } else if (fields[i].get(entity).getClass().getName().equals("java.math.BigDecimal")) {  
                     	tempArgTypes[i] = Types.DECIMAL;
                     }
                 }  
                 System.arraycopy(tempArgTypes, 1, argTypes, 0, tempArgTypes.length - 1); // 数组拷贝  
                 argTypes[argTypes.length - 1] = tempArgTypes[0];  
   
             } catch (Exception e) {  
                 e.printStackTrace();  
             }  
             return argTypes;  
   
         } else if (sqlFlag.equals(SQL_DELETE)) {  
             int[] argTypes = new int[1]; // 长度是1  
             try {  
                 fields[0].setAccessible(true); // 暴力反射  
                 if (fields[0].get(entity).getClass().getName().equals("java.lang.String")) {  
                     argTypes[0] = Types.VARCHAR;  
                 } else if (fields[0].get(entity).getClass().getName().equals("java.lang.Integer")) {  
                     argTypes[0] = Types.INTEGER;  
                 }  
   
             } catch (Exception e) {  
                 e.printStackTrace();  
             }  
             return argTypes;  
         }  
         return null;  
 	}
	
    public void save(T entity){
    	String sql=this.SQl(SQL_INSERT);
    	Object [] obj=this.setArgs(entity, SQL_INSERT);
    	System.out.println(sql);
    	for (int i = 0; i < obj.length; i++) {
    		System.out.println("--------------------");
			System.out.println(obj[i]);
			System.out.println("--------------------");
		}
    	int [] objTypes=this.setArgsTypes(entity, SQL_INSERT);
        jdbcTemplate.update(sql, obj,objTypes);
    }	
    public void upate(T entity){
    	String sql=this.SQl(SQL_UPDATE);
    	Object [] obj=this.setArgs(entity, SQL_UPDATE);
    	int [] objTypes=this.setArgsTypes(entity, SQL_UPDATE);
        jdbcTemplate.update(sql, obj, objTypes);
    }  
    public void delete(T entity){
    	String sql=this.SQl(SQL_DELETE);
    	Object [] obj=this.setArgs(entity, SQL_DELETE);
    	int [] objTypes=this.setArgsTypes(entity, SQL_DELETE);
        jdbcTemplate.update(sql, obj, objTypes);
    }    
    public List<T> findAll(){
    	String sql="SELECT * FROM "+entityClass.getSimpleName();
    	RowMapper<T> rowMapper=BeanPropertyRowMapper.newInstance(entityClass); 
    	return jdbcTemplate.query(sql, rowMapper);
    } 
    public T findById(Serializable id){
    	String sql="SELECt * FROM  "+entityClass.getSimpleName()+"  where id=?";
    	RowMapper<T> rowMapper=BeanPropertyRowMapper.newInstance(entityClass);
    	if(jdbcTemplate.query(sql, rowMapper, id).size()>0)
    		return jdbcTemplate.query(sql, rowMapper, id).get(0);
		return null;
    }  
}

  ⑥ 写一个Uerdao集成baseDao,代码如下

package com.yw.dao;

import com.yw.Dto.UserDto;
import com.yw.model.User;

public class UserDao extends BaseDao<User, UserDto> {	
}

  就是这样就行了,想增加一个sql语句就这样慢慢一个添加就的了

⑦ model和dto如下:

package com.yw.model;

public class User {
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", pass=" + pass + "]";
	}

	private Integer id;
	
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPass() {
		return pass;
	}

	public void setPass(String pass) {
		this.pass = pass;
	}
	private String name;
	private String pass;
}
/---------------------/
package com.yw.Dto;

public class UserDto {
private int id;
	
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPass() {
		return pass;
	}

	public void setPass(String pass) {
		this.pass = pass;
	}

	private String name;
	
	private String pass;
}

  ⑧ service层创建 一个Userservice,代码如下:

package com.yw.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yw.dao.UserDao;
import com.yw.model.User;

@Service("userService")
public class UserService {
    @Autowired
	private UserDao  userDao;    
    public void  save(User user){
    	userDao.save(user);	
    }    
    public void delete(User user){
    	userDao.delete(user);
    }   
    public void update(User user){
    	userDao.upate(user);
    }
    public User findById(int id){
    	return userDao.findById(id);
    }
    public void findAll(){
    	
    	List<User> user=userDao.findAll();
    	System.out.println(user);
    }
} 

  ⑨ 就是Contrlloer层了 创建一个userController

package com.yw.Contrlloer;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.yw.model.User;
import com.yw.service.UserService;

@Controller
@RequestMapping("/test/controller")
public class UserController {
	@Autowired
	private UserService userService;
	
   @RequestMapping("/test.do")
	public void test(HttpServletRequest reServletRequest,HttpServletResponse response) throws IOException{
		 response.getWriter().println("23456789-");
		 //查询所有的用户
		 userService.findAll();
		 //查询id为2的用户
		 User user=userService.findById(2);
		 //增加一个用户
		 User user2=new User();
		 user2.setId(0); //增加数据的是数据库的id为在自增的,所以在这里就写死了
		 user2.setName("夏明");
		 user2.setPass("12345678");
		 userService.save(user2);
		 //删除一个用户
		 userService.delete(user);
		 //更新一个用户,更新之前最好是查询一次在更新
		 User user3=userService.findById(2);
		 user3.setName("GaVien");
		 userService.update(user3);
		 
	}
}

  

好了到这里算是真正完成了,直接跑起来O了,项目就这样就结束。
笔者说说在遇到问题和注意事项以及心得吧:
(1)笔者老是在配置spring配置出错的,老是报bean创建失败,出现这个问题 第一个可能是 扫描包可能没有扫到
第二可能是bean的配置的class的包的路径不对
第三可能是你的jdk编译有问题,如是:自己百度一下,更换一下jdk吧
第四可能是你没有添加bean吧
(2)创建model的时候有id的必须在所有字段的属性前面,为后来的baseDao的数据拷贝方便呢
(3)经过笔者的测试 ,自己的写反射运行和数据库响应时间并没有比mybatis和hibernate慢甚至还快呢呢,而且自己写的反射所有sql语句都可以自己去控制,没有任何多余的数据呢,
(4)对于宇宙无敌的spring框架不熟,那你就只能自己去补了,反射也是咯 哈哈

最后项目下载路径 http://pan.baidu.com/s/1c2mMHiS

 

以上是关于利用反射搭建项目的dao层,从此可以告别被人的dao层框架了(spring+反射)的主要内容,如果未能解决你的问题,请参考以下文章

JRebel热部署,从此告别一遍一遍重启项目

springboot整合knife4j,从此告别手写接口文档

反射实现增删改查(DAO层)——修改数据

反射实现增删改查(DAO层)——插入数据

告别 LuaGoWasm 插件,是时候用低代码 API 网关了

反射实现增删改查(DAO层)——删除数据