Skip to content

Latest commit

 

History

History
201 lines (163 loc) · 6.71 KB

09.基于SpringJDBC手写定制自己的ORM框架.md

File metadata and controls

201 lines (163 loc) · 6.71 KB

手写定制ORM框架

从ResultSet说起

public class JdbcTest {

    public static void main(String[] args) {
        Member condition = new Member();
        condition.setName("Tom");
        condition.setAge(19);
        List<?> result =  select(condition);
        System.out.println(Arrays.toString(result.toArray()));
    }

    private static List<?> select(Object condition) {

        List<Object> result = new ArrayList<>();

        Class<?> entityClass = condition.getClass();

        Connection con = null;
        PreparedStatement pstm = null;
        ResultSet rs = null;
        try {
            //1、加载驱动类
            Class.forName("com.mysql.jdbc.Driver");
            //2、建立连接
            con = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/gp-vip-spring-db-demo?characterEncoding=UTF-8&rewriteBatchedStatements=true","root","123456");

            //根据类名找属性名
            Map<String,String> columnMapper = new HashMap<String,String>();
            //根据属性名找字段名
            Map<String,String> fieldMapper = new HashMap<String,String>();
            Field[] fields =  entityClass.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String fieldName = field.getName();
                if(field.isAnnotationPresent(Column.class)){
                    Column column = field.getAnnotation(Column.class);
                    String columnName = column.name();
                    columnMapper.put(columnName,fieldName);
                    fieldMapper.put(fieldName,columnName);
                }else {
                    //默认就是字段名属性名一致
                    columnMapper.put(fieldName, fieldName);
                    fieldMapper.put(fieldName,fieldName);
                }
            }

            //3、创建语句集
            Table table = entityClass.getAnnotation(Table.class);
            String sql = "select * from " + table.name();

            StringBuffer where = new StringBuffer(" where 1=1 ");
            for (Field field : fields) {
                Object value =field.get(condition);
                if(null != value){
                    if(String.class == field.getType()) {
                        where.append(" and " + fieldMapper.get(field.getName()) + " = '" + value + "'");
                    }else{
                        where.append(" and " + fieldMapper.get(field.getName()) + " = " + value + "");
                    }
                    //其他的,在这里就不一一列举,下半截我们手写ORM框架会完善
                }
            }
            System.out.println(sql + where.toString());
            pstm =  con.prepareStatement(sql + where.toString());

            //4、执行语句集
            rs = pstm.executeQuery();

            //元数据?
            //保存了处理真正数值以外的所有的附加信息
            int columnCounts = rs.getMetaData().getColumnCount();
            while (rs.next()){
                Object instance = entityClass.newInstance();
                for (int i = 1; i <= columnCounts; i++) {
                    //实体类 属性名,对应数据库表的字段名
                    //可以通过反射机制拿到实体类的说有的字段

                    //从rs中取得当前这个游标下的类名
                    String columnName = rs.getMetaData().getColumnName(i);
                    //有可能是私有的
                    Field field = entityClass.getDeclaredField(columnMapper.get(columnName));
                    field.setAccessible(true);
                    field.set(instance,rs.getObject(columnName));
                }

                result.add(instance);


            }

            //5、获取结果集
        }catch (Exception e){
            e.printStackTrace();
        }
        //6、关闭结果集、关闭语句集、关闭连接
        finally {
            try {
                rs.close();
                pstm.close();
                con.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        return result;
    }

}
public class OrmTest {

    private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmdd");

    @Autowired private MemberDao memberDao;

    @Autowired private OrderDao orderDao;

    //ORM(对象关系映射 Object Relation Mapping)
    //Hibernate/Spring JDBC/MyBatis/JPA 一对多、多对多、一对一

    //Hibernate 全自动档  不需要写一句SQL语句
    //MyBatis 半自动(手自一体) 支持简单的映射,复杂关系,需要自己写SQL
    //Spring JDBC 全手动挡,所有的SQL都要自己写,它帮我们设计了一套标准  模板模式

    //为什么有了MyBatis我还要自己的手写ORM框架呢?
    //1、用MyBatis,我可控性无法保证
    //2、我有不敢用Hibernate,高级玩家玩的,
    //3、没有时间自己从0到1写一个ORM框架
    //4、站在巨人的肩膀上再升级,做二次开发

    //约定优于配置
    //1、先制定顶层接口,参数返回值全部统一
    // List<?> Page<?>  select(QueryRule queryRule)
    // Int   delete(T entity) entity中的ID不能为空,如果ID为空,其他条件不能为空,都为空不予执行
    // ReturnId  insert(T entity) 只要entity不等于null
    // Int  update(T entity) entity中的ID不能为空,如果ID为空,其他条件不能为空,都为空不予执行

    //基于JDBC封装了一套
    //基于Redis封装了一套
    //基于MongoDB
    //基于ElasticSearch
    //基于Hive
    //基于HBase

    //QueryRule

    @Test
    public void testSelectAllForMember(){
        try {
            List<Member> result = memberDao.selectAll();
            System.out.println(Arrays.toString(result.toArray()));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    @Ignore
    public void testInsertMember(){
        try {
            for (int age = 25; age < 35; age++) {
                Member member = new Member();
                member.setAge(age);
                member.setName("Tom");
                member.setAddr("Hunan Changsha");
                memberDao.insert(member);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }


    @Test
//	@Ignore
    public void testInsertOrder(){
        try {
            Order order = new Order();
            order.setMemberId(1L);
            order.setDetail("历史订单");
            Date date = sdf.parse("20180201123456");
            order.setCreateTime(date.getTime());
            orderDao.insertOne(order);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}