自制ORM框架
需求技术:
技术栈: (1)java+mysql+反射+自定义注解+泛型+jdbc.
持久层框架: 与数据库交互的一层称为持久层(dao)。完成orm操作。
o:(Object对象) r:(relative关系) m:(mapping映射)。
实体类-数据库表 属性-表的字段 实体类对象-一条记录 集合-表中多条记录。
手撕持久层框架:
编写无需写sql语句即可完成对单表的CRUD操作。
1.创建MavenJava工程并引入依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
</dependencies>
2.创建数据源的属性文件.properties
#配置数据源信息
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username=root
password=root
3.创建DbUtil工具类
package com.gzx.util;
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;
public class DbUtil {
private static DataSource ds = null;
static {
try {
// 创建一个属性对象
Properties prop = new Properties();
// 读取db.properties配置文件
InputStream in = DbUtil.class.getClassLoader().getResourceAsStream("db.properties");
prop.load(in);
// 获取连接池对象
ds = DruidDataSourceFactory.createDataSource(prop);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 获取连接对象
public static Connection getConn(Connection conn) throws SQLException {
conn = ds.getConnection();
return conn;
}
// 关闭资源
public static void closeAll(Connection conn,PreparedStatement ps,ResultSet rs){
if (rs != null) {
try {
rs.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
增删查改BaseDao:
package com.gzx.dao;
import com.gzx.annotation.ListAnnotation;
import com.gzx.annotation.TableAnnotation;
import com.gzx.util.DbUtil;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class BaseDao<T> extends DbUtil {
Connection connection;
PreparedStatement ps;
ResultSet rs;
// 添加sql----------------------------------------
public int insert(T t){
try {
// 创建添加sql语句
StringBuffer sql = new StringBuffer("insert into ");
// 获取反射类
Class<T> aClass = (Class<T>) t.getClass();
// 通过反射类获取注释
TableAnnotation annotation = aClass.getAnnotation(TableAnnotation.class);
// 添加表名: 判断是否拥有注释 如果没有添加类名
sql.append(annotation != null && !Objects.equals(annotation.value(), "") ? annotation.value() : aClass.getSimpleName());
// 创建列名列表
List<String> list = new ArrayList<>();
// 创建列值
List l = new ArrayList();
// 循环赋值list列表列名和值
for (Field field : aClass.getDeclaredFields()) {
// 获取成员变量的注释
ListAnnotation la = field.getAnnotation(ListAnnotation.class);
// 改变私有变量访问权限
field.setAccessible(true);
// 赋值列名 判断是否拥有表名注释 有则加注释名 无则加变量名
list.add(la != null && !Objects.equals(la.value(), "") ? la.value() : field.getName());
// 赋值 判断是否为null 是则直接添加 无则添加''
l.add(field.get(t)!=null ? "'"+field.get(t)+"'" : field.get(t));
}
// 转换[]为()并添加sql语句中并添加values字段
sql.append(list.toString().replace("[", "(").replace("]", ")")+(" values "));
// 转换[]为()并添加sql语句中
sql.append(l.toString().replace("[", "(").replace("]", ")"));
// 输出sql
System.out.println(sql);
// 连接对象
connection = DbUtil.getConn(connection);
// 传入sql
ps = connection.prepareStatement(sql.toString());
// 获取返值
int i = ps.executeUpdate();
return i;
} catch (Exception e) {
System.out.println("BaseDao insert error出现错误!!");
e.printStackTrace();
} finally {
closeAll(connection,ps,rs);
}
return 0;
}
// 修改sql----------------------------------------
public int update(T t){
try {
StringBuffer sql = new StringBuffer("update ");
Class<?> aClass = t.getClass();
TableAnnotation annotation = aClass.getAnnotation(TableAnnotation.class);
sql.append((annotation!=null?annotation.value():aClass.getSimpleName())+" set ");
StringBuilder update = new StringBuilder("where ");
for (Field field : aClass.getDeclaredFields()) {
field.setAccessible(true);
// 获取成员变量的注释
ListAnnotation la = field.getAnnotation(ListAnnotation.class);
// 判断是否拥有注释为id
if(la != null && 1==la.length()){
// 如果注释为1那么添加至update 并判断是否为null 不是则添加''
update.append((la != null && !Objects.equals(la.value(), "") ? la.value() : field.getName())+"="+(field.get(t)!=null ? "'"+field.get(t)+"'" : field.get(t))+" and ");
}else {
if(field.get(t)!=null) {
sql.append((la != null && !Objects.equals(la.value(), "") ? la.value() : field.getName()) + "=" + (field.get(t) != null ? "'" + field.get(t) + "'" : field.get(t)) + " ,");
}
}
}
// 添加where语句
if(!update.toString().equals("where ")){
for (int i = 0; i < 4; i++) {
update.deleteCharAt(update.length() - 1);
}
sql.deleteCharAt(sql.length()-1);
sql.append(update);
}
// 输出sql
System.out.println(sql);
// 连接对象
connection = DbUtil.getConn(connection);
// 传入sql
ps = connection.prepareStatement(sql.toString());
// 获取返值
int i = ps.executeUpdate();
return i;
} catch (Exception e) {
System.out.println("BaseDao update error出现错误!!");
e.printStackTrace();
} finally {
closeAll(connection,ps,rs);
}
return 0;
}
// 删除sql----------------------------------------
public int delete(T t){
try {
StringBuffer sql = new StringBuffer("delete from ");
Class<?> aClass = t.getClass();
TableAnnotation annotation = aClass.getAnnotation(TableAnnotation.class);
sql.append((annotation!=null?annotation.value():aClass.getSimpleName())+" ");
StringBuilder deletes = new StringBuilder("where ");
for (Field field : aClass.getDeclaredFields()) {
field.setAccessible(true);
// 获取成员变量的注释
ListAnnotation la = field.getAnnotation(ListAnnotation.class);
if(field.get(t)!=null){
deletes.append((la != null && !Objects.equals(la.value(), "") ? la.value() : field.getName())+"="+(field.get(t)!=null ? "'"+field.get(t)+"'" : field.get(t))+" and ");
}
}
// 添加where语句
if(!deletes.toString().equals("where ")){
for (int i = 0; i < 4; i++) {
deletes.deleteCharAt(deletes.length()-1);
}
sql.append(deletes);
}
// 输出sql
System.out.println(sql);
// 连接对象
connection = DbUtil.getConn(connection);
// 传入sql
ps = connection.prepareStatement(sql.toString());
// 获取返值
int i = ps.executeUpdate();
return i;
} catch (Exception e) {
System.out.println("BaseDao update error出现错误!!");
e.printStackTrace();
} finally {
closeAll(connection,ps,rs);
}
return 0;
}
// 查找sql----------------------------------------
public List<T> select(T t){
List<T> t1 = new ArrayList<>();
try {
StringBuffer sql = new StringBuffer("select * from ");
Class<?> aClass = t.getClass();
TableAnnotation annotation = aClass.getAnnotation(TableAnnotation.class);
sql.append((annotation!=null?annotation.value():aClass.getSimpleName())+" ");
StringBuilder selects = new StringBuilder("where ");
int a = 0;
for (Field field : aClass.getDeclaredFields()) {
a++;
field.setAccessible(true);
// 获取成员变量的注释
ListAnnotation la = field.getAnnotation(ListAnnotation.class);
if(field.get(t)!=null){
selects.append((la != null && !Objects.equals(la.value(), "") ? la.value() : field.getName())+"="+(field.get(t)!=null ? "'"+field.get(t)+"'" : field.get(t))+" and ");
}
}
// 添加where语句
if(!selects.toString().equals("where ")){
for (int i = 0; i < 4; i++) {
selects.deleteCharAt(selects.length()-1);
}
sql.append(selects);
}
// 输出sql
System.out.println(sql);
// 连接对象
connection = DbUtil.getConn(connection);
// 传入sql
ps = connection.prepareStatement(sql.toString());
// 获取返值
rs = ps.executeQuery();
while(rs.next()){
T o = (T) aClass.newInstance();
for (Field field : aClass.getDeclaredFields()) {
ListAnnotation la = field.getAnnotation(ListAnnotation.class);
field.setAccessible(true);
// 赋值对象
field.set(o,rs.getObject(la != null && !Objects.equals(la.value(), "") ? la.value() : field.getName()));
}
t1.add(o);
}
return t1;
} catch (Exception e) {
System.out.println("BaseDao update error出现错误!!");
e.printStackTrace();
} finally {
closeAll(connection,ps,rs);
}
return t1;
}
}
使用:
实体类:
import com.gzx.annotation.ListAnnotation;
import com.gzx.annotation.TableAnnotation;
import lombok.Data;
@TableAnnotation("User")
@Data
public class User {
@ListAnnotation(value = "id",length = 1)
private Integer id;
@ListAnnotation(value = "username",length = 0)
private String user_name;
private String password;
private Integer phone;
}
Test测试:
package com.gzx;
import com.gzx.dao.BaseDao;
import com.gzx.entity.User;
import java.util.List;
public class Main {
public static void main(String[] args) {
BaseDao<User> baseDao = new BaseDao();
User user = new User();
user.setId(2);
user.setUser_name("www");
int num = 3;
if(num==0){
int a = baseDao.insert(user);
System.out.println(a);
}else if(num==1){
int a = baseDao.update(user);
System.out.println(a);
}else if(num==2){
int a = baseDao.delete(user);
System.out.println(a);
}else if(num==3){
List<User> ls = baseDao.select(user);
for (User u : ls) {
System.out.println(u);
}
}
}
}
其中多为自我理解进行总结,可能会有错误,仅供参考