自定义实现ORMapping框架的核心在于反射和注解的应用,关于这部分的内容可以参考文章:
Java反射总结
Java自定义注解的实现
在本篇文章中主要实现save方法,关键在于以下几步:
具体代码如下
annotation:
/**
* @Author: huhu
* @Date: 2019-08-10 19:21
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface HuHuBean {
String value();
}
/**
* @Author: huhu
* @Date: 2019-08-10 19:22
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface HuHuField {
String value();
}
dao:
/**
* @Author: huhu
* @Date: 2019-08-10 19:28
*/
public interface BaseDAO {
/**
* insert into xxx(col1, col2, col3...) values(?,?,?...)
*
* @param t
* @param
* @return
*/
<T>Serializable save(T t);
}
/**
* @Author: huhu
* @Date: 2019-08-10 19:35
*/
public class BaseDAOImpl implements BaseDAO {
/**
* 入参是T:User
*
* insert into t_user (name,age,birth_day) values (?,?,?);
*
* t: user
* user.getId() user.getName() 通过这种方式依次将值给获取出来
*
* 常见面试考点:StringBuffer与StringBuilder的区别
*
* @param t
* @param
* @return
*/
@Override
public <T> Serializable save(T t) {
StringBuilder builder = new StringBuilder("insert into ");
String table = Tools.getTable(t.getClass());
builder.append(table).append(" (");
Class<?> clazz = t.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
//判断获取的字段是否为id,id为自增主键,因此不需要拼接
if (!field.getName().equals("id")) {
String column = Tools.getColumn(field);
builder.append(column).append(",");
}
}
// 删除逗号
builder.deleteCharAt(builder.toString().length()-1)
.append(") values (");
// 有几个?取决于需要拼接几个字段
for (Field field : fields) {
if (!field.getName().equals("id")) {
builder.append("?,");
}
}
// 删除逗号
builder.deleteCharAt(builder.toString().length()-1)
.append(")");
// System.out.println(builder.toString());
Connection connection = null;
PreparedStatement pstmt = null;
ResultSet rs =null;
int index = 1;
try {
connection = DBUtils.getConnection();
// 将拼接好的SQL传入
// pstmt = connection.prepareStatement(builder.toString());
// 传入拼接好的sql以及需要返回的字段名id
pstmt = connection.prepareStatement(builder.toString(), new String[]{"id"});
for (Field field : fields) {
if (!field.getName().equals("id")) {
String getMethod = Tools.getMethod(field);
Method method = clazz.getDeclaredMethod(getMethod);
Object obj = method.invoke(t);
pstmt.setObject(index++, obj);
}
}
int rowCount = pstmt.executeUpdate();
System.out.println("rowCount: " + rowCount);
if (rowCount > 0) {
rs = pstmt.getGeneratedKeys();
rs.next();
// 返回id字段的最新值
return (Serializable) rs.getObject(1);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
domain:
/**
* @Author: huhu
* @Date: 2019-08-10 19:18
*/
@HuHuBean("t_user")
public class User {
private Integer id;
private String name;
private Integer age;
@HuHuField("birth_day")
private Date bithday;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBithday() {
return bithday;
}
public void setBithday(Date bithday) {
this.bithday = bithday;
}
public User() {}
public User(String name, Integer age, Date bithday) {
this.name = name;
this.age = age;
this.bithday = bithday;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", bithday=" + bithday +
'}';
}
}
utils:
/**
* @Author: huhu
* @Date: 2019-08-11 20:41
*/
public class DBUtils {
public static Connection getConnection() {
String url = "jdbc:mysql://localhost:3306/orm";
String user = "root";
String password = "root";
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
return connection;
}
public static void close(Connection connection) {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
/**
* @Author: huhu
* @Date: 2019-08-11 16:31
*/
public class Tools {
/**
* 根据注解获取表名
*
* @param clazz
* @return
*/
public static String getTable(Class<?> clazz) {
String tableName = "";
HuHuBean huHuBean = clazz.getAnnotation(HuHuBean.class);
if (huHuBean != null) {
// 获取注解中的值
tableName = huHuBean.value();
} else {
// 如果为空,就直接获取类名
tableName = clazz.getSimpleName();
}
return tableName;
}
/**
* 根据注解获取属性名称
*
* @param field
* @return
*/
public static String getColumn(Field field) {
String column = "";
HuHuField huHuField = field.getAnnotation(HuHuField.class);
if (huHuField != null) {
// 获取注解中的值
column = huHuField.value();
} else {
// 如果为空,就直接获取字段名
column = field.getName();
}
return column;
}
/**
* 根据字段获取对应的get方法
*
* @param field
* @return
*/
public static String getMethod(Field field) {
String fieldName = field.getName();
// id==>getId
// name==>getNamet
String name = fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
return "get" + name;
}
}
Test:
/**
* @Author: huhu
* @Date: 2019-08-11 17:52
*/
public class BaseDAOImplTest {
@Test
public void test01() {
BaseDAO dao = new BaseDAOImpl();
User user = new User("HuHu", 22, new Date());
System.out.println(dao.save(user));
}
}