完成一个ORM框架---目标: 能够理解反射泛型注解应用。
要求:JDBC+反射+泛型+注解+maven。
1 创建一个工程Maven.
2 引用依赖。
<?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.am</groupId>
<artifactId>orm</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.4</version>
</dependency>
</dependencies>
</project>
3 创建一个连接数据库的工具类
db.properties
package com.am.util;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
/**
* @program: orm
* @description:
* @author: 阿木
* @create: 2022-02-12 08:49
**/
public class ConnectionUtil {
private static DataSource dataSource;//声明一个连接池对象
static{ //静态代码块。随着类的加载而被加载到JVM内存 而且只会被加载一次。
try {
InputStream inputStream = ConnectionUtil.class.getClassLoader()
.getResourceAsStream("db.properties");
Properties properties = new Properties(); //读取属性文件内容。
properties.load(inputStream);
dataSource = DruidDataSourceFactory.createDataSource(properties);//通过Druid的工厂类对象创建数据源对象
}catch (Exception e){
e.printStackTrace();
}
}
//从连接池中获取连接对象。
public static Connection getConnection() throws Exception{
Connection connection = dataSource.getConnection();
return connection;
}
//关闭连接对象。
public static void close(ResultSet rs, PreparedStatement ps,Connection connection){
try {
if(rs!=null){
rs.close();
}
if(ps!=null){
ps.close();
}
if(connection!=null){
connection.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
4 创建一个公共的父类。
4.1 添加功能
//添加操作。
public int insert(T t) {
try {
//sql="insert into 表名 values('值1','值2'....)";
StringBuffer sql = new StringBuffer("insert into ");
//获取实体类的反射类对象
Class<?> aClass = t.getClass();
//获取类上指定的注解类对象。
Table table = aClass.getAnnotation(Table.class);
//如何获取表名。
String tableName = table.value();
sql.append(tableName + " values ");
//获取t中相应的值。new Product(11,"已发送",25.5,300)
Field[] fields = aClass.getDeclaredFields();
List<Object> values = new ArrayList<Object>();
for (Field f : fields) {
f.setAccessible(true);
values.add("'" + f.get(t) + "'");
}
String replace = values.toString().replace("[", "(").replace("]", ")");
sql.append(replace);
System.out.println(sql);
//执行sql语句。
connection = ConnectionUtil.getConnection();
ps = connection.prepareStatement(sql.toString());
int row = ps.executeUpdate();
return row;
}catch (Exception e){
e.printStackTrace();
}finally {
ConnectionUtil.close(rs,ps,connection);
}
return 0;
}
4.2 修改
//修改。
public int update(T t) {
try {
//sql: update 表名 set 列名='值',列名=值.... where 主键=值;
StringBuffer sql=new StringBuffer("update ");
//获取反射类
Class<?> aClass = t.getClass();
//获取表名
String tableName = aClass.getAnnotation(Table.class).value();
sql.append(tableName+" set ");
//获取所有的属性对象。
Field[] fields = aClass.getDeclaredFields();
String set="";
String where=" where ";
for (Field f:fields){
f.setAccessible(true);
TableId tableId = f.getAnnotation(TableId.class);
if(tableId==null){ //不是主键
set+=f.getName()+"='"+f.get(t)+"',";
}else{
if(tableId.value().equals("")){
where+=f.getName()+"='"+f.get(t)+"'";
}else{
where+=tableId.value()+"='"+f.get(t)+"'";
}
}
}
sql.append(set.substring(0,set.lastIndexOf(","))).append(where);
//执行sql
connection=ConnectionUtil.getConnection();
ps=connection.prepareStatement(sql.toString());
int row = ps.executeUpdate();
return row;
} catch (Exception e) {
e.printStackTrace();
}finally {
ConnectionUtil.close(rs,ps,connection);
}
return 0;
}
4.3 删除
//删除 sql delete from 表名 where 主键=id
public int delete(Object id) {
try {
StringBuffer sql = new StringBuffer("delete from ");
String tableName = aClass.getAnnotation(Table.class).value();
sql.append(tableName + " where ");
//获取所有的属性对象
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
TableId tableId = field.getAnnotation(TableId.class);
if (tableId != null) {
String value = tableId.value();
if (value.equals("")) {
sql.append(field.getName() + "='" + id + "'");
} else {
sql.append(tableId.value() + "='" + id + "'");
}
}
}
//执行sql
connection = ConnectionUtil.getConnection();
ps = connection.prepareStatement(sql.toString());
int row = ps.executeUpdate();
return row;
} catch (Exception e) {
e.printStackTrace();
} finally {
ConnectionUtil.close(rs, ps, connection);
}
return 0;
}
4.4 查询所有
//查询所有 select * from 表名 where 主键=值
public List<T> findAll() {
List<T> list=new ArrayList<T>();
try {
StringBuffer sql = new StringBuffer("select * from ");
String tableName = aClass.getAnnotation(Table.class).value();
sql.append(tableName);
connection=ConnectionUtil.getConnection();
ps=connection.prepareStatement(sql.toString());
rs=ps.executeQuery();
while(rs.next()){
T o = (T)aClass.newInstance();
Field[] fields = aClass.getDeclaredFields();
for (Field f:fields){
f.setAccessible(true);
TableId tableId = f.getAnnotation(TableId.class);
if(tableId==null){
f.set(o,rs.getObject(f.getName()));
}else{
String value = tableId.value();
if(value.equals("")){
f.set(o,rs.getObject(f.getName()));
}else{
f.set(o,rs.getObject(value));
}
}
}
list.add(o);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ConnectionUtil.close(rs,ps,connection);
}
return list;
}