1、
ORM介绍
对象关系映射
解决了一个问题: 对象模型和关系模型之间阻抗。
对象模型 关系模型
对象名称 Student 表 t_student
对象属性类型 Integer 列的值的类型 int
对象属性名称 stuId 列名 student_id
1、ORM思想就诞生=>Java是一门面向对象的语言。
2、操作对象中属性的值间接操作数据库中表。
实现方式:hibernate框架
Student.hbm.xml
<class name="类的全路径" table="映射的表的名称">
<id name="主键映射的属性名称">
<cloumn name="表中的主键名称" />
</id>
<property name="studentName" cloumn="student_name" />
</class>
mybatis框架:
<resutMap name="stuMap" type="com.demo.domain.Student">
<id property="studentId" cloumn="student_id" />
<result property="studentName" column="student_name"/>
</resultMap>
// 通过注解方式完成ORM映射配置
JPA,hibernate,spring-data-jpa
@Table(name="t_student")
public class Student {
@Id // 映射主键
@Column(name="student_id")
private Integer studentId;
@Column(name="student_name")
private String studentName;
}
springBoot(mybatis,spring-data-jpa,hibernate)=>微框架
2、
ORM框架的核心反射
反射:API
自定义注解:核心语法和使用方式
3、
模拟ORM的框架的部分实现
首先需要连接到JDBC,导入我们的驱动包以及手写一个工具类
手动实现增删改执行返回影响行数的方法
package com.orm.demo.db;
/**
* @author longhai
* @date 2018/9/19 - 14:06
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
/**
* 操作数据的通过方法
*/
public class DBUtils {
private static final String DRIVER_CLASS = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/practice?useSSL=true";
private static final String USERNAME = "root";
private static final String PASSWORD = "123456";
static {
try {
Class.forName(DRIVER_CLASS);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取连接对象的方法
*
* @return
*/
private static Connection getConnection() {
try {
return DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 编写一个执行通过的增,删,改的方法, 返回受影响的行数
*/
public static int executeUpdate(String sql, Object...parameters) {
try (
Connection connection = getConnection();
PreparedStatement pst = connection.prepareStatement(sql);
) {
//在sql语句里面添加所对应的参数
// 是否设置参数呢
if (parameters.length > 0 ) {
for (int i = 0; i < parameters.length; i++) {
// 循环设置参数
pst.setObject(i + 1, parameters[i]);//注意:此方法在API里面写到,
// 第一个参数不是零,是1,所以要i+1
}
}
return pst.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
}
然后创建一个学生对象
package com.orm.demo.model;
import com.orm.demo.annoation.Colum;
import com.orm.demo.annoation.Table;
/**
* @author longhai
* @date 2018/9/19 - 14:29
*/
@Table("t_student")
public class StudentInfo {
@Colum("student_id")
private Integer studentId;
@Colum("student_name")
private String studentName;
@Colum("student_sex")
private String studentSex;
@Colum("student_age")
private int studentAge;
public StudentInfo(Integer studentId, String studentName, String studentSex, int studentAge) {
this.studentId = studentId;
this.studentName = studentName;
this.studentSex = studentSex;
this.studentAge = studentAge;
}
public Integer getStudentId() {
return studentId;
}
public void setStudentId(Integer studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getStudentSex() {
return studentSex;
}
public void setStudentSex(String studentSex) {
this.studentSex = studentSex;
}
public int getStudentAge() {
return studentAge;
}
public void setStudentAge(int studentAge) {
this.studentAge = studentAge;
}
}
自定义注解Colum和Table
package com.orm.demo.annoation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author longhai
* @date 2018/9/19 - 13:53
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Colum {
String value() default "";//属性映射的字段名称
}
package com.orm.demo.annoation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author longhai
* @date 2018/9/19 - 13:52
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {
String value() default "";//注解映射的表名称
}
具体实现类
注:由于注释比较详细,思路我就不多说了,非常易懂
package com.orm.demo;
import com.orm.demo.annoation.Colum;
import com.orm.demo.annoation.Table;
import com.orm.demo.db.DBUtils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* @author longhai
* @date 2018/9/19 - 14:36
*
*
* javabean操作的通用工具类
* <pre>
* 目标: 把entity对象传入到方法中完成该对象的持久化。
* 核心: 反射
* </pre>
*
*/
public class BeanUtil {
public static <T> int save(T entity){
// 定义存储SQL语句占位符对应值的集合(也就是属性字段所对应的值)
List<Object> parameters = new ArrayList<>();
StringBuilder sqlBuilder = new StringBuilder(256);//springbuffer方便组合sql语句
// 获取到当前操作类的Class对象
Class<?> aClass = entity.getClass();
// 问题1: 表名称和类名称不一致怎么办?
String tableName = aClass.getSimpleName();
// 判断aClass是否有Table注解
if (aClass.isAnnotationPresent(Table.class)) {
Table table = aClass.getAnnotation(Table.class);
if (!"".equals(table.value())) {
tableName = table.value().toUpperCase();//如果写了别名
// 就将表的名字设为别名的大写
}
}
// 构建前面半部分SQL
sqlBuilder.append("INSERT INTO ").append(tableName).append(" (");
确定哪些字段需要参与SQL语句中 /
Field[] fields = aClass.getDeclaredFields();
try {//通过此对象获取到其所有字段以及属性
if (fields != null && fields.length > 0) {
for (Field field : fields) {
// 获取列名
String columName = field.getName();
//判断是否有表字段和此类属性名称对不上的情况
if (field.isAnnotationPresent(Colum.class)) {
Colum column = field.getAnnotation(Colum.class);
if (!"".equals(column.value())) {
columName = column.value().toUpperCase();
}
}
// 获取当前这个字段的值
field.setAccessible(true);
Object value = field.get(entity);
if (value != null) {
sqlBuilder.append(columName).append(",");
parameters.add(value);
//每个字段值追加逗号
}
}
sqlBuilder.deleteCharAt(sqlBuilder.length() - 1).append(") VALUES (");
//截取最后一个逗号
}
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < parameters.size(); i++) {
sqlBuilder.append("?,");
}
//构建sql语句后半段(?,?,?,?,
sqlBuilder.deleteCharAt(sqlBuilder.length() - 1).append(")");
//(?,?,?,?)
System.out.println(sqlBuilder);//打印sql语句
System.out.println(parameters);//打印参数
return DBUtils.executeUpdate(sqlBuilder.toString(),parameters.toArray());
//由于parameters是集合所以将他toArrary一下
}
}
import com.orm.demo.model.StudentInfo;
/**
* @author longhai
* @date 2018/9/19 - 14:53
*/
public class TestORM {
public static void main(String[] args) {
// 创建一个学生对象
StudentInfo studentInfo = new StudentInfo(1001, "寒梅", "男", 20);
int row = BeanUtil.save(studentInfo);
System.out.println(row > 0 ? "成功" : "失败");
}
}
我的数据库是这样的 :表名T_STUDENT 字段:STUDENT_ID,STUDENT_NAME,STUDENT_AGE,STUDENT_SEX
测试一下,我们已经将这一条信息添加到数据库中了!
大家理解了大概的过程了吗? 去动手吧,写出自己想要的功能!框架其实并没有那么困难,要多动手多动脑!
对你有帮助的就点个赞,让天下没有难学的编程
版权声明:本文为Area007原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。