java 注解定义及数据库封装

1.1) 定义注解  Column

@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.FIELD)
public @interface Column {
     /** 
     * 字段名称 
     */  
    String value();  
      
    /** 
     * 字段的类型 
     * @return 
     */  
    Class<?> type() default String.class;  
      
    /** 
     * 字段的长度 
     * @return 
     */  
    int length() default 0; 

}

1.2)定义注解  Entity

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) 
public @interface Entity {
    /** 
     * 表名 
     */  
    String value();
}

1.3)定义注解 Id

/** 
 * 标识数据库字段的ID 
 */  
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.FIELD)  
public @interface Id {      
        /** 
         * ID的名称 
         * @return 
         */  
        String value();  
}

 

2 接口的封装

2.1)

//数据库操作的接口,常用的增删改查,以及按照条件来查询
public interface GenericDAO<T> {
    
    public void save(T t) throws Exception;   //增加数据
    
    public void delete(Object id, Class<T> clazz) throws Exception;  //删除数据
    
    public void update(T t) throws Exception;   //更新数据
    
    public T get(Object id, Class<T> clazz) throws Exception;   //查找数据
    
    public List<T> findAllByConditions(Map<String, Object> sqlWhereMap, Class<T> clazz ) throws Exception;   //根据搜索条件,批量查询数据
}

 

2.2)

package com.zy.simpleORM;

import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.zy.annotation.Column;
import com.zy.annotation.Entity;
import com.zy.annotation.Id;
 
//数据库常用操作的实现
public class GenericDAOImpl<T> implements GenericDAO<T> {
    private static final String TABLE_ALIAS = "t";
    //添加数据:1.获取表名,2.获取字段、字段值,3.拼接sql语句,4.执行sql语句,5.释放资源
    //insert into t_book (t_isbn,t_name,t_author,t_publishing,t_pubdate,t_price) values (?,?,?,?,?,?)
    public void save(T t) throws Exception {
        // TODO Auto-generated method stub
        Class<?> clazz = t.getClass();
        //获取表名
        String tableName = getTableName(clazz);
        
        StringBuilder fieldNames = new StringBuilder();  //存储字段名字
        List<Object> fieldValues = new ArrayList<Object>(); //存储字段值
        StringBuilder placeholders = new StringBuilder();   //占位符
        //获取字段名字和值
        Field[] fields = clazz.getDeclaredFields();
        for(Field field:fields) {
            PropertyDescriptor pd = new PropertyDescriptor(field.getName(), t.getClass());
            if(field.isAnnotationPresent(Id.class)) {
                fieldNames.append(field.getAnnotation(Id.class).value()).append(",");
                fieldValues.add(pd.getReadMethod().invoke(t));
            } else if(field.isAnnotationPresent(Column.class)) {
                fieldNames.append(field.getAnnotation(Column.class).value()).append(",");
                fieldValues.add(pd.getReadMethod().invoke(t));
            }
            placeholders.append("?").append(",");
        }
        
        //删除最后一个逗号
        fieldNames.deleteCharAt(fieldNames.length()-1);
        placeholders.deleteCharAt(placeholders.length()-1);
        
        //拼接sql
        StringBuilder sql = new StringBuilder("");

        sql.append("insert into ").append(tableName).append(" (").append(fieldNames.toString())
        .append(") values (").append(placeholders).append(")");
        PreparedStatement ps = JdbcDaoHelper.getConnection().prepareStatement(sql.toString()); 
         //设置SQL参数占位符的值  
        setParameter(fieldValues, ps, false);  
        //执行sql语句
        ps.execute();
        JdbcDaoHelper.release(ps, null);
        
        System.out.println(sql+"\n"+clazz.getSimpleName()+"添加成功");
    }

