1. 什么是反射?
反射是框架设计的灵魂,框架:它是一个半成品,可以拿来使用,添加上自己的业务代码。提高开发效率。
反射就是把类中成员抽取成其他类的过程。这就是反射。

2. 如何获取反射类Class
(1) 通过Class.forName获取反射对象.
Class.forName("全路径") --spring它就是使用的该模式<bean class="全路径">
(2)通过类名.class获取
类名.class; ---代理类--->SqlSession.getMapper(StudentDao.class)
(3) 通过对象.getClass()方法获取
对象.getClass();
---当知道对象时可以通过这种方式获取反射对象
public class Test01 {
public static void main(String[] args) throws ClassNotFoundException {
//1.通过Class.forName来获取反射类对象。
Class aClass = Class.forName("demo.People");
//2.通过类名调用.class获取反射类对象
Class aClass1 = People.class;
//3.通过对象获取反射类对象
People p=new People();
Class aClass2 = p.getClass();
//思考:上面三个反射对象的引用地址是否一致! 是一致的。 一个类只会被加在到内存中一次。
System.out.println(aClass==aClass1);
System.out.println(aClass2==aClass1);
}
}
3. 根据反射类获取对应的类对象。
public class Test02 {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
//1.获取反射类对象
Class<People> aClass = People.class;
//2.由反射类创建类对象---调用为无参构造函数
People people = aClass.newInstance();
People people2 = aClass.newInstance();
//3.他们的地址是否相同
System.out.println(people==people2);
}
}
4. 通过反射获取对应的Field属性对象
aclass.newInstance();
public class Test {
public static void main(String[] args) throws Exception {
Class<?> aClass = Class.forName("demo.People");
//获取本类中指定的属性对象
Field name = aClass.getDeclaredField("name");
System.out.println(name);
//获取本类以及父类中指定的属性---必须为public修饰的。
Field name1 = aClass.getField("sex");
System.out.println(name1);
//获取本类中所有的属性对象
Field[] declaredFields = aClass.getDeclaredFields();
for (Field field:declaredFields) {
System.out.println(field);
}
//获取本类以及父类中所有public修饰的属性对象
Field[] fields = aClass.getFields();
for (Field field:
fields) {
System.out.println(field);
}
}
}
4.1 Field属性对象中常见的方法。
getName():获取属性名
setAccessible(true):设置属性可访问。
set(o,v):为对象o的属性赋值v
get(o):获取对象o的属性值
public static void main(String[] args) throws Exception {
Class<People> peopleClass = People.class;
Field nameField = peopleClass.getDeclaredField("name");
//1.获取属性的名称
String name = nameField.getName();
System.out.println("属性名称:"+name);
//2.为属性赋值.
//Object obj,对象
// Object value
People people = peopleClass.newInstance();
System.out.println(people);
nameField.setAccessible(true);//为nameField设置可访问权限,打破了封装性
nameField.set(people,"张三");
System.out.println(people);
//3.获取属性值
Object o = nameField.get(people);
System.out.println(o);
//nameField.getAnnotation();//获取nameField属性上的注解对象
}
5. 通过反射获取对应的Method方法对象
public class Test03 {
public static void main(String[] args) throws Exception {
Class<People> aClass = People.class;
//获取本类中所有的方法。
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method method:declaredMethods) {
System.out.println(method);
}
System.out.println("======================================================");
//获取本类和父类中所有public修饰的方法
Method[] methods = aClass.getMethods();
for (Method method : methods) {
System.out.println(method);
}
System.out.println("**************************************************************");
//本类中指定的 方法对象
Method fun = aClass.getDeclaredMethod("fun");
System.out.println(fun);
Method setName = aClass.getDeclaredMethod("setName",String.class);
System.out.println(setName);
//获取本类以及父类中指定名称的方法对象
Method equals = aClass.getMethod("equals", Object.class);
System.out.println(equals);
}
}
5.1Method类中常见的方法
//method.invoke(对象,方法参数值);
invoke(people,"15");//回调。动态代理
6. 如何获取对应的Annotation注解对象
public class Test {
public static void main(String[] args) throws Exception{
Class<Student> aClass = Student.class;
//获取类对象的指定注解
MyAnnotation annotation = aClass.getAnnotation(MyAnnotation.class);
System.out.println(annotation.value());
Field idField = aClass.getDeclaredField("id");
MyAnnotation annotation1 = idField.getAnnotation(MyAnnotation.class);
System.out.println(annotation1.value());
System.out.println(annotation1.sex());
}
}
7. 手撕ORM框架
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zjh</groupId>
<artifactId>ORM0714</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
</dependencies>
</project>
entity
package com.zjh.entity;
import com.zjh.annotation.TableField;
import com.zjh.annotation.TableId;
import com.zjh.annotation.TableName;
import lombok.Data;
import java.lang.annotation.Target;
/**
* @author: jh
* @create: 2022/7/14
*/
@Data
@TableName(value = "user")
public class User {
@TableId
private Integer id;
@TableField("userName")
private String username;
private String password;
}
UserDao
package com.zjh.dao;
import com.zjh.entity.User;
import com.zjh.util.BaseDao;
/**
* @author: jh
* @create: 2022/7/14
*/
public class UserDao extends BaseDao<User> {
}
自定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableId {
String value() default "id";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TableName {
String value();/*表名*/
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableField {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface TablePromaryKey {
String value();
}
DButils
package com.zjh.util;
import java.sql.*;
/**
* @author: jh
* @create: 2022/7/14
*/
public class DBUtils {
private static String driverName="com.mysql.cj.jdbc.Driver";
private static String url="jdbc:mysql://localhost:3306/mydb?severTimezone=Asia/Shanghai";
private static String username="root";
private static String password="123456";
public static Connection getConn() throws Exception{
Class.forName(driverName);
Connection connection = DriverManager.getConnection(url,username,password);
return connection;
}
public static void closeAll(ResultSet rs, PreparedStatement ps,Connection connection) {
try {
if (rs!=null){
rs.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
package com.zjh.util;
import com.zjh.annotation.TableField;
import com.zjh.annotation.TableId;
import com.zjh.annotation.TableName;
import com.zjh.annotation.TablePromaryKey;
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;
/**
* @author: jh
* @create: 2022/7/14
*/
public class BaseDao<T>{
private Class<?> clazz;
public BaseDao(){
Class<? extends BaseDao> aClass = this.getClass();
ParameterizedType genericSuperclass = (ParameterizedType) aClass.getGenericSuperclass();
Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
clazz= (Class<?>) actualTypeArguments[0];
}
/*查询单个*/
public T selectById(Object id) throws Exception {
StringBuffer sql = new StringBuffer("select * from ");
//获取表名
TableName tableNameAnnotation = clazz.getAnnotation(TableName.class);
String tableName = "";
//是否存在该注解
if (tableNameAnnotation != null) {
tableName = tableNameAnnotation.value();
} else {
tableName = clazz.getSimpleName();
}
sql.append(tableName + " where ");
Field[] declaredFields = clazz.getDeclaredFields();
boolean f=false;
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
TableId tableId = declaredField.getAnnotation(TableId.class);
if(tableId!=null){
sql.append(tableId.value()+"='"+id+"'");
f=true;
break;
}
}
if(f==false){
throw new RuntimeException("没有添加主键注解");
}
Connection conn = DBUtils.getConn();
PreparedStatement ps = conn.prepareStatement(sql.toString());
ResultSet rs = ps.executeQuery();
Object o = clazz.newInstance();
while (rs.next()){
Field[] declaredFields1 = clazz.getDeclaredFields();
for (Field declaredField : declaredFields1){
declaredField.setAccessible(true);
TableField tableField = declaredField.getAnnotation(TableField.class);
if (tableField == null){
declaredField.set(o,rs.getObject(declaredField.getName()));
}else {
declaredField.set(o,rs.getObject(tableField.value()));
}
}
}
return (T) o;
}
/*查询所有*/
public List<T> findAll() throws Exception{
List<T> list = new ArrayList<T>();
StringBuffer sql=new StringBuffer("select * from ");
//获取表名
TableName tableNameAnnotation = clazz.getAnnotation(TableName.class);
String tableName = "";
//是否存在该注解
if (tableNameAnnotation != null) {
tableName = tableNameAnnotation.value();
} else {
tableName = clazz.getSimpleName();
}
sql.append(tableName);
Connection conn = DBUtils.getConn();
PreparedStatement ps = conn.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);
TableField tableField = declaredField.getAnnotation(TableField.class);
if (tableField == null){
TablePromaryKey tablePromaryKey = declaredField.getAnnotation(TablePromaryKey.class);
if (tablePromaryKey!=null){
declaredField.set(o,rs.getObject(tablePromaryKey.value()));
}else {
declaredField.set(o,rs.getObject(declaredField.getName()));
}
}else {
declaredField.set(o,rs.getObject(tableField.value()));
}
}
list.add((T) o);
}
return list;
}
//delete from 表名 where 主键=主键值
public int deleteById(Object id) throws Exception {
StringBuffer sql = new StringBuffer("delete from ");
//获取表名
TableName tableNameAnnotation = clazz.getAnnotation(TableName.class);
String tableName = "";
//是否存在该注解
if (tableNameAnnotation != null) {
tableName = tableNameAnnotation.value();
} else {
tableName = clazz.getSimpleName();
}
sql.append(tableName+" where ");
Field[] declaredFields = clazz.getDeclaredFields();
boolean flag=false;
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
TableId tableId = declaredField.getAnnotation(TableId.class);
if(tableId!=null){
sql.append(tableId.value()+"='"+id+"'");
flag=true;
break;
}
}
if(flag==false){
throw new RuntimeException("没有添加主键注解");
}
Connection conn = DBUtils.getConn();
PreparedStatement ps = conn.prepareStatement(sql.toString());
int i = ps.executeUpdate();
return i;
}
/*修改*/
//修改--update 表名 set 列名=值,列名=值.... where 主键=值;
//只能根据注解修改
public int updateById(T t) throws Exception{
StringBuffer sql=new StringBuffer("update ");
//获取表名
Class<?> aClass = t.getClass();
TableName tableNameAnnotation = aClass.getAnnotation(TableName.class);
String tableName = "";
//是否存在该注解
if (tableNameAnnotation != null) {
tableName = tableNameAnnotation.value();
} else {
tableName = aClass.getSimpleName();
}
sql.append(tableName+" set ");
String columnValue="";
String where =" where ";
//获取所有得属性对象。
Field[] declaredFields = aClass.getDeclaredFields();
boolean flag=false;
for(Field field:declaredFields){
field.setAccessible(true);
TableField fieldAnnotation = field.getAnnotation(TableField.class);
if(fieldAnnotation!=null){
columnValue+=fieldAnnotation.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 conn = DBUtils.getConn();
PreparedStatement ps = conn.prepareStatement(sql.toString());
int i = ps.executeUpdate();
return i;
}
/*增加*/
public int insert(T t){
try {
StringBuffer sb = new StringBuffer("insert into ");
/*获取表名*/
Class<?> aClass = t.getClass();
TableName tableNameAnnotation = aClass.getAnnotation(TableName.class);
String tableName = "";
if (tableNameAnnotation != null) {
tableName = tableNameAnnotation.value();
} else {
tableName = aClass.getSimpleName();
}
sb.append(tableName);
/*获取反射类对象中所有的属性对象*/
Field[] declaredFields = aClass.getDeclaredFields();
/*创建两个集合*/
List<String> columns = new ArrayList<String>();/*存放所有的列名*/
List<String> values = new ArrayList<String>();/*存放所有的列值*/
for (Field declaredField : declaredFields) {
declaredField.setAccessible(true);
TableField tableField = declaredField.getAnnotation(TableField.class);
if (tableField != null) {
columns.add(tableField.value());
} else {
columns.add(declaredField.getName());
}
values.add("'" + declaredField.get(t) + "'");
}
sb.append(columns.toString().replace("[", "(").replace("]", ")"));
sb.append(" values ");
sb.append(values.toString().replace("[", "(").replace("]", ")"));
/*获取连接对象*/
Connection conn = DBUtils.getConn();
PreparedStatement ps = conn.prepareStatement(sb.toString());
int i = ps.executeUpdate();
return i;
}catch(Exception e){
e.printStackTrace();
}finally{
}
return 0;
}
}
测试
package com.zjh;
import com.zjh.dao.UserDao;
import com.zjh.entity.User;
import java.util.List;
/**
* @author: jh
* @create: 2022/7/14
*/
public class Test {
public static void main(String[] args) throws Exception{
UserDao userDao = new UserDao();
User user = new User();
/*user.setId(19);
user.setUsername("赵六");
user.setPassword("12345");
userDao.insert(user);*/
/*user.setId(19);
user.setUsername("李四");
user.setPassword("123456");
userDao.updateById(user);*/
/*userDao.deleteById(19);*/
/*List<User> list = userDao.findAll();
System.out.println(list);*/
User user1 = userDao.selectById(1);
System.out.println(user1);
}
}