首先ORM自定义学习框架。敲完理解就行。
话不多说上代码
项目结构看图片
目录
工具
自定义注解
package 自己写;
import com.xyao.orm.annotation.MyColumn;
import com.xyao.orm.annotation.MyId;
import com.xyao.orm.annotation.MyTable;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
//如果缺包,自己导入
public class BaseDao {
//万能插入操作
public int save(Object obj){
//根据插入的obj生成插入sql语句
//insert into 表明 (列明) values (?,?,?);
//根据对象获取类的类对象
Class clazz =obj.getClass();
//创建拼接的语句
StringBuffer sb = new StringBuffer();
sb.append("insert into ");
/获取表名称
//获取class上的注解对象
MyTable tableAnn = (MyTable) clazz.getDeclaredAnnotation(MyTable.class);
//获取注解上的表名称
String tableName = tableAnn.value();
sb.append(tableName);
sb.append("(");
//获取列的名称
Field[] fields = clazz.getDeclaredFields();
for (Field field :fields) {
//从属性上获取注解
//只处理存储了Column注解的属性
if(field.isAnnotationPresent(MyColumn.class)){
MyColumn columnAnn = field.getDeclaredAnnotation(MyColumn.class);
String columnName = columnAnn.value();
//拼接columnName
sb.append(columnName+",");
}
}
//去掉最后一个逗号
sb.deleteCharAt(sb.length()-1);
sb.append(") values (");
for (Field field :fields) {
//只处理存储了Column注解的属性
if(field.isAnnotationPresent(MyColumn.class)){
sb.append("?,");
}
}
//去掉最后一个逗号
sb.deleteCharAt(sb.length()-1);
//拼接?号
sb.append(")");
//打印sql语句
System.out.println(sb.toString());
//打开连接创建预编译
Connection conn = DBUtil.getConn();
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sb.toString());
//设置参数
int columnIndex = 1;//用于计算参数的数量
for (int i=0;i<fields.length;i++) {
//获取属性的对应的值
Field field = fields[i];
if(field.isAnnotationPresent(MyColumn.class)){
field.setAccessible(true);
//从传递进来对象中获取值
Object fieldValue = field.get(obj);
ps.setObject(columnIndex++,fieldValue);//设置参数
}
}
//执行操作
return ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} finally {
DBUtil.close(conn,ps,null);
}
return 0;
}
//自定义删除条件
public int delete(Class clazz,String wheresql,Object[] params){
//delete from 表名 where x =?
//创建拼接的语句
StringBuffer sb = new StringBuffer();
sb.append("delete from ");
/获取表名称
sb.append(getTableName(clazz));
//设置删除条件
sb.append(" "+wheresql+" ");
//打印sql语句
System.out.println(sb.toString());
//创建预编译
Connection conn = DBUtil.getConn();
PreparedStatement ps =null;
try {
ps = conn.prepareStatement(sb.toString());
//设置参数
for (int i=0;i<params.length;i++){
ps.setObject(i+1,params[i]);
}
//执行删除
return ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DBUtil.close(conn,ps,null);
}
return 0;
}
//以第一个属性作为条件进行删除
public int delete(Object obj){
//delete from 表名 where x =?
Class clazz =obj.getClass();
//创建拼接的语句
StringBuffer sb = new StringBuffer();
sb.append("delete from ");
/获取表名称
sb.append(getTableName(clazz));
//设置删除条件
Field keyField = findKeyField(clazz);
//获取属性列的名称
//找到主键的Field
String idColumn = getColumnName(keyField);
sb.append(" where "+idColumn+" = ?");
//打印sql语句
System.out.println(sb.toString());
//创建预编译
Connection conn = DBUtil.getConn();
PreparedStatement ps =null;
try {
ps = conn.prepareStatement(sb.toString());
//设置参数
ps.setObject(1,getFieldValue(keyField,obj));
//执行删除
return ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DBUtil.close(conn,ps,null);
}
return 0;
}
//查询主键方法
private Field findKeyField(Class clazz){
Field[] fields = clazz.getDeclaredFields();
for (Field field :fields) {
//判断是否存在注解
if(field.isAnnotationPresent(MyId.class)){
return field;
}
}
throw new RuntimeException("主键不存在");
}
//获取属性的名称
private String getColumnName(Field field){
MyColumn columnAnn = field.getDeclaredAnnotation(MyColumn.class);
return columnAnn.value();
}
//获取属性的值
private Object getFieldValue(Field field,Object obj){
field.setAccessible(true);
try {
return field.get(obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
};
//获取表的名称
private String getTableName(Class clazz){
//获取class上的注解对象
MyTable tableAnn = (MyTable) clazz.getDeclaredAnnotation(MyTable.class);
//获取注解上的表名称
return tableAnn.value();
}
//更新操作
public int update(Object obj){
Class clazz = obj.getClass();
//拼接更新的sql语句
StringBuffer sb = new StringBuffer();
sb.append("update ");
sb.append(getTableName(clazz));//表明
sb.append(" set ");
//获取所有的字段
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields){
//判断字段就不拼接
if(field.isAnnotationPresent(MyColumn.class) && getFieldValue(field,obj)!=null){
sb.append(getColumnName(field)+"=?,");
}
}
//去掉最后一个逗号
sb.deleteCharAt(sb.length()-1);
//设置更新条件
Field keyField = findKeyField(clazz);
sb.append(" where "+getColumnName(keyField)+"=?");
System.out.println(sb.toString());
//创建预编译
Connection connection = DBUtil.getConn();
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(sb.toString());
//设置参数
int colIdx = 1;
for (Field field :fields) {
//判断字段为空就不插入
if(field.isAnnotationPresent(MyColumn.class) && getFieldValue(field,obj)!=null){
Object value = getFieldValue(field,obj);
ps.setObject(colIdx++,value);
}
}
//最后的时候还需要设置id
ps.setObject(colIdx++,getFieldValue(keyField,obj));
//执行更新
return ps.executeUpdate();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DBUtil.close(connection,ps,null);
}
return 0;
}
//sql查询语句
//params:查询参数
//resultClass:映射结果对象
public List query(
String sql,//sql语句
Object[] params,//传递的参数数组
Class resultClazz //结果映射类对象
){
Connection conn = DBUtil.getConn();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement(sql);
if(params!=null){
int colIdx = 1;
for(Object o :params){
ps.setObject(colIdx++,o);
}
}
//执行操作
rs = ps.executeQuery();
//将查询结果映射指定的类上
List list = getList(resultClazz, rs);
return list;
} catch (SQLException throwables) {
throwables.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}finally {
DBUtil.close(conn,ps,rs);
}
return null;
}
public int getMaxId(Class clazz){
//找到主键
Field[] fields = clazz.getDeclaredFields();
Field pkField = null;
for (Field field :fields) {
if(field.isAnnotationPresent(MyId.class)){
pkField = field;
break;
}
}
Connection conn = DBUtil.getConn();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement("select max("+getColumnName(pkField)+") from "+ getTableName(clazz));
rs = ps.executeQuery();
if(rs.next()){
return rs.getInt(1);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
DBUtil.close(conn,ps,rs);
}
return -1;
}
private List getList(Class resultClazz, ResultSet rs) throws SQLException, InstantiationException, IllegalAccessException {
List list = new ArrayList();
//存储所有的Field的集合
List<Field> fieldList = new ArrayList<>();
//遍历当前了的所有的父类
//c.getDeclaredFields()只能获取当前类的所有的属性,无法获取父类的属性
for(Class c = resultClazz; //初始值
c!=Object.class; //循环退出条件
c = c.getSuperclass()){//每次遍历的时候设置的新的条件
//获取当前类的所有的属性
Field[] fields = c.getDeclaredFields();
List tempList = Arrays.asList(fields);//将数组转换成集合
fieldList.addAll(tempList);//添加到集合
}
while(rs.next()){
Object obj = resultClazz.newInstance();
//给对象的属性赋值,赋予查询的值e
for (Field field :fieldList) {
if(field.isAnnotationPresent(MyColumn.class)){
Object value = rs.getObject(getColumnName(field));
//给属性赋值
field.setAccessible(true);
if(value instanceof BigDecimal){
double d1 = ((BigDecimal) value).doubleValue();
field.set(obj, Double.valueOf(d1));//设置对象类型
}else{
field.set(obj,value);
}
}
}
list.add(obj);//将对象放入到集合中
}
return list;
}
//查询操作
public List query(Class clazz,String whereSql,Object[] params){
//拼接查询的语句
//select * from 表名
StringBuffer sb = new StringBuffer();
sb.append("select * from ");
sb.append(getTableName(clazz));
//拼接查询条件
if(whereSql!=null){
sb.append(" "+whereSql);
}
System.out.println(sb.toString());
//执行操作
Connection conn = DBUtil.getConn();
PreparedStatement ps = null;
ResultSet rs = null;
Field[] fields = clazz.getDeclaredFields();
try {
ps = conn.prepareStatement(sb.toString());
//设置参数
int colIdx = 1;
if(params !=null){
for (Object o :params) {
ps.setObject(colIdx++,o);
}
}
rs = ps.executeQuery();
return getList(clazz,rs);
} catch (SQLException throwables) {
throwables.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}finally {
DBUtil.close(conn,ps,rs);
}
return null;
}
}
工具
package 别看了自己写;
//druid包
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class DBUtil {
static DruidDataSource ds;
static {
//加载配置文件
Properties ps = new Properties();
try {
ps.load(DBUtil.class.getClassLoader().getResourceAsStream("db.properties"));
//创建数据库连接池
ds = (DruidDataSource) DruidDataSourceFactory.createDataSource(ps);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//打开连接
public static Connection getConn(){
try {
return ds.getConnection();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
//关闭连接
public static void close(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();
}
}
}
}
自定义注解
//三个分开的,别写一起来,我偷懒
package annotion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//注解作用的类型
@Target(ElementType.TYPE)
//注解有效范围
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTable {
//定义注解的存储属性
public String value();
}
package annotion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyColumn {
public String value();
}
package annotion;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)//运行时调用
@Target({ElementType.FIELD, ElementType.TYPE})//指定作用范围类
public @interface MyId {
}
db.properties文件的设置
driver = com.mysql.cj.jdbc.Driver url = jdbc:mysql://localhost:3306/数据库?serverTimezone=PRC username = root password = root