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.* ...
随机推荐
- oracle之spool详细使用总结
今天实际项目中用到了spool,发现网上好多内容不是很全,自己摸索了好半天,现在总结一下. 一.通过spool 命令,可以将select 数据库的内容写到文件中,通过在sqlplus设置一些参数,使得 ...
- 如何将SQL Server运行到Windows Azure上
从2012年6月6日开始,Windows Azure上一些强大的新功能现在可用于预览,包括新的Windows Azure虚拟机(VM).其中有关Windows Azure虚拟机最强大的一件事是他们利用 ...
- CSS書寫規範及CSS Hack
基本原则: CSS样式可细分为3类:自定义样式.重新定义HTML样式.链接状态样式. 样式为设计师自定义的新 CSS 样式,影响被使用本样式的区域,用于完成网页中局部的样式设定. 样式名 “.”+“相 ...
- POJ-3017 Cut the Sequence DP+单调队列+堆
题目链接:http://poj.org/problem?id=3017 这题的DP方程是容易想到的,f[i]=Min{ f[j]+Max(num[j+1],num[j+2],......,num[i] ...
- VPS选购及辨别vps虚拟化技术
现在国内外的VPS(Virtual Private Server)服务商非常多,每个服务商使用的VPS架构都不同.VPS属于虚拟化服务器,中文名:虚拟专用服务器. 常见的VPS虚拟化架构有多种:Ope ...
- Spring源码入门——DefaultBeanNameGenerator解析
我们知道在spring中每个bean都要有一个id或者name标示每个唯一的bean,在xml中定义一个bean可以指定其id和name值,但那些没有指定的,或者注解的spring的beanname怎 ...
- JS好的学习网站
1.JavaScript 秘密花园 2.W3CSchool 3.js严格模式 4.js核心之原型 5.尼古拉斯怎么面试前端工程师 6.zepto中文版api 7.jquery API
- PowerDesigner实用技巧小结(2)
PowerDesigner实用技巧小结 1.ORACLE数据库建模时,由于ORACLE的表名.字段名如果是小写会有一定的麻烦,需要将小写转化为大写? (1)在打开pdm的情况下,进入Tools-Mod ...
- cookie机制
Cookie通过在客户端记录信息确定用户身份 一个用户的所有请求操作都应该属于同一个会话, HTTP协议是无状态的协议.一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接. ...
- 数字信号处理与音频处理(使用Audition)
前一阵子由于考博学习须要,看了<数字信号处理>,之前一直不清除这门课的理论在哪里应用比較广泛. 这次正巧用Audition处理了一段音频,猛然发现<数字信号处理>这门课还是很实 ...