ORM框架实现的深度剖析

我对写笔记什么的没什么太大兴趣,用篇博文记录下自己的学习,还是挺不错的。

这篇讲的是ORM框架的深度剖析,不废话了。

直接放图

这是数据库类型和java数据类型的映射关系

  我们用代码来说明一下

这是代码的bean类,也就是跟数据库表作对应的

这里用到了两个自定义的注解Table和Column,主要是模拟

 1 package com.orm.demo.domain;
 2 
 3 import org.orm.test.annotation.Column;
 4 import org.orm.test.annotation.Table;
 5 
 6 @Table("t_user")
 7 public class User {
 8     private int id;
 9     @Column("name")
10     private String name;
11     private int age;
12 
13     public int getId() {
14         return id;
15     }
16 
17     public void setId(int id) {
18         this.id = id;
19     }
20 
21     public String getName() {
22         return name;
23     }
24 
25     public void setName(String name) {
26         this.name = name;
27     }
28 
29     public int getAge() {
30         return age;
31     }
32 
33     public void setAge(int age) {
34         this.age = age;
35     }
36 
37     public User(String name, int age) {
38         this.name = name;
39         this.age = age;
40     }
41 }
View Code

 我们再来看dao层的代码

这里的session是自定义的类

 1 package com.orm.demo.mapper;
 2 
 3 import com.orm.demo.domain.User;
 4 
 5 import java.util.List;
 6 
 7 public interface UserMapper {
 8     List<User> findAll();
 9     void insert(User user);
10 }
View Code
 1 package com.orm.demo.mapper.impl;
 2 
 3 import com.orm.demo.domain.User;
 4 import com.orm.demo.mapper.UserMapper;
 5 import org.orm.test.Session;
 6 import org.orm.test.impl.SessionImpl;
 7 
 8 import java.util.List;
 9 
