目录
手写ORM框架:----O(Object 对象) R(relative 关系) M(Mapping 映射) 对象关系映射
就是把数据库中的表映射为java的类,表中的记录映射为java的对象,列映射为java类中属性。
该框架可以在不写sql语句的前题下完成对单表的CRUD操作。
一、Annitation包:自定义注解 用于实体类上
TableName:表明和实体类名不一致时使用
TableField:列名和属性名不一致时使用
TableId:列名和属性名不一致时使用
package com.wjk.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableField {
String value();
}
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/28 14:17
* @Version 1.0
*/
package com.wjk.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableId {
String value() default "id";
}
package com.wjk.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
String value();
}
二、until:公共类
DBUtils:获取连接对象和关闭连接资源
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/28 9:27
* @Version 1.0
*/
package com.wjk.until;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class DBUtil {
private static String driverName="";
private static String url="";
private static String username="";
private static String password="";
//静态代码块 随着类的加载而被加载到内存中,且只会被加载一次
static {
try {
//该类用于读取属性文件
Properties properties=new Properties();
InputStream inputStream = ClassLoader.getSystemResourceAsStream("db.properties");
properties.load(inputStream);
//读取属性文件中相应的内容
driverName =properties.getProperty("jdbc.driverName");
url =properties.getProperty("jdbc.url");
username =properties.getProperty("jdbc.username");
password =properties.getProperty("jdbc.password");
}catch (Exception e){
throw new RuntimeException("无法读取db.properties");
}
}
/**
* 获取数据库连接
* @return
*/
public static Connection getConnection()throws Exception{
Class.forName("com.mysql.cj.jdbc.Driver");
Connection connection= DriverManager.getConnection(url,username,password);
return connection;
}
/**
* 关闭资源
* @param connection
* @param ps
* @param rs
*/
public static void closeAll(Connection connection, PreparedStatement ps, ResultSet rs){
try {
if (rs!=null){
rs.close();
}
if (ps!=null){
ps.close();
}
if (connection!=null){
connection.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
三、BaseDao类:父类
如何获取类名中泛型T:
//this对应的是子类对象 获取当前类的反射类对象
Class<? extends BaseDao> aClass = this.getClass();
//获取当前反射类的父类反射类----包含了父类的泛型
ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();
//获取泛型的反射类
Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
clazz = (Class<?>) actualTypeArguments[0];
BaseDao中的添加方法
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/28 12:57
* @Version 1.0
*/
package com.wjk.until;
import com.wjk.annotation.TableField;
import com.wjk.annotation.TableId;
import com.wjk.annotation.TableName;
import org.junit.Test;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.ArrayList;
import java.util.List;
public class BaseDao<T> {
/**
* 添加功能
* insert into
* @param t
* @return
*/
public int insert(T t)throws Exception{
StringBuilder sql=new StringBuilder("insert into ");
//根据对象获取该对象反射类的Class
Class<?> aClass = t.getClass();
//获取反射类上的注解
TableName annotation = aClass.getAnnotation(TableName.class);
//获取注解的属性
String tableName = annotation.value();
//拿到表名
sql.append(tableName);
//获取所有的列名
Field[] fields = aClass.getDeclaredFields();
//声明集合 代表所有的列名
List<String> columns=new ArrayList<>();
//声明集合 代表的所有列值
List<Object> values=new ArrayList<>();
for (Field field:fields){
//获取属性对象上的注解对象
TableField tableField = field.getAnnotation(TableField.class);
TableId tableId = field.getAnnotation(TableId.class);
String name ="";
if (tableId!=null){
continue;
}
if (tableField!=null){
name=tableField.value();
}else {
name=field.getName();
}
//允许访问
field.setAccessible(true);
//获取对象t对应的列值
Object o = field.get(t);
values.add("'"+o+"'");
columns.add(name);
}
//获取到了列名
String columnNames=columns.toString().replace("[","(").replace("]",")");
//获取到了列值
String valuesNames=values.toString().replace("[","(").replace("]",")");
sql.append(columnNames);
sql.append("values");
sql.append(valuesNames);
System.out.println(sql);
//执行sql
Connection connection = DBUtil.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql.toString());
int i = preparedStatement.executeUpdate();
return 0;
}
}
BaseDao中的删改和查询方法
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/28 12:57
* @Version 1.0
*/
package com.wjk.until;
import com.wjk.annotation.TableField;
import com.wjk.annotation.TableId;
import com.wjk.annotation.TableName;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class BaseDao<T> {
private Class<?> aClazz;
public BaseDao(){
//this对应的是子类对象 获取当前类的反射对象
Class<? extends BaseDao> aClass = this.getClass();
//获取当前反射类的父类
ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();
//获取泛型的反射类
Type[] types = genericSuperclass.getActualTypeArguments();
aClazz= (Class<?>) types[0];
}
private Connection conn = null;
private ResultSet rs=null;
/**
* 修改功能
* @param t
* @return
* @throws Exception
*/
public int update(T t) throws Exception {
StringBuilder sql=new StringBuilder("update ");
//根据对象获取该对象反射类的Class
Class<?> aClass = t.getClass();
//获取反射类上的注解
TableName annotation = aClass.getAnnotation(TableName.class);
//获取注解的属性
String tableName = "";
//判断是否存在注解
if (annotation!=null){
tableName=annotation.value();
}else {
tableName=aClass.getSimpleName();
}
sql.append(tableName+" set ");
String colunmValue="";
String where ="where ";
//获取所有属性
Field[] declaredFields = aClass.getDeclaredFields();
boolean flag=false;
for (Field field:declaredFields){
//允许访问
field.setAccessible(true);
//获取属性对象的指定注解
TableField tableField = field.getAnnotation(TableField.class);
TableId tableId = field.getAnnotation(TableId.class);
if (tableId!=null){
flag=true;
where+=tableId.value()+"='"+field.get(t)+"'";
}else {
if (tableField!=null){
colunmValue+=tableField.value()+"='"+field.get(t)+"',";
}else {
//获取属性名称
colunmValue+=field.getName()+"='"+field.get(t)+"',";
}
}
}
if (flag==false){
throw new RuntimeException("没有添加主键注解");
}
//这里要删除最后的逗号
colunmValue= colunmValue.substring(0, colunmValue.lastIndexOf(","));
sql.append(colunmValue);
sql.append(where);
System.out.println(sql);
conn=DBUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql.toString());
int row = ps.executeUpdate();
return row;
}
/**
* 删除功能
* @param id
* @return
*/
public int delete(Object id)throws Exception{
StringBuilder sql=new StringBuilder("delete from ");
//获取表名
TableName tableName = aClazz.getAnnotation(TableName.class);
if (tableName!=null){
sql.append(tableName.value());
}else {
sql.append(aClazz.getSimpleName());
}
sql.append(" where ");
Field[] fields = aClazz.getDeclaredFields();
boolean flag=false;
for (Field field:fields){
TableId tableId = field.getAnnotation(TableId.class);
if (tableId!=null){
sql.append(tableId.value()+" = '"+id+"'");
flag=true;
break;
}
}
if (flag==false){
throw new RuntimeException("没有主键注解");
}
System.out.println(sql);
Connection connection = DBUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(sql.toString());
int i = ps.executeUpdate();
return i;
}
/**
* 查询所有
* @return
*/
public List<T> selectAll()throws Exception{
List<T> list = new ArrayList<>();
StringBuilder sql=new StringBuilder("select ");
//获取所有属性对象
Field[] declaredFields = aClazz.getDeclaredFields();
boolean flag=false;
for (Field field:declaredFields){
//允许访问
field.setAccessible(true);
TableField tableField = field.getAnnotation(TableField.class);
TableId tableId = field.getAnnotation(TableId.class);
if (tableId!=null){
flag=true;
sql.append(tableId.value()+",");
}else {
if (tableField!=null){
sql.append(tableField.value()+",");
}else {
//获取属性名称
sql.append(field.getName()+",");
}
}
}
if (flag==false){
throw new RuntimeException("没有主键注解");
}
sql.deleteCharAt(sql.length()-1);
sql.append(" from ");
//获取表名
TableName tableName = aClazz.getAnnotation(TableName.class);
if (tableName!=null){
sql.append(tableName.value());
}else {
sql.append(aClazz.getSimpleName());
}
Connection connection = DBUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(sql.toString());
rs = ps.executeQuery();
while (rs.next()){
Object o = aClazz.newInstance();
Field[] declaredFields1 = aClazz.getDeclaredFields();
boolean flag1=false;
for (Field field:declaredFields1){
field.setAccessible(true);
TableField tableField = field.getAnnotation(TableField.class);
TableId tableId = field.getAnnotation(TableId.class);
if (tableId!=null){
flag1=true;
field.set(o,rs.getObject(tableId.value()));
}else {
if (tableField!=null){
field.set(o,rs.getObject(tableField.value()));
}else {
field.set(o,rs.getObject(field.getName()));
}
}
}
if (flag1==false){
throw new RuntimeException("没有主键注解");
}
list.add((T) o);
}
return list;
}
/**
* 根据id查询
* @param id
* @return
*/
public T selectById(Object id)throws Exception{
T t =null;
StringBuilder sql=new StringBuilder("select ");
//获取所有的属性对象
Field[] declaredFields = aClazz.getDeclaredFields();
String where = " where ";
boolean flag=false;
for (Field field:declaredFields){
field.setAccessible(true);
//获取属性对象的注解
TableField tableField = field.getAnnotation(TableField.class);
TableId tableId = field.getAnnotation(TableId.class);
if (tableId!=null){
flag=true;
sql.append(tableId.value()+",");
where+=tableId.value()+" = ";
}else {
if (tableField!=null){
sql.append(tableField.value()+",");
}else {
//获取属性名称
sql.append(field.getName()+",");
}
}
}
if (flag==false){
throw new RuntimeException("没有主键注解");
}
sql.deleteCharAt(sql.length()-1);
sql.append(" from ");
//获取表名
TableName tableName = aClazz.getAnnotation(TableName.class);
if (tableName!=null){
sql.append(tableName.value());
}else {
sql.append(aClazz.getSimpleName());
}
sql.append(where+id);
Connection connection = DBUtil.getConnection();
PreparedStatement ps = connection.prepareStatement(sql.toString());
rs=ps.executeQuery();
while (rs.next()){
t= (T) aClazz.newInstance();
Field[] declaredFields1 = aClazz.getDeclaredFields();
boolean flag1=false;
for (Field field:declaredFields1){
field.setAccessible(true);
//获取属性对象的注解
TableField tableField = field.getAnnotation(TableField.class);
TableId tableId = field.getAnnotation(TableId.class);
if (tableId!=null){
flag1=true;
field.set(t,rs.getObject(tableId.value()));
}else {
if (tableField!=null){
field.set(t,rs.getObject(tableField.value()));
}else {
field.set(t,rs.getObject(field.getName()));
}
}
}
if (flag1==false){
throw new RuntimeException("没有主键注解");
}
}
return t;
}
}
entity包:实体类Student Teacher
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/28 12:59
* @Version 1.0
*/
package com.wjk.entity;
import com.wjk.annotation.TableField;
import com.wjk.annotation.TableId;
import com.wjk.annotation.TableName;
@TableName(value = "t_student")
public class Student {
@TableId
private Integer id;
@TableField(value = "stu_name")
private String stuName;
@TableField(value = "stu_age")
private Integer stuAge;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public Integer getStuAge() {
return stuAge;
}
public void setStuAge(Integer stuAge) {
this.stuAge = stuAge;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/28 13:00
* @Version 1.0
*/
package com.wjk.entity;
import com.wjk.annotation.TableId;
import com.wjk.annotation.TableName;
import lombok.Data;
@TableName(value = "t_teacher")
@Data
public class Teacher {
@TableId
public int id;
private String name;
private int age;
private String sex;
}
dao包:操作类
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/28 12:58
* @Version 1.0
*/
package com.wjk.dao;
import com.wjk.entity.Student;
import com.wjk.until.BaseDao;
public class StudentDao extends BaseDao<Student> {
}
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/28 13:00
* @Version 1.0
*/
package com.wjk.dao;
import com.wjk.entity.Teacher;
import com.wjk.until.BaseDao;
public class TeacherDao extends BaseDao<Teacher> {
}
测试
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/28 14:45
* @Version 1.0
*/
package com.wjk.test;
import com.wjk.dao.TeacherDao;
import com.wjk.entity.Teacher;
public class Test01 {
public static void main(String[] args) throws Exception {
TeacherDao teacherDao=new TeacherDao();
Teacher teacher=new Teacher();
teacher.setId(11);
teacher.setName("八嘎");
teacher.setAge(99);
teacher.setSex("男");
int update = teacherDao.update(teacher);
TeacherDao teacherDao1=new TeacherDao();
teacherDao1.delete(1);
}
}
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/29 12:11
* @Version 1.0
*/
package com.wjk.test;
import com.wjk.dao.TeacherDao;
import com.wjk.entity.Teacher;
import java.lang.reflect.Method;
import java.util.List;
/**
* 查询所有
*/
public class Test02 {
public static void main(String[] args) throws Exception{
TeacherDao teacherDao=new TeacherDao();
List<Teacher> teachers = teacherDao.selectAll();
System.out.println(teachers);
}
}
/**
* Created by Intellij IDEA
*
* @author 王俊凯
* @Date: 2022/10/29 12:27
* @Version 1.0
*/
package com.wjk.test;
import com.wjk.dao.TeacherDao;
import com.wjk.entity.Teacher;
/**
* 查询单个
*/
public class Test03 {
public static void main(String[] args) throws Exception{
TeacherDao teacherDao=new TeacherDao();
Teacher teacher = teacherDao.selectById(5);
System.out.println(teacher);
}
}