简单版手写ORM框架 项目结构
1.引入jar包 <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.27</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.7</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies>
AnMyTableFieldId 注解
//标记主键使用的
//在属性名上使用
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnMyTableFieldId {
String value();
}
AnMyTableFiled
//标记不同的字段名
public @interface AnMyTableFiled {
String value();
}
AnMyTableName
//自定义注解
//只能在类上使用
@Target(ElementType.TYPE)
//运行时注解还在作用范围内
@Retention(RetentionPolicy.RUNTIME)
public @interface AnMyTableName {
String value();
}
AccountDao
public class AccountDao extends BaseDao<Account> {
}
Account
@AnMyTableName("account")
public class Account {
@AnMyTableFieldId("username")
private String username;
@AnMyTableFiled("balance")
private Integer balance;
@Override
public String toString() {
return "Account{" +
"username='" + username + '\'' +
", balance=" + balance +
'}';
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getBalance() {
return balance;
}
public void setBalance(Integer balance) {
this.balance = balance;
}
}
DbUtil
package com.ccr.util;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
@SuppressWarnings("all")
public class DbUtil {
// 声明数据源对象
private static DataSource dataSource;
static {
try {
InputStream inputStream = DbUtil.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
// 读取配置文件
properties.load(inputStream);
// 根据配置文件中的内容为datasourcse配置
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
// 获取连接池对象
public static Connection getConn(){
// 连接池中获取连接对象
try {
Connection connection = dataSource.getConnection();
return connection;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
// 关闭资源
public static void close(ResultSet r, PreparedStatement ps, Connection c) {
if (r != null) {
try {
r.close();
if (ps != null) {
ps.close();
}
if (c != null) {
c.close();
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
BaseDao
package com.ccr.util;
import com.ccr.annotation.AnMyTableFieldId;
import com.ccr.annotation.AnMyTableFiled;
import com.ccr.annotation.AnMyTableName;
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.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
//表加数据
public class BaseDao<T> {
public PreparedStatement ps;
public Connection conn;
public ResultSet rs;
private Class<?> aClass;
public BaseDao() {
// 当前对象的直接超类的Type
//获取子类Dao的反射类对象
Class<? extends BaseDao> aClazz = this.getClass();
// 获取子类对象以及子类对象泛型
ParameterizedType genericSuperclass = (ParameterizedType) aClazz.getGenericSuperclass();
// 获取子类中的泛型对象
Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
// 获取反射对象
aClass = (Class<?>) actualTypeArguments[0];
// System.out.println(aClass);
}
// 查询所有
public List<T> findAll() {
// 查询的方法是以一个数组
List<T> list = new ArrayList<T>();
StringBuffer sql = new StringBuffer("select * from ");
// 获取表名
String tableName = aClass.getAnnotation(AnMyTableName.class).value();
// sql添加表名
sql.append(tableName);
// 执行sql语句
try {
// 连接数据库
conn = DbUtil.getConn();
ps = conn.prepareStatement(sql.toString());
rs = ps.executeQuery();
// 获取到所有字段名
while (rs.next()){
// 创建实体类对象
Object o = aClass.newInstance();
//获取属性名
Field[] declaredFields = aClass.getDeclaredFields();
for (Field f: declaredFields) {
// 设置属性课件性
f.setAccessible(true);
// 循环获取到表中的属性,但是不严谨,实体类中数据可能和数据组数据不对照
// f.set(o,rs.getObject(f.getName()));
AnMyTableFieldId annotationid = f.getAnnotation(AnMyTableFieldId.class);
//
if (annotationid!=null){
f.set(o,rs.getObject(annotationid.value()));
}
AnMyTableFiled annotationname = f.getAnnotation(AnMyTableFiled.class);
if (annotationname!=null){
f.set(o,rs.getObject(annotationname.value()));
}else {
f.set(o,rs.getObject(f.getName()));
}
}
list.add((T) o);
}
} catch (Exception throwables) {
throwables.printStackTrace();
} finally {
DbUtil.close(null, ps, conn);
}
return list;
}
// 根据id查询
public T findById(Object id){
StringBuffer sql = new StringBuffer("select * from ");
// 获取表名
String tableName = aClass.getAnnotation(AnMyTableName.class).value();
sql.append(tableName+" where ");
// 获取主键id
// 先获取所有
Field[] declaredFields = aClass.getDeclaredFields();
for (Field f: declaredFields){
AnMyTableFieldId annotationid = f.getAnnotation(AnMyTableFieldId.class);
if (annotationid!=null){
String valueid = annotationid.value();
// 添加到数据中
sql.append(valueid+"='"+id+"'");
break;
}
}
try {
// 连接数据库
conn = DbUtil.getConn();
ps = conn.prepareStatement(sql.toString());
rs = ps.executeQuery();
// 创建实体类对象
Object o = aClass.newInstance();
// 获取到所有字段名
if (rs.next()){
for (Field f: declaredFields) {
// 设置属性课件性
f.setAccessible(true);
// 循环获取到表中的属性,但是不严谨,实体类中数据可能和数据组数据不对照
// f.set(o,rs.getObject(f.getName()));
AnMyTableFieldId annotationid = f.getAnnotation(AnMyTableFieldId.class);
//
if (annotationid!=null){
f.set(o,rs.getObject(annotationid.value()));
}
AnMyTableFiled annotationname = f.getAnnotation(AnMyTableFiled.class);
if (annotationname!=null){
f.set(o,rs.getObject(annotationname.value()));
}else {
f.set(o,rs.getObject(f.getName()));
}
}
return (T) o;
}
} catch (Exception throwables) {
throwables.printStackTrace();
}finally {
DbUtil.close(null, ps, conn);
}
// System.out.println(sql);
return null;
}
//添加功能所有表的添加功能。 insert into 表() values()
public int insert(T t) {
try {
// 声明一个字符串sql语句
StringBuffer sql = new StringBuffer("insert into ");
// 通过泛型获取反射类对象
Class<?> aClass = t.getClass();
// 通过注解得到类名
AnMyTableName anMyTableName = aClass.getAnnotation(AnMyTableName.class);
// 获取表名
String tableName = anMyTableName.value();
// 把获取的表名拼接sql上
sql.append(tableName);
// 声明俩个集合 分别存储列名 列值
// 列值
ArrayList<Object> values = new ArrayList<Object>();
// 列名
ArrayList<String> columns = new ArrayList<String>();
// 获取添加字段列名通过反射类获取
Field[] declaredFields = aClass.getDeclaredFields();
for (Field f : declaredFields) {
//设置当前类属性值为可见性
f.setAccessible(true);
// 判断当前类的属性id是否为空
if (f.getAnnotation(AnMyTableFieldId.class) == null || f.get(t) != null) {
// 当id值等于空时添加
String name = f.getName();
// 通过泛型添加值
Object value = f.get(t);
// 将名字存到定义的类名数组中
columns.add(name);
// 值存到列值中 不确定值是否为字符串列值加上‘’
values.add("'" + value + "'");
}
}
// 获取到列名和列值 数据是 数组形势出现所有要把[]替换()
sql.append(columns.toString().replace("[", "(").replace("]", ")"));
sql.append("values ");
sql.append(values.toString().replace("[", "(").replace("]", ")"));
System.out.println(sql);
// 数据库连接的
conn = DbUtil.getConn();
ps = conn.prepareStatement(sql.toString());
int i = ps.executeUpdate();
return i;
} catch (Exception e) {
DbUtil.close(null, ps, conn);
}
return 0;
}
// 修改 update 表名 set 字段=值 where id=id;
public int update(T t) {
try {
StringBuffer sql = new StringBuffer("update ");
// 1. 获取表名,
Class<?> aClass = t.getClass();
// 通过注解获取数据库中对应到表名
AnMyTableName tableNamean = aClass.getAnnotation(AnMyTableName.class);
String tablename = tableNamean.value();
sql.append(tablename + " set ");
// 获取values值
Field[] declaredFields = aClass.getDeclaredFields();
// 获取条件
String where = " where ";
for (Field f : declaredFields) {
// 设置可见性
f.setAccessible(true);
// 获取到列名中的id 通过判断修改数据
AnMyTableFieldId annotation = f.getAnnotation(AnMyTableFieldId.class);
// 得到数据
String name = f.getName();
Object value = f.get(t);
/*if (annotation.equals("")||annotation!=null)*/
if (annotation == null || annotation.equals("")) {
sql.append(name + "='" + value + "',");
} else {
where += name + "='" + value + "'";
}
}
// 截取掉where前的,号
String s = sql.substring(0, sql.lastIndexOf(",")) + where;
Connection conn = DbUtil.getConn();
ps = conn.prepareStatement(s);
// System.out.println(s);
int i = ps.executeUpdate();
return i;
} catch (Exception e) {
} finally {
DbUtil.close(null, ps, conn);
}
return 0;
}
// 删除 delete from 表名
public int delete(Object id) {
try {
StringBuffer sql = new StringBuffer("delete from ");
// 获取实体类的反射对象 表名
String tableName = aClass.getAnnotation(AnMyTableName.class).value();
sql.append(tableName + " where ");
// 获取主键
Field[] declaredFields = aClass.getDeclaredFields();
// 循环得到id
for (Field f : declaredFields) {
// 设置字段可见性
f.setAccessible(true);
// 获取id值
AnMyTableFieldId annotation = f.getAnnotation(AnMyTableFieldId.class);
// 判断id是否为空删除
if (annotation != null) {
// 获取列名
String vaid = annotation.value();
// 拼接到SQL中
sql.append(vaid + "='" + id + "'");
// 获取到可以停止然后删除
break;
}
}
// 获取数据链接对象
conn = DbUtil.getConn();
ps = conn.prepareStatement(sql.toString());
int i = ps.executeUpdate();
return i;
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DbUtil.close(null, ps, conn);
}
return 0;
}
}
db.properties
# druid.properties文件的配置
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/tranbook?serverTimezone=Asia/Shanghai
username=root
password=root
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大超时时间
maxWait=3000
Test
public class Test01 {
@Test
// 根据id查
public void Test11(){
AccountDao accountDao = new AccountDao();
Account a = accountDao.findById("哈哈哈21");
System.out.println(a);
}
@Test
//添加
public void Test12(){
AccountDao accountDao = new AccountDao();
Account account = new Account();
account.setUsername("哈哈哈");
account.setBalance(12);
int insert = accountDao.insert(account);
System.out.println("添加成功"+insert);
}
@Test
//修改
public void Test13(){
AccountDao accountDao = new AccountDao();
Account account = new Account();
account.setUsername("哈哈哈");
account.setBalance(15);
int update = accountDao.update(account);
System.out.println("修改成功"+update);
}
@Test
// 删除id
public void Test14(){
AccountDao accountDao = new AccountDao();
int a = accountDao.delete("哈哈哈");
System.out.println(a);
}
@Test
// 根据id查
public void Test15(){
AccountDao accountDao = new AccountDao();
List<Account> all = accountDao.findAll();
System.out.println(all);
}
}
|