谁都可以手写ORM
创建@Table注解
@Inherited
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Table {
String value() default "";
}
创建@Column注解
@Inherited
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
String value() default "";
}
创建实体类
@Table("t_user")
public class User implements Serializable {
@Column("id")
private String id;
@Column("name")
private String name;
@Column("age")
private Integer age;
public User() {
}
public User(String id, String name) {
this.id = id;
this.name = name;
}
public User(String id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String 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;
}
@Override
public String toString() {
return "User{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
创建注解解析,拼接SQL
/**
* 解析自定义注解
* @author BTI-PC-DELL5370-243
*/
public class AnnotationParser {
/**
* 通过注解来组装查询条件,生成查询语句
* @param obj
* @return
*/
public static String assemblesSqlFromObj(Object obj){
//根据表类型获取表
Table table = obj.getClass().getAnnotation(Table.class);
StringBuffer sql = new StringBuffer();
//获取注解的值
String tableName = table.value();
sql.append("select * from ").append(tableName).append("where 1 = 1");
//getDeclaredFields() => 获得某个类的所有声明的字段,即包括public、private和proteced,但是不包括父类的申明字段。-> null字段也会传入
Field [] fields = obj.getClass().getDeclaredFields();
for (Field f : fields){
//field -> name为字段名
String filedName = f.getName();
String methodName = "get" + filedName.substring(0,1).toUpperCase() + filedName.substring(1);
try {
//getAnnotation() 获取字节码
Column column = f.getAnnotation(Column.class);
if(column != null){
Method method = obj.getClass().getMethod(methodName);
Object v = method.invoke(obj);
if( v != null ){
if( v instanceof String){
StringBuilder value = new StringBuilder(v.toString().trim());
// 判断参数是不是 in 类型参数 1,2,3
if(value.toString().contains(",")){
//去除value中的,
String sqlParams = value.toString().replace(",","").trim();
//value中都是纯数字
if(isNum(value.toString())){
sql.append("and").append(column.value()).append("in(").append(value).append(")");
} else {
String [] split = value.toString().split(",");
//将value置空
value = new StringBuilder();
for (String s : split) {
value.append("'").append(s).append("',");
}
value.append("'").append(split[split.length - 1]).append("'");
sql.append(" and ").append(column.value()).append(" in (").append(value).append(") ");
}
}else {
if(value.length() > 0){
sql.append(" and ").append(column.value()).append(" like '%").append(value).append("%' ");
}
}
}else {
sql.append(" and ").append(column.value()).append("=").append(v.toString()).append(" ");
}
}
}
}catch (Exception e){
e.printStackTrace();
}
}
return sql.toString();
}
/**
* 添加数据方法
*/
public static String add(Object obj){
Table table = obj.getClass().getAnnotation(Table.class);
StringBuffer sql = new StringBuffer();
String tableName = table.value();
sql.append("insert into ").append(tableName).append(" ( ");
Field [] fields = obj.getClass().getDeclaredFields();
List<Object> valueList = new ArrayList<Object>();
if(fields.length > 0){
for(Field field : fields){
String fieldName = field.getName();
String methodName = "get" + fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
sql.append(fieldName).append(",");
Column column = field.getAnnotation(Column.class);
try{
if(column != null){
Method method = obj.getClass().getMethod(methodName);
Object v = method.invoke(obj);
if(ObjectUtils.allNotNull(v)){
valueList.add(v);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
//减去最后一个逗号
StringBuilder resultSql = new StringBuilder(sql.deleteCharAt(sql.length() - 1)).append(" ) ");
//添加sql后缀
resultSql.append(" value ( ");
for(Object object : valueList){
resultSql.append(object).append(" ,");
}
//去除逗号
sql = new StringBuffer(resultSql.deleteCharAt(resultSql.length()-1));
sql.append(" );");
}else{
try{
throw new SQLException("请输入参数");
}catch (Exception e){
e.printStackTrace();
}
}
return sql.toString();
}
/**
* 检查给定的值是不是 id 类型 1.检查字段名称 2.检查字段值
*
* @param target
* @return
*/
public static boolean isNum(String target) {
boolean isNum = false;
if (target.toLowerCase().contains("id")) {
isNum = true;
}
if (target.matches("\\d+")) {
isNum = true;
}
return isNum;
}
}
创建数据库连接工具类
public class DBUtil {
//获取数据库连接参数
private final static String DRIVER_CLASS = "com.mysql.jdbc.Driver";
private final static String URL = "jdbc:mysql://localhost:3006/TABLE?characterEncoding=UTF-8";
private final static String USER = "userName";
private final static String PASSWORD = "passWord";
//封装加载驱动
static {
try{
Class.forName(DRIVER_CLASS);
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 封装连接数据库
*/
public static Connection getConnection(){
try{
return DriverManager.getConnection(URL,USER,PASSWORD);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
//定义通用CRUD
public static int executeUpdate(String sql , Object...parameters){
int row = 0;
Connection connection = getConnection();
PreparedStatement preparedStatement = null;
try{
preparedStatement = connection.prepareStatement(sql);
//判断有没有参数需要设置
if(parameters.length > 0){
for(int i=0;i<parameters.length;i++) {
//参数类型如何判断呢。所有类都是object子类
preparedStatement.setObject(i+1, parameters[i]);
}
}
//执行sql
row = preparedStatement.executeUpdate();
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(preparedStatement!=null) {
preparedStatement.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
try {
if(connection!=null) {
connection.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
return row;
}
}
创建测试类进行测试
public class AnnotationTest {
public static void main(String[] args) {
testOne();
}
private static void testOne(){
User testDto = new User("123", "34");
User testDto1 = new User("123", "test1",1);
User testDto2 = new User("", "test1,test2,test3,test4",2);
String sql = AnnotationParser.assemblesSqlFromObj(testDto);
String sql1 = AnnotationParser.assemblesSqlFromObj(testDto1);
String sql2 = AnnotationParser.assemblesSqlFromObj(testDto2);
System.out.println(sql);
System.out.println(sql1);
System.out.println(sql2);
User addOne = new User("2", "1502",22);
int num = DBUtil.executeUpdate(AnnotationParser.add(addOne));
System.err.print(num);
}
}