标签:
作为一名刚入手的小白程序猿,不但"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+反射)
标签:
原文地址:http://www.cnblogs.com/bt-gavin/p/5915964.html