第一步,编写两个注解类,用于表明实体类对应的表名及字段。

TableInfo.java    此注解用于标注表名及主键名
import static java.lang.annotation.ElementType.TYPE;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* TableName对应表名称
* PrimaryKey对应主键字段名
*/
@Target({TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TableInfo { public String TableName();
public String PrimaryKey(); }
ColumnInfo.java  此注解用于标注实体类字段对应表字段
import static java.lang.annotation.ElementType.FIELD;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/*
* 用于标识表字段名
*/
@Target({FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface ColumnInfo {
String columnName();
}

第二步:编写一个实体类,并注明好注解

 import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Date; import annotation.ColumnInfo;
import annotation.TableInfo; /*
*
*/
@TableInfo(TableName = "student", PrimaryKey = "id")
public class Student {
@ColumnInfo(columnName="id")
private int sid;
@ColumnInfo(columnName="sname")
private String sname;
@ColumnInfo(columnName="sclass")
private int sclass;
@ColumnInfo(columnName="startdate")
private Date startdate;
@ColumnInfo(columnName="stopdate")
private Date stopdate; public Date getStopdate() {
return stopdate;
}
public void setStopdate(Date stopdate) {
this.stopdate = stopdate;
}
public Date getStartdate() {
return startdate;
}
public void setStartdate(Date startdate) {
this.startdate = startdate;
} public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public int getSclass() {
return sclass;
}
public void setSclass(int sclass) {
this.sclass = sclass;
}
@Override
public String toString() {
return "Student [id=" + sid + ", sname=" + sname + ", sclass=" + sclass
+ ", startdate=" + startdate + ", stopdate=" + stopdate + "]\n";
}
}

第三部:编写BaseDao.java(对数据库的操作基于c3p0组件)

 import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List; import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.BeanHandler; import annotation.ColumnInfo;
import annotation.TableInfo; import fnz.utils.JdbcUtil2; public class BaseDao<T> { private Class clazz; //类的字节码文件
private String tableName;//表明
private String primaryKey;//主键
private Field[] fields;//所有的字段
public BaseDao(){
Type type = this.getClass().getGenericSuperclass();//当前运行类的父类,即为“BaseDao<实体类>”,其实就是“参数化类型”ParameterizedType
ParameterizedType pt = (ParameterizedType)type;// 强制转换为“参数化类型” BaseDao<实体类>
Type types[] = pt.getActualTypeArguments(); // 获取“参数化类型”中的实体类
clazz = (Class)types[0];
//tableName = clazz.getSimpleName();//获取类名(不带包名)
TableInfo tab = (TableInfo)clazz.getAnnotation(TableInfo.class);
tableName = tab.TableName();
primaryKey = tab.PrimaryKey();
fields = clazz.getDeclaredFields();
} /**
* 主键查询
* @param id 主键值
* @return 返回封装后的对象
* @throws SQLException
*/
public T getOne(Object id){
try {
return JdbcUtil2.getQueryRunner().query("select * from "+tableName+" where "+ primaryKey+" = ?", new MBeanHandler<T>(clazz,mMethod.SELECT),id);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
} /**
* 查询全部
* @return 返回所有记录,封装成List<T>
* @throws SQLException
*/
public List<T> getAll(){
try {
return JdbcUtil2.getQueryRunner().query("select * from "+tableName, new MBeanListHandler<T>(clazz));
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 保存
* @param t 要保存的实体对象
* @return 保存后的对象
*/
public T baseSave(T t){
try{
List<Object> params = new ArrayList<Object>();
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);//强制是有字段也可以访问
params.add(fields[i].get(t));
}
//sql拼接
StringBuilder sql = new StringBuilder();
sql.append("insert into "+tableName+"(");
for (int j = 0; j < fields.length; j++) {
String fieldName = fields[j].getAnnotation(ColumnInfo.class).columnName();//获取表字段名
if(j == fields.length-1){
sql.append(fieldName+")");
}else{
sql.append(fieldName+",");
}
}
sql.append(" values(");
for (int k = 0; k < fields.length; k++) {
if(k == fields.length-1){
sql.append("?)");
}else{
sql.append("?,");
}
} JdbcUtil2.getQueryRunner().insert(sql.toString()
,new MBeanHandler<T>(clazz,mMethod.INSERT)
,params.toArray());
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return t;
} /**
* 执行更新
* @param t 更新对象
* @return
*/
public T baseUpdate(T t){
try{
List<Object> params = new ArrayList<Object>();
Object idParam = null;
for (int i = 0; i < fields.length; i++) {
fields[i].setAccessible(true);//强制是有字段也可以访问
if(!primaryKey.equals(fields[i].getAnnotation(ColumnInfo.class).columnName())){
params.add(fields[i].get(t));
}else{
idParam = fields[i].get(t);
}
}
params.add(idParam);//id为最后一个参数
//sql拼接
StringBuilder sql = new StringBuilder();
sql.append("update "+tableName+" set");
String strWhere = "";
for (int j = 0; j < fields.length; j++) {
String fieldName = fields[j].getAnnotation(ColumnInfo.class).columnName();//获取表字段名
if(!fieldName.equals(primaryKey)){
sql.append(" "+fieldName+"=?,");
}else if(fieldName.equals(primaryKey)){
strWhere = " where "+primaryKey+"=?";
}
}
int idx = sql.lastIndexOf(",");
sql = sql.replace(idx, idx+1, "");
sql.append(strWhere); JdbcUtil2.getQueryRunner().update(sql.toString(),params.toArray());
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return t;
} /**
* 根据主键删除
* @param id 主键id
* @return
*/
public Boolean baseDelete(Object id){
try{
JdbcUtil2.getQueryRunner().update("delete from "+tableName+" where "+primaryKey+"=?",id);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return true;
} } enum mMethod{
SELECT,
INSERT,
UPDATE
}
/**
* 自定义结果集:封装单个Bean对象
* @author fnz
*
* @param <T>
*/
class MBeanHandler<T> implements ResultSetHandler<T>{
private mMethod method;
private Class<T> clazz;
public MBeanHandler(Class<T> clazz,mMethod method){
this.clazz = clazz;
this.method = method;
} public T handle(ResultSet rs) throws SQLException {
try {
if(this.method == mMethod.SELECT){
if(rs.next()){
T tobj = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();//获取到所有的
for (Field field : fields) {
ColumnInfo col = field.getAnnotation(ColumnInfo.class);//获取实体类字段上的注解ColumnInfo
String colName = col.columnName();//得到 实体类字段 对应 表的字段名
//获取表字段的值
rs.findColumn(colName);
Object value = rs.getObject(colName);
//封装对象
field.setAccessible(true);
field.set(tobj, value);
}
return tobj;
}
}else{
return null;
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return null;
}
}
/**
* 自定义结果集:封装多个Bean对象
* @author fnz
*
* @param <T>
*/
class MBeanListHandler<T> implements ResultSetHandler<List<T>>{
// 保存传入的要封装的类的字节码
private Class<T> clazz;
public MBeanListHandler(Class<T> clazz) {
this.clazz = clazz;
}
// 封装结果集的方法
public List<T> handle(ResultSet rs) throws SQLException {
try {
List<T> list = new ArrayList<T>();
// 向下读一行
while(rs.next()){
T tobj = clazz.newInstance();
Field[] fields = clazz.getDeclaredFields();//获取到所有的
for (Field field : fields) {
ColumnInfo col = field.getAnnotation(ColumnInfo.class);//获取实体类字段上的注解ColumnInfo
String colName = col.columnName();//得到 实体类字段 对应 表的字段名
//获取表字段的值
Object value = rs.getObject(colName);
//封装对象
field.setAccessible(true);
field.set(tobj, value);
}
list.add(tobj);
}
return list;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

C3P0配置文件

<c3p0-config>
<!-- 默认加载配置 -->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test01</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">10</property>
</default-config>
<!-- 指定名称加载配置 -->
<named-config name="C3P0TestName">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test01</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">10</property>
</named-config> </c3p0-config>

JdbcUtil2.java(上面的BaseDao.java用到的工具类)

 import java.sql.Connection;
import org.apache.commons.dbutils.QueryRunner; import com.mchange.v2.c3p0.ComboPooledDataSource; public class JdbcUtil2 {
private static ComboPooledDataSource dataSource = null;
static{
//初始化操作
// 自动加载src目录下c3p0的配置文件【c3p0-config.xml】
dataSource = new ComboPooledDataSource();// 使用默认的配置
//使用c3p0-config.xml配置文件中named-config的name属性为C3P0TestName的配置
//dataSource = new ComboPooledDataSource("C3P0TestName");
} //获取QueryRunner对象
public static QueryRunner getQueryRunner(){
return new QueryRunner(dataSource);
}
//获取连接 通过c3p0核心类对象获取(此例子没用到该方法)
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}

最后:简单编写一下测试类

StudentDao继承BaseDao

   @Test
public void test6(){
StudentDao dao = new StudentDao();
Student s = dao.getOne(1);
System.out.println(s);
}

输出结果:Student [id=1, sname=张三, sclass=1, startdate=2016-09-22 00:00:00.0, stopdate=2016-09-23]

over

java 利用注解实现BaseDao 增删查改的更多相关文章

  1. 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性

    基于.net的分布式系统限流组件   在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...

  2. DataGridView绑定泛型List时,利用BindingList来实现增删查改

    DataGridView绑定泛型List时,利用BindingList来实现增删查改  一.   DataGridView绑定泛型List的种种 1.DataGridView数据绑定对比(DataTa ...

  3. HDFS Java Client对hdfs文件增删查改

      step1:增加依赖 pom.xml           ...      <!-- https://mvnrepository.com/artifact/org.apache.hadoop ...

  4. Java实现单链表的增删查改及逆置打印

    //所提供的接口 LinkList.java package Struct; public interface LinkList {//判断链表为空public boolean linkListIsE ...

  5. C# DataGridView绑定List对象时,利用BindingList来实现增删查改

    当DataGridView的DataSource是DataTable的时候,DataTable的数据改变时,DataGridView的数据会随之改变,无需重新绑定到DataGridView.  当Da ...

  6. SpringBoot与Jpa自定义增删查改

    一.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  7. 后端Spring Boot+前端Android交互+MySQL增删查改(Java+Kotlin实现)

    1 前言&概述 这篇文章是基于这篇文章的更新,主要是更新了一些技术栈以及开发工具的版本,还有修复了一些Bug. 本文是SpringBoot+Android+MySQL的增删查改的简单实现,用到 ...

  8. 利用dbutils工具实现数据的增删查改操作(dbutis入门)

    一.前期准备 1.安装数据库(如:mysql5.5) 2.安装Eclipse(如:3.4) 3.下载数据库驱动包 4.下载dbutis工具包 5.在Eclipse创建名为 dbutils 的工程并在工 ...

  9. java中CRUD(增删查改)底层代码的实现

    java中CRUD(增删查改)底层代码的实现: package com.station.dao; import com.station.model.Product; import java.sql.* ...

随机推荐

  1. linux的nohup命令的用法

    在应用Unix/Linux时,我们一般想让某个程序在后台运行,于是我们将常会用 & 在程序结尾来让程序自动运行.比如我们要运行mysql在后台: /usr/local/mysql/bin/my ...

  2. 【wuzhicms】apache 设置禁止访问某些文件或目录

    [apache配置禁止访问] 1. 禁止访问某些文件/目录 增加Files选项来控制,比如要不允许访问 .inc 扩展名的文件,保护php类库: <Files ~ "\.inc$&qu ...

  3. vijosP1289 老板娘的促销方案

    vijosP1289 老板娘的促销方案 链接:https://vijos.org/p/1289 [思路] 组合公式+高精度. 如果n-m<2则无解. 否则对于第一个询问:ans=C(n-m,2) ...

  4. 洛谷P1189 逃跑的拉尔夫(SEARCH)

    洛谷1189 SEARCH 题目描述 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置. 那个装置太旧了,以至于只能发射关于那辆车的 ...

  5. HDU2196 - Computer(树形DP)

    题目大意 给定一颗n个结点的树,编号为1~n,要求你求出每个结点能到达的最长路径 题解 用动态规划解决的~~~~把1 当成树根,这样就转换成有根树了.我们可以发现,对于每个结点的最长路,要么是从子树得 ...

  6. poj1873 The Fortified Forest 凸包+枚举 水题

    /* poj1873 The Fortified Forest 凸包+枚举 水题 用小树林的木头给小树林围一个围墙 每棵树都有价值 求消耗价值最低的做法,输出被砍伐的树的编号和剩余的木料 若砍伐价值相 ...

  7. oc学习之路----scrollView的代理模式

    右图是OC里面scrollView的代理的描述,从这里可以开出来,任何对象都可以作为scorllView的代理对象只要实现了UIScrollViewDelegate这个协议,为什么呢,原因要追究到UI ...

  8. sql语句相关整理

    select * from jcls_lawfirms where length(lf_2)=2 for updateselect * from jcls_lawfirms where length( ...

  9. 使用Mybatis-Generator自动生成Dao、Model、Mapping相关文件

    最近一直在学习SSM框架,今天遇到一个关于MyBatis生成的问题,记录一下. http://blog.csdn.net/zhshulin/article/details/37956105 我是根据这 ...

  10. .Net Framwork类库

    .NET Framework 类库是一个由类.接口和值类型组成的库,通过该库中的内容可访问系统功能.它是生成 .NET Framework 应用程序.组件和控件的基础.类库中的命名空间和命名空间类别在 ...