    //删除数据
    //delete from t_book where id = 1
    public void delete(Object id, Class<T> clazz)  throws Exception {
        // TODO Auto-generated method stub
        //获取表名
        String tableName = getTableName(clazz);
    
        StringBuilder sql = new StringBuilder("");
        sql.append("delete from ").append(tableName).append(" where id = ").append(id);
        PreparedStatement ps = JdbcDaoHelper.getConnection().prepareStatement(sql.toString());
        ps.execute();
        JdbcDaoHelper.release(ps, null);
        System.out.println(sql+"\n"+clazz.getSimpleName()+"删除成功");

    }
    //根据id来进行更新数据
    //update t_book set t_name=?,t_author=?,t_publishing=?,t_pubdate=?,t_price=? where t_isbn=?
    public void update(T t) throws Exception {
        // TODO Auto-generated method stub
        Class<?> clazz = t.getClass();
        //获取表名
        String tableName = getTableName(clazz);
        

        List<String> fieldNames = new ArrayList<String>();  //存储字段名字
        List<Object> fieldValues = new ArrayList<Object>(); //存储字段值
        List<String> placeholders = new ArrayList<String>();   //占位符
        
        
        String idFieldName = "";  
        Object idFieldValue = "";
        //获取字段名字和值
        Field[] fields = clazz.getDeclaredFields();
        for(Field field:fields) {
            PropertyDescriptor pd = new PropertyDescriptor(field.getName(), t.getClass());
            if(field.isAnnotationPresent(Id.class)) {
                idFieldName = field.getAnnotation(Id.class).value();
                idFieldValue = pd.getReadMethod().invoke(t);
            } else if(field.isAnnotationPresent(Column.class)) {
                fieldNames.add(field.getAnnotation(Column.class).value());
                fieldValues.add(pd.getReadMethod().invoke(t));
                placeholders.add("?");
            }            
        }
        //ID作为更新条件,放在集合中的最后一个元素  
        fieldNames.add(idFieldName);  
        fieldValues.add(idFieldValue);  
        placeholders.add("?");  
        
        
        StringBuilder sql = new StringBuilder("");
        sql.append("update " ).append(tableName).append(" set ");
        int index = fieldNames.size()-1;
        for(int i=0; i<index; i++) {
            sql.append(fieldNames.get(i)).append("=").append(placeholders.get(i)).append(",");
        }
        sql.deleteCharAt(sql.length()-1).append(" where ").append(idFieldName).append("=").append("?");
        PreparedStatement ps = JdbcDaoHelper.getConnection().prepareStatement(sql.toString()); 
         //设置SQL参数占位符的值  
       setParameter(fieldValues, ps, false);  
       
       //执行sql语句
       ps.execute();
       JdbcDaoHelper.release(ps, null);
       System.out.println(sql+"\n"+clazz.getSimpleName()+"更新成功");
    }

    //select t.t_isbn as isbn,t.t_name as name,t.t_author as author,t.t_publishing as publishing,t.t_pubdate as pubdate,t.t_price as price from t_book t where t.t_isbn like ? 
    public T get(Object id, Class<T> clazz) throws Exception {
        // TODO Auto-generated method stub
    
        String idFieldName = "";  
        Field[] fields = clazz.getDeclaredFields();  
        boolean flag = false;  
        for (Field field : fields) {  
            if (field.isAnnotationPresent(Id.class)) {  
                idFieldName = field.getAnnotation(Id.class).value();  
                flag = true;  
                break;  
            }   
        }  
          
        if (!flag) {  
            throw new Exception(clazz.getName() + " object not found id property.");  
        }  
          
        //拼装SQL  
        Map<String,Object> sqlWhereMap = new HashMap<String, Object>();  
        sqlWhereMap.put(TABLE_ALIAS + "." + idFieldName, id);  
          
        List<T> list = findAllByConditions(sqlWhereMap, clazz); 
        
        return list.size() > 0 ? list.get(0) : null;
    }

