zoukankan      html  css  js  c++  java
  • 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(); 
    }

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

     1 import static java.lang.annotation.ElementType.CONSTRUCTOR;
     2 import static java.lang.annotation.ElementType.FIELD;
     3 import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
     4 import static java.lang.annotation.ElementType.METHOD;
     5 import static java.lang.annotation.ElementType.PARAMETER;
     6 import static java.lang.annotation.ElementType.TYPE;
     7 
     8 import java.lang.annotation.Retention;
     9 import java.lang.annotation.RetentionPolicy;
    10 import java.lang.annotation.Target;
    11 import java.util.Date;
    12 
    13 import annotation.ColumnInfo;
    14 import annotation.TableInfo;
    15 
    16 
    17 /*
    18  * 
    19  */
    20 @TableInfo(TableName = "student", PrimaryKey = "id")
    21 public class Student {
    22     @ColumnInfo(columnName="id")
    23     private int sid;
    24     @ColumnInfo(columnName="sname")
    25     private String sname;
    26     @ColumnInfo(columnName="sclass")
    27     private int sclass;
    28     @ColumnInfo(columnName="startdate")
    29     private Date startdate;
    30     @ColumnInfo(columnName="stopdate")
    31     private Date stopdate;
    32     
    33     public Date getStopdate() {
    34         return stopdate;
    35     }
    36     public void setStopdate(Date stopdate) {
    37         this.stopdate = stopdate;
    38     }
    39     public Date getStartdate() {
    40         return startdate;
    41     }
    42     public void setStartdate(Date startdate) {
    43         this.startdate = startdate;
    44     }
    45     
    46     public int getSid() {
    47         return sid;
    48     }
    49     public void setSid(int sid) {
    50         this.sid = sid;
    51     }
    52     public String getSname() {
    53         return sname;
    54     }
    55     public void setSname(String sname) {
    56         this.sname = sname;
    57     }
    58     public int getSclass() {
    59         return sclass;
    60     }
    61     public void setSclass(int sclass) {
    62         this.sclass = sclass;
    63     }
    64     @Override
    65     public String toString() {
    66         return "Student [id=" + sid + ", sname=" + sname + ", sclass=" + sclass
    67                 + ", startdate=" + startdate + ", stopdate=" + stopdate + "]
    ";
    68     }
    69 }

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

      1 import java.lang.reflect.Field;
      2 import java.lang.reflect.ParameterizedType;
      3 import java.lang.reflect.Type;
      4 import java.sql.ResultSet;
      5 import java.sql.SQLException;
      6 import java.util.ArrayList;
      7 import java.util.List;
      8 
      9 import org.apache.commons.dbutils.ResultSetHandler;
     10 import org.apache.commons.dbutils.handlers.BeanHandler;
     11 
     12 import annotation.ColumnInfo;
     13 import annotation.TableInfo;
     14 
     15 import fnz.utils.JdbcUtil2;
     16 
     17 public class BaseDao<T> {
     18     
     19     private Class clazz; //类的字节码文件
     20     private String tableName;//表明
     21     private String primaryKey;//主键
     22     private Field[] fields;//所有的字段
     23     public BaseDao(){
     24         Type type = this.getClass().getGenericSuperclass();//当前运行类的父类,即为“BaseDao<实体类>”,其实就是“参数化类型”ParameterizedType
     25         ParameterizedType pt = (ParameterizedType)type;// 强制转换为“参数化类型”  BaseDao<实体类>
     26         Type types[] = pt.getActualTypeArguments(); // 获取“参数化类型”中的实体类
     27         clazz = (Class)types[0];
     28         //tableName = clazz.getSimpleName();//获取类名(不带包名)
     29         TableInfo tab = (TableInfo)clazz.getAnnotation(TableInfo.class);
     30         tableName = tab.TableName();
     31         primaryKey = tab.PrimaryKey();
     32         fields = clazz.getDeclaredFields();
     33     }
     34     
     35     
     36     /**
     37      * 主键查询
     38      * @param id    主键值
     39      * @return      返回封装后的对象
     40      * @throws SQLException 
     41      */
     42     public T getOne(Object id){
     43         try {
     44             return JdbcUtil2.getQueryRunner().query("select * from "+tableName+" where "+ primaryKey+" = ?", new MBeanHandler<T>(clazz,mMethod.SELECT),id);
     45         } catch (SQLException e) {
     46             e.printStackTrace();
     47             throw new RuntimeException(e);
     48         }
     49     }
     50     
     51     /**
     52      * 查询全部
     53      * @return 返回所有记录,封装成List<T>
     54      * @throws SQLException 
     55      */
     56     public List<T> getAll(){
     57         try {
     58             return JdbcUtil2.getQueryRunner().query("select * from "+tableName, new MBeanListHandler<T>(clazz));
     59         } catch (SQLException e) {
     60             e.printStackTrace();
     61             throw new RuntimeException(e);
     62         }
     63     }
     64     /**
     65      * 保存
     66      * @param t 要保存的实体对象
     67      * @return 保存后的对象
     68      */
     69     public T baseSave(T t){
     70         try{
     71             List<Object> params = new ArrayList<Object>();
     72             for (int i = 0; i < fields.length; i++) {
     73                 fields[i].setAccessible(true);//强制是有字段也可以访问
     74                 params.add(fields[i].get(t));
     75             }
     76             //sql拼接
     77             StringBuilder sql = new StringBuilder();
     78             sql.append("insert into "+tableName+"(");
     79             for (int j = 0; j < fields.length; j++) {
     80                 String fieldName = fields[j].getAnnotation(ColumnInfo.class).columnName();//获取表字段名
     81                 if(j == fields.length-1){
     82                     sql.append(fieldName+")");
     83                 }else{
     84                     sql.append(fieldName+",");
     85                 }
     86             }
     87             sql.append(" values(");
     88             for (int k = 0; k < fields.length; k++) {
     89                 if(k == fields.length-1){
     90                     sql.append("?)");
     91                 }else{
     92                     sql.append("?,");
     93                 }
     94             }
     95             
     96             JdbcUtil2.getQueryRunner().insert(sql.toString()
     97                     ,new MBeanHandler<T>(clazz,mMethod.INSERT)
     98                     ,params.toArray());
     99         } catch (Exception e) {
    100             e.printStackTrace();
    101             throw new RuntimeException(e);
    102         }
    103         return t;
    104     }
    105     
    106     /**
    107      * 执行更新
    108      * @param t 更新对象
    109      * @return
    110      */
    111     public T baseUpdate(T t){
    112         try{
    113             List<Object> params = new ArrayList<Object>();
    114             Object idParam = null;
    115             for (int i = 0; i < fields.length; i++) {
    116                 fields[i].setAccessible(true);//强制是有字段也可以访问
    117                 if(!primaryKey.equals(fields[i].getAnnotation(ColumnInfo.class).columnName())){
    118                     params.add(fields[i].get(t));
    119                 }else{
    120                     idParam = fields[i].get(t);
    121                 }
    122             }
    123             params.add(idParam);//id为最后一个参数
    124             //sql拼接
    125             StringBuilder sql = new StringBuilder();
    126             sql.append("update "+tableName+" set");
    127             String strWhere = "";
    128             for (int j = 0; j < fields.length; j++) {
    129                 String fieldName = fields[j].getAnnotation(ColumnInfo.class).columnName();//获取表字段名
    130                 if(!fieldName.equals(primaryKey)){
    131                     sql.append(" "+fieldName+"=?,");
    132                 }else if(fieldName.equals(primaryKey)){
    133                     strWhere = " where "+primaryKey+"=?";
    134                 }
    135             }
    136             int idx = sql.lastIndexOf(",");
    137             sql = sql.replace(idx, idx+1, "");
    138             sql.append(strWhere);
    139             
    140             JdbcUtil2.getQueryRunner().update(sql.toString(),params.toArray());
    141         } catch (Exception e) {
    142             e.printStackTrace();
    143             throw new RuntimeException(e);
    144         }
    145         return t;
    146     }
    147     
    148     /**
    149      * 根据主键删除
    150      * @param id 主键id
    151      * @return
    152      */
    153     public Boolean baseDelete(Object id){
    154         try{
    155             JdbcUtil2.getQueryRunner().update("delete from "+tableName+" where "+primaryKey+"=?",id);
    156         } catch (Exception e) {
    157             e.printStackTrace();
    158             throw new RuntimeException(e);
    159         }
    160         return true;
    161     }
    162     
    163 }
    164 
    165 enum mMethod{
    166     SELECT,
    167     INSERT,
    168     UPDATE
    169 }
    170 /**
    171  * 自定义结果集:封装单个Bean对象
    172  * @author fnz
    173  *
    174  * @param <T>
    175  */
    176 class MBeanHandler<T> implements ResultSetHandler<T>{
    177     private mMethod method;
    178     private Class<T> clazz;
    179     public MBeanHandler(Class<T> clazz,mMethod method){
    180         this.clazz = clazz;
    181         this.method = method;
    182     }
    183     
    184     public T handle(ResultSet rs) throws SQLException {
    185         try {
    186             if(this.method == mMethod.SELECT){
    187                 if(rs.next()){
    188                     T tobj = clazz.newInstance();
    189                     Field[] fields = clazz.getDeclaredFields();//获取到所有的
    190                     for (Field field : fields) {
    191                         ColumnInfo col = field.getAnnotation(ColumnInfo.class);//获取实体类字段上的注解ColumnInfo
    192                         String colName = col.columnName();//得到 实体类字段 对应 表的字段名
    193                         //获取表字段的值
    194                         rs.findColumn(colName);
    195                         Object value = rs.getObject(colName);
    196                         //封装对象
    197                         field.setAccessible(true);
    198                         field.set(tobj, value);
    199                     }
    200                     return tobj;
    201                 }
    202             }else{
    203                 return null;
    204             }
    205         } catch (Exception e) {
    206             e.printStackTrace();
    207             throw new RuntimeException(e);
    208         }
    209         return null;
    210     }
    211 }
    212 /**
    213  * 自定义结果集:封装多个Bean对象
    214  * @author fnz
    215  *
    216  * @param <T>
    217  */
    218 class MBeanListHandler<T> implements ResultSetHandler<List<T>>{
    219     // 保存传入的要封装的类的字节码
    220     private Class<T> clazz;
    221     public MBeanListHandler(Class<T> clazz) {
    222         this.clazz = clazz;
    223     }
    224     // 封装结果集的方法
    225     public List<T> handle(ResultSet rs) throws SQLException {
    226         try {
    227             List<T> list = new ArrayList<T>();
    228             // 向下读一行
    229             while(rs.next()){
    230                 T tobj = clazz.newInstance();
    231                 Field[] fields = clazz.getDeclaredFields();//获取到所有的
    232                 for (Field field : fields) {
    233                     ColumnInfo col = field.getAnnotation(ColumnInfo.class);//获取实体类字段上的注解ColumnInfo
    234                     String colName = col.columnName();//得到 实体类字段 对应 表的字段名
    235                     //获取表字段的值
    236                     Object value = rs.getObject(colName);
    237                     //封装对象
    238                     field.setAccessible(true);
    239                     field.set(tobj, value);
    240                 }
    241                 list.add(tobj);
    242             }
    243             return list;
    244         } catch (Exception e) {
    245             throw new RuntimeException(e);
    246         }
    247     }
    248 }

    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用到的工具类)

     1 import java.sql.Connection;
     2 import org.apache.commons.dbutils.QueryRunner;
     3 
     4 import com.mchange.v2.c3p0.ComboPooledDataSource;
     5 
     6 
     7 public class JdbcUtil2 {
     8     private static ComboPooledDataSource dataSource = null;
     9     static{
    10         //初始化操作
    11         // 自动加载src目录下c3p0的配置文件【c3p0-config.xml】
    12         dataSource = new ComboPooledDataSource();// 使用默认的配置
    13         //使用c3p0-config.xml配置文件中named-config的name属性为C3P0TestName的配置
    14         //dataSource = new ComboPooledDataSource("C3P0TestName");
    15     }
    16     
    17     //获取QueryRunner对象
    18     public static QueryRunner getQueryRunner(){
    19         return new QueryRunner(dataSource);
    20     }
    21     //获取连接 通过c3p0核心类对象获取(此例子没用到该方法)
    22     public static Connection getConnection(){
    23         try {
    24             return dataSource.getConnection();
    25         } catch (Exception e) {
    26             e.printStackTrace();
    27             throw new RuntimeException(e);
    28         }
    29     }
    30 }

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

    StudentDao继承BaseDao

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

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

    over

  • 相关阅读:
    线段树 建树 单点修改 单点/区间查询
    JAVAEE学期总结
    Spring框架教程IDEA版-----更新中
    第一章操作系统引论-------批处理、分时、实时各个操作系统特点 进程与线程的区别
    读《阿法狗围棋系统的简要分析》
    matlab启动后的默认路径
    从长辈们的故事谈起
    在成为一名老司机的路上不要狂奔
    物理学与其它科学的关系
    读《现象级带货网红的自我修养》
  • 原文地址:https://www.cnblogs.com/fnz0/p/6108047.html
Copyright © 2011-2022 走看看