java 利用注解实现BaseDao 增删查改
第一步,编写两个注解类,用于表明实体类对应的表名及字段。
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 增删查改的更多相关文章
- 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性
基于.net的分布式系统限流组件 在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...
- DataGridView绑定泛型List时,利用BindingList来实现增删查改
DataGridView绑定泛型List时,利用BindingList来实现增删查改 一. DataGridView绑定泛型List的种种 1.DataGridView数据绑定对比(DataTa ...
- HDFS Java Client对hdfs文件增删查改
step1:增加依赖 pom.xml ... <!-- https://mvnrepository.com/artifact/org.apache.hadoop ...
- Java实现单链表的增删查改及逆置打印
//所提供的接口 LinkList.java package Struct; public interface LinkList {//判断链表为空public boolean linkListIsE ...
- C# DataGridView绑定List对象时,利用BindingList来实现增删查改
当DataGridView的DataSource是DataTable的时候,DataTable的数据改变时,DataGridView的数据会随之改变,无需重新绑定到DataGridView. 当Da ...
- SpringBoot与Jpa自定义增删查改
一.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...
- 后端Spring Boot+前端Android交互+MySQL增删查改(Java+Kotlin实现)
1 前言&概述 这篇文章是基于这篇文章的更新,主要是更新了一些技术栈以及开发工具的版本,还有修复了一些Bug. 本文是SpringBoot+Android+MySQL的增删查改的简单实现,用到 ...
- 利用dbutils工具实现数据的增删查改操作(dbutis入门)
一.前期准备 1.安装数据库(如:mysql5.5) 2.安装Eclipse(如:3.4) 3.下载数据库驱动包 4.下载dbutis工具包 5.在Eclipse创建名为 dbutils 的工程并在工 ...
- java中CRUD(增删查改)底层代码的实现
java中CRUD(增删查改)底层代码的实现: package com.station.dao; import com.station.model.Product; import java.sql.* ...
随机推荐
- bzoj 1877 [SDOI2009]晨跑(最小费用最大流)
Description Elaxia最近迷恋上了空手道,他为自己设定了一套健身计划,比如俯卧撑.仰卧起坐等 等,不过到目前为止,他坚持下来的只有晨跑. 现在给出一张学校附近的地图,这张地图中包含N个十 ...
- CodeForces 362B Petya and Staircases
题意:一个小男孩要上楼梯,他一次可以走1个台阶或2个台阶或3个台阶,但是有一些台阶是脏的,他不想走在脏台阶上.一共有n个台阶和m个脏台阶,他最开始在第1个台阶上,要走到第n个台阶.问小男孩能不能不踩到 ...
- Windows Azure 的虚拟硬盘和文件的相关概念
虚拟硬盘和文件 在 Windows Azure 外部,虚拟硬盘可使用 VHD 或 VHDX 格式.它们还可以是固定的.动态扩展或差异的.Windows Azure 支持 VHD 格式的固定磁盘.固定格 ...
- grep环境变量常用配置
vim ~/.bashrc GREP_OPTIONS="-irns --exclude-dir=output --exclude=tags --exclude=*.files" 然 ...
- 【解决】python2.x版本的Django下admin管理页面css无效
折腾一下午,终于解决了这个问题,有必要记录一下,我就奇怪了为什么实验室电脑没问题,到宿舍就挂掉了,哼 主要是改mimetypes文件,位于D:\MySoftware\Python27\Lib下 1.添 ...
- map的基本操作函数及含义
map的基本操作函数: C++ Maps是一种关联式容器,包含“关键字/值”对 begin() 返回指向map头部的迭代器 clear() ...
- JavaScript----this陷阱的最全收集
原文翻译: JavaScript来自一门健全的语言,所以你可能觉得JavaScript中的this和其他面向对象的语言如java的this一样,是指存储在实例属性中的值.事实并非如此,在JavaScr ...
- 如何给Windows添加自动启动的程序
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:如何给Windows添加自动启动的程序.
- servlet三大作用域:request,session,application
javaweb开发中Servlet三大域对象的应用(request.session.application(ServletContext)). 1. request request是表示一个请求,只要 ...
- java中用线程解决进出水问题
//进水 class Inflow implements Runnable{ //水对象 Water wat; public Inflow(Water w){ this.wat = w; } @Ove ...