    public List<T> findAllByConditions(Map<String, Object> sqlWhereMap, Class<T> clazz) throws Exception {
        // TODO Auto-generated method stub
        List<T> list = new ArrayList<T>();  
        String tableName = getTableName(clazz);  
        String idFieldName = "";  
        //存储所有字段的信息  
        //通过反射获得要查询的字段  
        StringBuffer fieldNames = new StringBuffer();  
        Field[] fields = clazz.getDeclaredFields();  
        for (Field field : fields) {  
            String propertyName = field.getName();  
            if (field.isAnnotationPresent(Id.class)) {  
                idFieldName = field.getAnnotation(Id.class).value();  
                fieldNames.append(TABLE_ALIAS + "." + idFieldName)  
                          .append(" as ").append(propertyName).append(",");  
            } else if (field.isAnnotationPresent(Column.class)) {  
                fieldNames.append(TABLE_ALIAS + "." + field.getAnnotation(Column.class).value())  
                          .append(" as ").append(propertyName).append(",");  
            }  
        }  
        fieldNames.deleteCharAt(fieldNames.length()-1);  
          
        //拼装SQL  
        String sql = "select " + fieldNames + " from " + tableName + " " + TABLE_ALIAS;  
        PreparedStatement ps = null;  
        List<Object> values = null;  
        if (sqlWhereMap != null) {  
            List<Object> sqlWhereWithValues = getSqlWhereWithValues(sqlWhereMap);  
            if (sqlWhereWithValues != null) {  
                //拼接SQL条件  
                String sqlWhere = (String)sqlWhereWithValues.get(0);  
                sql += sqlWhere;  
                //得到SQL条件中占位符的值  
                values = (List<Object>) sqlWhereWithValues.get(1);  
            }  
        }   
          
        //设置参数占位符的值  
        if (values != null) {  
            ps = JdbcDaoHelper.getConnection().prepareStatement(sql);  
            setParameter(values, ps, true);  
        } else {  
            ps = JdbcDaoHelper.getConnection().prepareStatement(sql);  
        }  
          
          
        //执行SQL  
        ResultSet rs = ps.executeQuery();  
        while(rs.next()) {  
            T t = clazz.newInstance();  
            initObject(t, fields, rs);  
            list.add(t);  
        }  
          
        //释放资源  
        JdbcDaoHelper.release(ps, rs);  
          
        System.out.println(sql);  
        return list;  
    }
    
    /** 
     * 获得表名 
     */  
    private String getTableName(Class<?> clazz) throws Exception {  
        if (clazz.isAnnotationPresent(Entity.class)) {  
            Entity entity = clazz.getAnnotation(Entity.class);  
            return entity.value();  
        } else {  
            throw new Exception(clazz.getName() + " is not Entity Annotation.");  
        }  
    }  
    
