当前位置:网站首页>手撕ORM 框架(泛型+注解+反射)
手撕ORM 框架(泛型+注解+反射)
2022-07-29 05:20:00 【不想秃头的小杨】
ORM:(Object relative Mapping)对象关系映射框架。帮你自动把数据库中的记录和java实体类对应映射在一起。
annitation包 : 自定义注解 用于实体类上
TableName:表名和实体类名不一致时使用
TableField:列名和属性名不一致时使用
TablePrimaryKey: 主键上使用,用来区别于其他属性
package com.qy151.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @unthor : YSH
* @date : 20:39 2022/7/14
*/
@Retention(value = RetentionPolicy.RUNTIME)
@Target(value = ElementType.TYPE)
public @interface TabelName {
String value();
}
util包: 公共类
DBUtils:获取连接对象和关闭连接资源
package com.qy151.util;
import java.sql.*;
/**
* @unthor : YSH
* @date : 20:06 2022/7/14
*/
/*获取连接对象和关闭连接资源*/
public class DBUtils {
private static String driverName="com.mysql.cj.jdbc.Driver";
private static String url="jdbc:mysql://localhost:3306/myda2?serverTimezone=Asia/Shanghai";
private static String user="你的用户名";
private static String password="";
public static Connection getCon() throws Exception {
Class.forName(driverName);
Connection connection = DriverManager.getConnection(url, user, 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();
}
}
}
BaseDao类:父类
如何获取类名中泛型T:
//this对应的是子类对象 获取当前类的反射类对象
Class<? extends BaseDao> aClass = this.getClass();
//获取当前反射类的父类反射类----包含了父类的泛型
ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();
//获取泛型的反射类
Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
clazz = (Class<?>) actualTypeArguments[0];
BaseDao里面实现了简单的CRUD操作
package com.qy151.util;
import com.qy151.annotation.TabelFiled;
import com.qy151.annotation.TabelName;
import com.qy151.annotation.TableId;
import com.qy151.entity.Student;
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;
/**
* @unthor : YSH
* @date : 20:27 2022/7/14
*/
/*T:表示实体类对象*/
public class BaseDao<T> {
private Class<?> clazz;
public BaseDao(){
//this对应的是子类对象 获取当前的反射类对象
Class<? extends BaseDao> aClass = this.getClass();
//获取当前反射类的父类反射类--包含父类的泛型
ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();
//获取泛型的反射类
Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
clazz= (Class<?>) actualTypeArguments[0];
/*System.out.println(clazz);*/
}
/*查询单个和查询所有的公共方法*/
public List<T> find(String sql) throws Exception{
List<T> list = new ArrayList<T>();
Connection connection = DBUtils.getCon();
PreparedStatement ps = connection.prepareStatement(sql.toString());
ResultSet rs = ps.executeQuery();
while (rs.next()){
Object o = clazz.newInstance();
Field[] declaredFields = clazz.getDeclaredFields();
for (Field declaredField:declaredFields
) {
declaredField.setAccessible(true);
TabelFiled tabelFiled = declaredField.getAnnotation(TabelFiled.class);
if (tabelFiled==null){
TableId tableId = declaredField.getAnnotation(TableId.class);
if(tableId!=null){
declaredField.set(o,rs.getObject(tableId.value()));
}else {
declaredField.set(o,rs.getObject(declaredField.getName()));
}
}else {
declaredField.set(o, rs.getObject(tabelFiled.value()));
}
}
list.add((T) o);
}
return list;
}
/*根据id查询*/
public Student findOneById(Object id) throws Exception {
Student student = null;
StringBuffer sql = new StringBuffer("select * from ");
//获取表名
TabelName tabelNameAnnotation = clazz.getAnnotation(TabelName.class);
String tabelname = "";
/*判断是否存在该注解*/
if (tabelNameAnnotation != null) {
tabelname = tabelNameAnnotation.value();
} else {
tabelname = clazz.getSimpleName();
}
//追加表名
sql.append(tabelname+" where ");
System.out.println(sql);
//获取该反射类对象中所有的属性对象
Field[] declaredFields = clazz.getDeclaredFields();
boolean flag = false;
for (Field declaredFiled:declaredFields
) {
TableId tableId = declaredFiled.getAnnotation(TableId.class);
if (tableId!=null){
sql.append(tableId.value()+"='"+id+"'");
flag=true;
break;
}
}
if (flag==false){
throw new RuntimeException("没有添加主键注解");
}
System.out.println(sql);
List<T> list = find(sql.toString());
if (list!=null&&list.size()==1){
return (Student) list.get(0);
}
return null;
}
//查询所有
public List<T> findAll() throws Exception{
StringBuffer sql = new StringBuffer("select * from ");
//获取表名
TabelName tabelNameAnnotation = clazz.getAnnotation(TabelName.class);
String tabelname = "";
/*判断是否存在该注解*/
if (tabelNameAnnotation != null) {
tabelname = tabelNameAnnotation.value();
} else {
tabelname = clazz.getSimpleName();
}
//追加表名
sql.append(tabelname);
System.out.println(sql);
return find(sql.toString());
}
//删除
public int delete(Object id){
try {
StringBuffer sql = new StringBuffer("delete from ");
//获取表名
TabelName tabelNameAnnotation = clazz.getAnnotation(TabelName.class);
String tabelname = "";
/*判断是否存在该注解*/
if (tabelNameAnnotation != null) {
tabelname = tabelNameAnnotation.value();
} else {
tabelname = clazz.getSimpleName();
}
//追加表名
sql.append(tabelname+" where ");
System.out.println(sql);
//获取该反射类对象中所有的属性对象
Field[] declaredFields = clazz.getDeclaredFields();
boolean flag = false;
for (Field declaredFiled:declaredFields
) {
TableId tableId = declaredFiled.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 con = DBUtils.getCon();
//获取sql语句对象
PreparedStatement ps = con.prepareStatement(sql.toString());
//执行sql语句
int i = ps.executeUpdate();
return i;
}catch (Exception e){
e.printStackTrace();
}
return 0;
}
//增加
public int insert(T t) {
try {
//Sql:insert into 表名 values(?,?,?......)
StringBuffer stringBuffer = new StringBuffer("insert into ");
//获取表名
Class<?> aClass = t.getClass();
TabelName tabelNameAnnotation = aClass.getAnnotation(TabelName.class);
String tabelname = "";
/*判断是否存在该注解*/
if (tabelNameAnnotation != null) {
tabelname = tabelNameAnnotation.value();
} else {
tabelname = aClass.getSimpleName();
}
//追加表名
stringBuffer.append(tabelname);
//获取该反射类对象中所有的属性对象
Field[] declaredFields = aClass.getDeclaredFields();
//创建两个集合
List<String> columns = new ArrayList<String>();//存放所有的列名
List<String> values = new ArrayList<String>();//存放所有的列值
for (Field field : declaredFields
) {
field.setAccessible(true);
//获取所有的列名
TabelFiled tabelFiled = field.getAnnotation(TabelFiled.class);
if (tabelFiled != null) {
columns.add(tabelFiled.value());
} else {
columns.add(field.getName());
}
//获取所有的列值
values.add("'" + field.get(t) + "'");
}
stringBuffer.append(columns.toString().replace("[", "(").replace("]", ")"));
stringBuffer.append(" values ");
stringBuffer.append(values.toString().replace("[", "(").replace("]", ")"));
System.out.println(stringBuffer);
//获取连接对象
Connection con = DBUtils.getCon();
//获取sql语句对象
PreparedStatement ps = con.prepareStatement(stringBuffer.toString());
//执行sql语句
int i = ps.executeUpdate();
return i;
}catch (Exception e){
e.printStackTrace();
}finally {
}
return 0;
}
/*修改01*/
public int update(T t){
try {
//update 表名 set 列名 = ? where id=?
StringBuffer stringBuffer = new StringBuffer("update ");
/*获取反射对象*/
Class<?> aClass = t.getClass();
TabelName tabelNameAnnotation = aClass.getAnnotation(TabelName.class);
String tablename = "";
if (tabelNameAnnotation != null) {
tablename = tabelNameAnnotation.value();
} else {
tablename = aClass.getSimpleName();
}
stringBuffer.append(tablename + " set ");
Field[] declaredFields = aClass.getDeclaredFields();
List<String> columns = new ArrayList<String>();
List<String> values = new ArrayList<String>();
for (Field field : declaredFields
) {
field.setAccessible(true);
TabelFiled tabelFiled = field.getAnnotation(TabelFiled.class);
if (tabelFiled != null) {
columns.add(tabelFiled.value());
} else {
columns.add(field.getName());
}
values.add("'" + field.get(t) + "'");
}
String remove = columns.remove(0);
String remove01 = values.remove(0);
System.out.println(remove + " " + remove01);
Object[] columnsArray = columns.toArray();
Object[] valuesArray = values.toArray();
for (int i = 0; i < columnsArray.length; i++) {
for (int j = 0; j < valuesArray.length; j++) {
if (i == j) {
stringBuffer.append(columnsArray[i] + "=" + valuesArray[j] + ",");
}
}
}
stringBuffer = new StringBuffer(stringBuffer.substring(0, stringBuffer.length() - 1) + " where " + remove + "=" + remove01);
System.out.println(stringBuffer);
Connection con = DBUtils.getCon();
PreparedStatement ps= con.prepareStatement(stringBuffer.toString());
int i = ps.executeUpdate();
return i;
}catch (Exception e){
e.printStackTrace();
}finally {
}
return 0;
}
/*修改02*/
public int updateById(T t){
try {
//修改--update 表名 set 列名=值,列名=值... where 主键=值;
StringBuffer sql = new StringBuffer("update ");
/*获取表名*/
Class<?> aClass = t.getClass();
TabelName tabelNameAnnotation = aClass.getAnnotation(TabelName.class);
String tableName = "";
if (tabelNameAnnotation != null) {
tableName = tabelNameAnnotation.value();
} else {
tableName = aClass.getSimpleName();
}
sql.append(tableName + " set ");
System.out.println(sql);
/*获取列值*/
String columnValue = "";
String where = " where ";
Field[] declaredFields = aClass.getDeclaredFields();
boolean flag = false;
for (Field field : declaredFields
) {
field.setAccessible(true);
TabelFiled tabelFiledAnnotation = field.getAnnotation(TabelFiled.class);
if (tabelFiledAnnotation != null) {
columnValue += tabelFiledAnnotation.value() + "='" + field.get(t) + "', ";
} else {
TableId tableIdAnnotation = field.getAnnotation(TableId.class);
if (tableIdAnnotation!=null){
flag = true;
where +=tableIdAnnotation.value()+"='"+field.get(t)+"'";
}else {
columnValue+= field.getName()+ "='" + field.get(t) + "',";
}
}
}
if (flag==false){
throw new RuntimeException("没有添加主键注解");
}
//去除最后一个问号
columnValue=columnValue.substring(0,columnValue.lastIndexOf(","));
sql.append(columnValue).append(where);
System.out.println(sql );
Connection con = DBUtils.getCon();
PreparedStatement ps= con.prepareStatement(sql.toString());
int i = ps.executeUpdate();
return i;
}catch (Exception e){
e.printStackTrace();
}
return 0;
}
}
entity包:实体类Student
package com.qy151.entity;
import com.qy151.annotation.TabelFiled;
import com.qy151.annotation.TabelName;
import com.qy151.annotation.TableId;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @unthor : YSH
* @date : 20:34 2022/7/14
*/
@Data
/*@NoArgsConstructor
@AllArgsConstructor*/
@TabelName(value = "t_student")
public class Student {
/*private Integer id;*/
@TabelFiled(value = "name")
private String studentname;
private String address;
//表示该列是主键列
@TableId(value = "id")
private Integer sid;
}
dao包:操作类
package com.qy151.dao;
import com.qy151.entity.Student;
import com.qy151.util.BaseDao;
/**
* @unthor : YSH
* @date : 20:49 2022/7/14
*/
public class StudentDao extends BaseDao<Student> {
}
Test:测试类
import com.qy151.dao.StudentDao;
import com.qy151.dao.UserDao;
import com.qy151.entity.Student;
import com.qy151.entity.User;
import org.junit.Test;
/**
* @unthor : YSH
* @date : 20:49 2022/7/14
*/
public class StudentTest {
StudentDao studentDao = new StudentDao();
@Test
public void insert(){
Student student = new Student();
student.setSid(20);
student.setStudentname("周六");
student.setAddress("北京");
studentDao.insert(student);
}
@Test
public void update() {
Student student = new Student();
student.setSid(20);
student.setStudentname("张三");
student.setAddress("金星");
studentDao.update(student);
}
@Test
public void updateById() {
Student student = new Student();
student.setSid(20);
student.setStudentname("张三");
student.setAddress("水星");
studentDao.updateById(student);
}
@Test
public void delete(){
Student student = new Student();
studentDao.delete(20);
}
@Test
public void findAll() throws Exception {
Student student = new Student();
System.out.println(studentDao.findAll());
}
@Test
public void findOneById() throws Exception {
Student student = new Student();
System.out.println(studentDao.findOneById(10));
}
}
IDEA将项目打包成jar包
IDEA将项目打包成jar包
https://blog.csdn.net/weixin_61634823/article/details/124827963
包含项目中使用的依赖
打包的jar包中Lombok包不能使用,报错
解决方法:
开启idea注解处理
边栏推荐
- The bear market is slow, and bit.store provides stable stacking products to help you get through the bull and bear market
- Laravel service container (Application of context binding)
- 裸金属云FASS高性能弹性块存储解决方案
- 剑指核心-TaoCloud全闪SDS助力构建高性能云服务
- Strategic cooperation with many institutions shows the strength of the leading company of platofarm yuancosmos
- PHP如何生成二维码?
- DeFi 2.0的LaaS协议,重振DeFi赛道发展的关键
- Detailed steps of JDBC connection to database
- xtrabackup 的使用
- Windows下cmd窗口连接mysql并操作表
猜你喜欢
超简单集成HMS ML Kit 人脸检测实现可爱贴纸
华为2020校招笔试编程题 看这篇就够了(上)
DAY15:文件包含漏洞靶场手册(自用 file-include 靶场)
DAY13:文件上传漏洞
Refresh, swagger UI theme changes
大部分PHP程序员,都搞不懂如何安全代码部署
Performance comparison | FASS iSCSI vs nvme/tcp
Sliding switch of tab of uniapp component
Fantom (FTM) 在 FOMC会议之前飙升 45%
Day14: upload labs customs clearance tutorial
随机推荐
The Platonic metauniverse advocated by musk has long been verified by platofarm
Starfish OS: create a new paradigm of the meta universe with reality as the link
Fantom (FTM) surged 45% before the FOMC meeting
“山东大学移动互联网开发技术教学网站建设”项目实训日志一
大部分PHP程序员,都搞不懂如何安全代码部署
Countdown of the uniapp component (such as the countdown to reading the agreement and the countdown to completing learning)
DAY15(DAY16拓展):文件包含漏洞
Laravel Swagger添加访问密码
识变!应变!求变!
QPalette学习笔记
Okaleido Tiger 7.27日登录Binance NFT,首轮已获不俗成绩
The bear market is slow, and bit.store provides stable stacking products to help you get through the bull and bear market
win10+opencv3.2+vs2015配置
Sports health is deeply rooted in the hearts of the people, and move protocol leads quality life
What is wapiti and how to use it
Strategic cooperation with many institutions shows the strength of the leading company of platofarm yuancosmos
Power BI Report Server 自定义身份验证
From starfish OS' continued deflationary consumption of SFO, the value of SFO in the long run
改哭了,终于解决了Cannot read properties of undefined (reading ‘parseComponent‘)
PHP如何生成二维码?