10 public class UserMapperImpl implements UserMapper {
11     private Session session = new SessionImpl();
12 
13     public List<User> findAll() {
14         List<User> users = session.findAll();
15         return users;
16     }
17 
18     public void insert(User user) {
19         session.insert(user);
20     }
21 }
View Code
1 package org.orm.test;
2 
3 import java.util.List;
4 
5 public interface Session {
6     <T> List<T> findAll();
7     <T> void insert(T obj);
8 }
View Code
  1 package org.orm.test.impl;
  2 
  3 import org.orm.test.Session;
  4 import org.orm.test.annotation.Column;
  5 import org.orm.test.annotation.Table;
  6 
  7 import java.lang.reflect.Field;
  8 import java.sql.*;
  9 import java.util.ArrayList;
 10 import java.util.List;
 11 
 12 public class SessionImpl implements Session {
 13     static {
 14         //加载驱动
 15         try {
 16             Class.forName("com.mysql.jdbc.Driver");
 17         } catch (ClassNotFoundException e) {
 18             e.printStackTrace();
 19         }
 20     }
 21 
 22     /**
 23      * 获取数据源
 24      * @return
 25      */
 26     private Connection getDataSource(){
 27         try {
 28             return DriverManager.getConnection(
 29                     "jdbc:mysql:///springboot",
 30                     "root",
 31                     "123"
 32             );
 33         } catch (SQLException e) {
 34             e.printStackTrace();
 35         }
 36         return null;
 37     }
 38 
 39 
 40     public <T> List<T> findAll() {
 41         Connection conn = getDataSource();
 42         String sql = "";
 43         try {
 44             PreparedStatement pst = conn.prepareStatement(sql);
 45             ResultSet res = pst.executeQuery();
 46         } catch (SQLException e) {
 47             e.printStackTrace();
 48         }
 49         return null;
 50     }
 51 
 52     public <T> void insert(T obj) {
 53         //实例化一个sb,用以存放sql
 54         StringBuilder sb = new StringBuilder();
 55         //存放参数的列表
 56         List<Object> paramList = new ArrayList<Object>();
 57         //调用方法拼接sql和拿到参数列表
 58         buildCondition(obj,sb,paramList);
 59         //拿到sql的字符串
 60         String sql = sb.toString();
 61         //拿到数据库连接
 62         Connection conn = getDataSource();
 63         try {
 64             PreparedStatement pst = conn.prepareStatement(sql);
 65             for(int i=0;i<paramList.size();i++){
 66                 pst.setObject(i+1,paramList.get(i));
 67             }
 68             pst.executeUpdate();
 69         } catch (SQLException e) {
 70             e.printStackTrace();
 71         }
 72     }
 73 
 74     public void buildCondition(Object obj,StringBuilder sb,List<Object> paramList){
 75         //获得当前对象的类
 76         Class<?> cls = obj.getClass();
 77         //拿到当前对象的类名作为表名
 78         String tableName = cls.getName().toUpperCase();
 79         //判断当前类是否有table注解
 80         if (cls.isAnnotationPresent(Table.class)){
 81             //如果有的话,把映射的表名取出
 82             tableName = cls.getAnnotation(Table.class).value().toUpperCase();
 83         }
 84         //添加sql前面的语句
 85         sb.append("insert into ").append(tableName).append("(");
 86         //获得当前类的所有属性
 87         Field[] fields = cls.getDeclaredFields();
 88         //遍历属性
 89         for(Field field : fields){
 90             //拿到当前属性的名字
 91             String col = field.getName().toUpperCase();
 92             //判断属性是否有column注解
 93             if(field.isAnnotationPresent(Column.class)){
 94                 //如果有,就把列名赋值为映射的名字
 95                 col = field.getAnnotation(Column.class).value().toUpperCase();
 96             }
 97             //添加sql
 98             sb.append(col+",");
 99             //获取字段值,设置可获取
100             field.setAccessible(true);
101             try {
102                 //拿到当前对象相应属性的值
103                 Object val = field.get(obj);
104                 //在参数列表中加入值
105                 paramList.add(val);
106             } catch (IllegalAccessException e) {
107                 e.printStackTrace();
108             }
109         }
110         //删除sb中最后一个逗号(多余)
111         sb.deleteCharAt(sb.length() - 1).append(") values(");
112         //遍历参数列表
113         for(int i=0;i<paramList.size();i++){
114             //拼接sql
115             sb.append("?,");
116         }
117         //删除sb中最后一个逗号(多余)
118         sb.deleteCharAt(sb.length() - 1).append(")");
119         System.out.print("sql=========>");
120         //输出sb
121         System.out.println(sb);
122     }
123 }
View Code

这里奉上session的代码,注释中有详细说明

这里是两个注解的代码

 1 package org.orm.test.annotation;
 2 
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Retention;
 5 import java.lang.annotation.RetentionPolicy;
 6 import java.lang.annotation.Target;
 7 
 8 @Retention(RetentionPolicy.RUNTIME)
 9 @Target(ElementType.TYPE)
10 public @interface Table {
11     String value() default "";
12 }
View Code
 1 package org.orm.test.annotation;
 2 
 3 import java.lang.annotation.ElementType;
 4 import java.lang.annotation.Retention;
 5 import java.lang.annotation.RetentionPolicy;
 6 import java.lang.annotation.Target;
 7 
 8 @Retention(RetentionPolicy.RUNTIME)
 9 @Target(ElementType.FIELD)
10 public @interface Column {
11     String value();
12 }
View Code

测试代码

 1 import com.orm.demo.domain.User;
 2 import com.orm.demo.mapper.UserMapper;
 3 import com.orm.demo.mapper.impl.UserMapperImpl;
 4 import org.junit.Test;
 5 
 6 import java.util.List;
 7 
 8 public class TestDao {
 9     private UserMapper userMapper = new UserMapperImpl();
10     @Test
11     public void test(){
12         User user = new User("小刘",18);
13         userMapper.insert(user);
14         System.out.println("插入成功");
15 //        List<User> users = userMapper.findAll();
16 //        System.out.println(users);
17     }
18 }
View Code

学习本无底,前进莫徬徨

猜你喜欢

转载自www.cnblogs.com/lwhblog/p/10599446.html