    /** 
     * 设置SQL参数占位符的值 
     */  
    private void setParameter(List<Object> values, PreparedStatement ps, boolean isSearch)  
            throws SQLException {  
        for (int i = 1; i <= values.size(); i++) {  
            Object fieldValue = values.get(i-1);  
            Class<?> clazzValue = fieldValue.getClass();  
            if (clazzValue == String.class) {  
                if (isSearch)   
                    ps.setString(i, "%" + (String)fieldValue + "%");  
                else  
                    ps.setString(i,(String)fieldValue);  
                      
            } else if (clazzValue == boolean.class || clazzValue == Boolean.class) {  
                ps.setBoolean(i, (Boolean)fieldValue);  
            } else if (clazzValue == byte.class || clazzValue == Byte.class) {  
                ps.setByte(i, (Byte)fieldValue);  
            } else if (clazzValue == char.class || clazzValue == Character.class) {  
                ps.setObject(i, fieldValue,Types.CHAR);  
            } else if (clazzValue == Date.class) {  
                ps.setTimestamp(i, new Timestamp(((Date) fieldValue).getTime()));  
            } else if (clazzValue.isArray()) {  
                Object[] arrayValue = (Object[]) fieldValue;  
                StringBuffer sb = new StringBuffer();  
                for (int j = 0; j < arrayValue.length; j++) {  
                    sb.append(arrayValue[j]).append("、");  
                }  
                ps.setString(i, sb.deleteCharAt(sb.length()-1).toString());  
            } else {  
                ps.setObject(i, fieldValue, Types.NUMERIC);  
            }  
        }  
    } 
    
    
    /** 
     * 根据结果集初始化对象 
     */  
    private void initObject(T t, Field[] fields, ResultSet rs)  
            throws SQLException, IntrospectionException,  
            IllegalAccessException, InvocationTargetException {  
        for (Field field : fields) {  
            String propertyName = field.getName();  
            Object paramVal = null;  
            Class<?> clazzField = field.getType();  
            if (clazzField == String.class) {  
                paramVal = rs.getString(propertyName);  
            } else if (clazzField == short.class || clazzField == Short.class) {  
                paramVal = rs.getShort(propertyName);  
            } else if (clazzField == int.class || clazzField == Integer.class) {  
                paramVal = rs.getInt(propertyName);  
            } else if (clazzField == long.class || clazzField == Long.class) {  
                paramVal = rs.getLong(propertyName);  
            } else if (clazzField == float.class || clazzField == Float.class) {  
                paramVal = rs.getFloat(propertyName);  
            } else if (clazzField == double.class || clazzField == Double.class) {  
                paramVal = rs.getDouble(propertyName);  
            } else if (clazzField == boolean.class || clazzField == Boolean.class) {  
                paramVal = rs.getBoolean(propertyName);  
            } else if (clazzField == byte.class || clazzField == Byte.class) {  
                paramVal = rs.getByte(propertyName);  
            } else if (clazzField == char.class || clazzField == Character.class) {  
                paramVal = rs.getCharacterStream(propertyName);  
            } else if (clazzField == Date.class) {  
                paramVal = rs.getDate(propertyName);
                //getTimestamp(propertyName);  
            } else if (clazzField.isArray()) {  
                paramVal = rs.getString(propertyName).split(",");   //以逗号分隔的字符串  
            }   
            PropertyDescriptor pd = new PropertyDescriptor(propertyName,t.getClass());  
            pd.getWriteMethod().invoke(t, paramVal);  
        }  
    }  
    
    
    /** 
     * 根据条件,返回sql条件和条件中占位符的值 
     * @param sqlWhereMap key:字段名 value:字段值 
     * @return 第一个元素为SQL条件,第二个元素为SQL条件中占位符的值 
     */  
    private List<Object> getSqlWhereWithValues(Map<String,Object> sqlWhereMap) {  
        if (sqlWhereMap.size() <1 ) return null;  
        List<Object> list = new ArrayList<Object>();  
        List<Object> fieldValues = new ArrayList<Object>();  
        StringBuffer sqlWhere = new StringBuffer(" where ");  
        Set<Entry<String, Object>> entrySets = sqlWhereMap.entrySet();  
        for (Iterator<Entry<String, Object>> iteraotr = entrySets.iterator();iteraotr.hasNext();) {  
            Entry<String, Object> entrySet = iteraotr.next();  
            fieldValues.add(entrySet.getValue());  
            Object value = entrySet.getValue();  
            if (value.getClass() == String.class) {  
                sqlWhere.append(entrySet.getKey()).append(" like ").append("?").append(" and ");  
            } else {  
                sqlWhere.append(entrySet.getKey()).append("=").append("?").append(" and ");  
            }  
        }  
        sqlWhere.delete(sqlWhere.lastIndexOf("and"), sqlWhere.length());  
        list.add(sqlWhere.toString());  
        list.add(fieldValues);  
        return list;  
    }  

    
}
 

3)封装类JdbcDaoHelper

package com.zy.simpleORM;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

public class JdbcDaoHelper {
    
    private static final String USER = "root"; //用户名
    private static final String PASSWORD = ""; //密码
    private static final String URL = "jdbc:mysql://localhost:3306/test";
    private static Connection con;
    
    private static Properties properties = null;
    
    static {
        properties = new Properties();    
        InputStream in = (InputStream) JdbcDaoHelper.class.getResourceAsStream("mysqlDB.properties");  
        
        try {  
            properties.load(in);  
        } catch (IOException ex) {    
            System.out.println(ex.getMessage());  
            ex.printStackTrace();  
        }
    }

    
    //获取数据库的连接,加载驱动,建立到数据库的连接
    public static Connection getConnection() {
        //将配置放在配置文件中        
        
        try {
            if(con == null) {
                Class.forName(properties.getProperty("DBDriver"));
                try {
                    con = DriverManager.getConnection(properties.getProperty("URL"), properties.getProperty("USERNAME"), properties.getProperty("PASSWORD"));
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } 
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return con;        
    }
        
    //释放数据库资源
    public static void release(PreparedStatement ps, ResultSet rs) {
        if(con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            con = null;
        }
        
        if( ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            ps = null;
        }
        
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            rs = null;
        }
    }

}
 

4)配置文件 mysqlDB.properties

 

DBDriver=com.mysql.jdbc.Driver
URL=jdbc\:mysql\://localhost\:3306/test
USERNAME=root
PASSWORD=

 

