我对写笔记什么的没什么太大兴趣,用篇博文记录下自己的学习,还是挺不错的。
这篇讲的是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 }
我们再来看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 }
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 }
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 }
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 }
这里奉上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 }
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 }
测试代码
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 }
学习本无底,前进莫徬徨