美文网首页java攻城狮我们就爱程序媛
利用反射实现数据库CRUD操作

利用反射实现数据库CRUD操作

作者: 大炮对着虫子 | 来源:发表于2017-09-16 16:42 被阅读14次

    如果不能简单的把事情说清楚,说明你还没有完全明白。

    最近学习框架的时候,一去看源码就各种懵逼与难受,所以去补了一波反射和动态代理。反射其实就是一波API,平时自己很少用到,陌生产生恐惧。

    正常情况下的CRUD操作,JDBC

    Bean

    public class User 
    {
        private int user_id;
        private String user_name;
        private String user_password;
        private String user_role;
    、、、各种get set
        
    }
    

    DAO

    public class UserDAO {
        private Connection conn=(Connection) ConnectFactory.getConnection();
        
        
        public List<User> selectAllUser()
        {
            List<User> list=new ArrayList<>();
            try
            {
                PreparedStatement st=null;
                String sql="select * from user";
                st=(PreparedStatement) conn.prepareStatement(sql);
                ResultSet rs=st.executeQuery(sql);
                while(rs.next())
                {
                    User user=new User();
                    
                    
                    user.setUser_name(rs.getString("user_name"));
                    user.setUser_id(rs.getInt("user_id"));
                    user.setUser_password(rs.getString("user_password"));
                    user.setUser_role(rs.getString("user_role"));
                    list.add(user);
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                ConnectFactory.closeConnection();
            }
            return list;
            
        }
    }
    

    那么问题来了,如果有10个表需要进行同样的操作,比如:查询表的所有信息,查询总记录数,插入一条信息等 这种通用操作的sql语句。就会用传统的JDBC操作,程序猿小哥表示ctrl+c ctrl+v 不过来。

    利用反射实现CRUD操作
    public class ReflexDAO {
        private Connection conn=(Connection) ConnectFactory.getConnection();
        
        /**
         * 查询 所有
         * @param c1
         * @return
         */
        public ArrayList selectAll(Class c1)  //如果查询ID,加个ID参数。ID作为主键默认 在Bean属性的 第一个。
        {
            ArrayList list=new ArrayList();
            try
            {
                PreparedStatement st=null;
                //数据库表的名字 ==bean类的名字
                String sql="select * from "+c1.getSimpleName();
                
                st=(PreparedStatement) conn.prepareStatement(sql);
                ResultSet rs=st.executeQuery(sql);
                
                Field [] fi=c1.getDeclaredFields();  //获取到 类对象 的所有属性
                while(rs.next())
                {
                    
                    Object ob=c1.newInstance();
                    for (Field field : fi) {
                        field.setAccessible(true);
                        field.set(ob, rs.getObject(field.getName()));
                    }
                    
                    list.add(ob);
                
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                ConnectFactory.closeConnection();
            }
            return list;
        }
    
    public void insert(Object oj)
        {
            try
            {
                Class cl=oj.getClass();
                PreparedStatement st=null;
                
                
                Field [] fields=cl.getDeclaredFields(); //获取所有的属性
                StringBuffer sf=new StringBuffer();
                sf.append("insert into ");
                
                sf.append(cl.getSimpleName());
                sf.append("(");
                for (int i=1;i<fields.length;i++) {
                    fields[i].setAccessible(true);  //让私有的可以被访问
                    if(i==fields.length-1)
                    {
                        sf.append(fields[i].getName());
                    }
                    else
                    {
                        sf.append(fields[i].getName()+",");
                    }
                
                    
                }
                sf.append(") value(");
                
                for (int i=1;i<fields.length;i++) {
                    
                    if(i==fields.length-1)
                    {
                        sf.append("?)");
                    }
                    else
                    {
                        sf.append("?,");
                    }
                    
                }
                System.out.println(sf);
                st=(PreparedStatement) conn.prepareStatement(sf.toString());
                for (int i=1;i<fields.length;i++)
                {
                    st.setObject(i, fields[i].get(oj));
                }
                
            
                st.executeUpdate();
        
                
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            finally
            {
                ConnectFactory.closeConnection();
            }
        }
    

    这样子,就能够实现一个方法到处浪。

    值得注意的是:

    数据库的表名 要和类名保持一致,如果不一致的话,需要用配置文件进行映射,框架一般也是这么做的。

    这种方法的反射我只 用了 属性去反射,存在一些局限性:如果属性的个数多余表列属性的个数,那么就会报错。

    相关文章

      网友评论

        本文标题:利用反射实现数据库CRUD操作

        本文链接:https://www.haomeiwen.com/subject/sxdysxtx.html