5)测试实体  Book

package com.zy.simpleORM;

import java.sql.Date;

import com.zy.annotation.Column;
import com.zy.annotation.Entity;
import com.zy.annotation.Id;

/** 
 * 图书 
 */  
@Entity("t_book")   //表名  
public class Book {  
  
    /** 
     * 图书编号 
     */  
    @Id("t_isbn")  
    private String isbn;  
  
    /** 
     * 书名 
     */  
    @Column("t_name")  
    private String name;  
  
    /** 
     * 作者 
     */  
    @Column("t_author")  
    private String author;  
  
    /** 
     * 出版社 
     */  
    @Column("t_publishing")  
    private String publishing;  
  
    /** 
     * 出版时间 
     */  
    @Column(value = "t_pubdate")  
    private Date pubdate;  
  
    /** 
     * 价格 
     */  
    @Column(value = "t_price")  
    private double price;  
  
    public String getIsbn() {  
        return isbn;  
    }  
  
    public void setIsbn(String isbn) {  
        this.isbn = isbn;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name;  
    }  
  
    public String getAuthor() {  
        return author;  
    }  
  
    public void setAuthor(String author) {  
        this.author = author;  
    }  
  
    public String getPublishing() {  
        return publishing;  
    }  
  
    public void setPublishing(String publishing) {  
        this.publishing = publishing;  
    }  
  
    public Date getPubdate() {  
        return pubdate;  
    }  
  
    public void setPubdate(Date pubdate) {  
        this.pubdate = pubdate;  
    }  
  
    public double getPrice() {  
        return price;  
    }  
  
    public void setPrice(double price) {  
        this.price = price;  
    }  
  
    @Override  
    public String toString() {  
        return "书名: " + name + " 图书编号: " + isbn + " 作者: " + author  
                + " 出版社: " + publishing + " 出版时间: " + pubdate  
                + " 价格: " + price;  
    }  
}  
 

6)测试泛型DAO的CRUD操作

package com.zy.simpleORM;

import junit.framework.TestCase;


import java.io.InputStream;
import java.sql.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.junit.BeforeClass;
import org.junit.Test;

/**
 * 测试泛型DAO的CRUD操作
 */
public class GenericDaoTest  {
    
    private GenericDAO<Book> bookDao = new GenericDAOImpl<Book>();    

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
//        is = XmlParserTest.class.getResourceAsStream("/books.xml");
    }
        
    @SuppressWarnings("deprecation")
    @Test
    public void testSave() throws Exception {
        //构造一本书,插入到数据库中
        Book book = new Book();    
        book.setIsbn("1234");
        book.setAuthor("zy");
        book.setName("pingfan");
        book.setPrice(55);
        book.setPubdate(new Date(105, 11, 12));  //这里的年是距离1900年的
        book.setPublishing("renmingchubanshe");
        bookDao.save(book);
    }        
    
    @Test
    public void testDelete() throws Exception {
        bookDao.delete(1, Book.class);
    }
    
    //更新数据测试,应该先search到数据,然后在数据上面设置值,然后update到数据库
    @SuppressWarnings("deprecation")
    @Test
    public void testUpdate() throws Exception {
        Book book = new Book();
        book.setIsbn("1234");  
        book.setName("test");  
        book.setAuthor("test");  
        book.setPublishing("test");     
        book.setPubdate(new Date(110,10,11));  
        book.setPrice(50.6);
        bookDao.update(book);
        
    }
    

    @Test
    public void testGet() throws Exception {
        bookDao.get("1234",Book.class);        
    }
    
    @Test
    public void testFindAllByConditions() throws Exception {
        System.out.println("\n-------------更新、删除前,测试根据条件查询所有记录--------------------");  
        Map<String,Object> sqlWhereMap = new HashMap<String, Object>();  
        //sqlWhereMap.put("t_isbn", "9787111213826");  
        //sqlWhereMap.put("t_name", "Java");  
        sqlWhereMap.put("t_publishing", "test");  
        //sqlWhereMap.put("t_pubdate", new Date(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2007-01-01 12:06:00").getTime()));  
        List<Book> books = bookDao.findAllByConditions(sqlWhereMap, Book.class);  
        for (Book book : books) {  
            System.out.println(book);  
        } 
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值