ORM:(Object relative Mapping)对象关系映射框架。帮你自动把数据库中的记录和java实体类对应映射在一起。
框架对应的包
annotation包:
TableName:
package com.lqh.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = {ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
String value();
}
TableField:
package com.lqh.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(value = ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableField {
String value();
}
dao包:
StudentDao:
package com.lqh.dao;
import com.lqh.entity.Student;
import com.lqh.utils.BaseDao;
/**
* @Author Li Qinghua
* @Create 2022/7/14 20:30
*/
public class StudentDao extends BaseDao<Student> {
}
entity包:
Student:
package com.lqh.entity;
import com.lqh.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author Li Qinghua
* @Create 2022/7/14 20:17
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName(value = "tb_student")
public class Student {
private Integer id;
private String name;
private Integer age;
private String address;
}
utils包:
BaseDao:
package com.lqh.utils;
import com.lqh.annotation.TableField;
import com.lqh.annotation.TableId;
import com.lqh.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.Arrays;
import java.util.List;
/**
* @Author Li Qinghua
* @Create 2022/7/14 20:14
*/
public class BaseDao<E> {
private Connection connection;
private ResultSet res;
private PreparedStatement ps;
private Class<?> clazz;
public BaseDao(){
//this对应的是子类对象,获取当前类的反射类对象
Class<? extends BaseDao> aClass = this.getClass();
//获取当前反射类的父类反射类--包含父类的泛型
ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();
//获取泛型的反射类
Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
//System.out.println("~~~~~~~~~~");
//System.out.println(Arrays.toString(actualTypeArguments));
clazz= (Class<?>) actualTypeArguments[0];
//System.out.println(clazz.getSimpleName());
}
public int insert(E e){
try {
StringBuffer sql = new StringBuffer("insert into ");
//获取表名
Class<?> aClass = e.getClass();
TableName tableNameAnnotation = aClass.getAnnotation(TableName.class);
String tableName = "";
//是否存在该注解
if (tableNameAnnotation != null) {
tableName = tableNameAnnotation.value();
} else {
tableName = aClass.getSimpleName();
}
sql.append(tableName);
//获取反射类对象中所有的属性对象
Field[] declaredFields = aClass.getDeclaredFields();
//创建两个集合、分别存放列和列的值
List<String> columns = new ArrayList<>();
List<String> values = new ArrayList<>();
for (Field field : declaredFields) {
field.setAccessible(true);
TableField tableField = field.getAnnotation(TableField.class);
if (tableField != null) {
columns.add(tableField.value());
} else {
columns.add(field.getName());
}
values.add("'" + field.get(e) + "'");
}
sql.append(columns.toString().replace("[", "(").replace("]", ")"));
sql.append(" values ");
sql.append(values.toString().replace("[", "(").replace("]", ")"));
System.out.println(sql);
connection=DBUtil.getConn();
ps=connection.prepareStatement(sql.toString());
int i = ps.executeUpdate();
return 1;
}catch (Exception o){
o.printStackTrace();
}finally {
DBUtil.closeAll(res,ps,connection);
}
return 0;
}
public int delete(Object id){
StringBuffer sql=new StringBuffer("delete from ");
try {
TableName tableName = clazz.getAnnotation(TableName.class);
if (tableName != null) {
sql.append(tableName.value() + " where ");
} else {
sql.append(clazz.getSimpleName() + " where ");
}
Field[] declaredFields = clazz.getDeclaredFields();
boolean flag = false;
for (Field field : declaredFields) {
field.setAccessible(true);
TableId tableId = field.getAnnotation(TableId.class);
if (tableId != null) {
flag = true;
sql.append(tableId.value() + "='" + id + "'");
break;
}
}
if (flag == false) {
throw new RuntimeException("没有添加主键注解!");
}
//System.out.println(sql);
connection = DBUtil.getConn();
ps = connection.prepareStatement(sql.toString());
int i = ps.executeUpdate();
return i;
}catch (Exception o){
o.printStackTrace();
}finally {
DBUtil.closeAll(res,ps,connection);
}
return 1;
}
public int update(E e){
try{
StringBuffer sql=new StringBuffer("update ");
Class<?> eClass = e.getClass();
TableName tableName = eClass.getAnnotation(TableName.class);
if(tableName!=null){
sql.append(tableName.value()+" set ");
}else{
sql.append(eClass.getSimpleName()+" set ");
}
String where=" where ";
boolean flag=false;
Field[] eClassFields = eClass.getDeclaredFields();
for (Field field : eClassFields) {
field.setAccessible(true);
TableId tableId = field.getAnnotation(TableId.class);
if(tableId!=null){
flag=true;
where+=tableId.value()+"='"+field.get(e)+"'";
}else{
TableField tableField = field.getAnnotation(TableField.class);
if(tableField!=null){
sql.append(tableField.value()+"='"+field.get(e)+"',");
}else {
sql.append(field.getName() + "='" + field.get(e) + "',");
}
}
}
if(flag==false){
throw new RuntimeException("No primary key annotation added!");
}
String SQL=sql.substring(0,sql.lastIndexOf(","))+where;
connection=DBUtil.getConn();
ps=connection.prepareStatement(SQL);
int i = ps.executeUpdate();
return 1;
}catch (Exception o){
o.printStackTrace();
}finally {
DBUtil.closeAll(res,ps,connection);
}
return 0;
}
public List<E> findAll(){
List<E> list=new ArrayList<>();
StringBuffer sql=new StringBuffer("select * from ");
try {
TableName tableName = clazz.getAnnotation(TableName.class);
if (tableName != null) {
sql.append(tableName.value());
} else {
sql.append(clazz.getSimpleName());
}
//System.out.println(sql);
connection = DBUtil.getConn();
ps = connection.prepareStatement(sql.toString());
res = ps.executeQuery();
while (res.next()){
Object obj = clazz.newInstance();
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {
field.setAccessible(true);
TableName annotation = field.getAnnotation(TableName.class);
if(annotation!=null){
field.set(obj,res.getObject(annotation.value()));
}else{
field.set(obj,res.getObject(field.getName()));
}
}
list.add((E) obj);
}
}catch (Exception o){
o.printStackTrace();
}finally {
DBUtil.closeAll(res,ps,connection);
}
return list;
}
}
DBUtil:
package com.lqh.utils;
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;
/**
* @Author Li Qinghua
* @Create 2022/7/14 20:03
*/
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();
//加载属性配置文件
properties.load(new FileInputStream("E:\\IDEA练习\\高级\\手撕ORM框架\\src\\main\\resources\\db.properties"));
//读取属性配置文件的内容
driverName = properties.getProperty("jdbc.driverName");
url = properties.getProperty("jdbc.url");
username = properties.getProperty("jdbc.username");
password = properties.getProperty("jdbc.password");
}catch (Exception e){
e.printStackTrace();
}
}
public static Connection getConn() throws Exception{
Class.forName(driverName);
Connection connection = DriverManager.getConnection(url,username,password);
return connection;
}
public static void closeAll(ResultSet res, PreparedStatement ps,Connection connection){
try {
if(res!=null){
res.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(ps!=null){
ps.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
try {
if(connection!=null){
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
测试:
Test:
package com.lqh;
import com.lqh.dao.StudentDao;
import com.lqh.entity.Student;
import java.util.List;
/**
* @Author Li Qinghua
* @Create 2022/7/14 20:31
*/
public class Test {
StudentDao sd=new StudentDao();
@org.junit.Test
public void testInsert() {
int insert = sd.insert(new Student(5,"王五4",25,"周口"));
}
@org.junit.Test
public void testUpdate(){
int update = sd.update(new Student(1,"ll",9,"zz"));
}
@org.junit.Test
public void testUpdate02(){
int id = sd.update02(new Student(1,"pp",19,"zpz"));
}
@org.junit.Test
public void testDelete(){
int delete = sd.delete(5);
}
@org.junit.Test
public void testFindAll(){
List<Student> list = sd.findAll();
System.out.println(list);
}
}
db.properties
jdbc.driverName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db2?serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=pAssW0rd
核心代码在BaseDao中