1.功能介绍
小例子主要完成以下功能,通过Java反射获取SQL语句,使用MyBatis传入SQL语句,将数据插入到数据库中
2.代码讲解
2.1 自定义注解
首先看一个自定义注解,在此例子中我自定义了两个注解,一个叫DBTable,另一个是DBColumn。
DBTable用于描述POJO对应的表名。
@Target({ElementType.Type})代表这个注解能用于描述类或者接口。
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
// 用来描述数据库中表的名称
String value();
}
DBColmn用于描述POJO中属性字段对应数据库的列名。
@Target({ElementType.Field})代表这个注解用于描述对象的字段。
@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface DBColumn {
// 用来描述表字段的名称
String value();
}
2.2 实体类
首先给贴出表结构,oper_info表包含四个字段,分别在oper_id(操作员编号),oper_name(操作员名称),oper_sex(操作员性别)及oper_role(操作员权限)。
贴出OperInfo实体类代码,在OperInfo的类名上打了个@DBTable注解,它的Value应该与表明oper_info对应。在OperInfo的属性上都打了@DBColumn,它们的value应该与数据库中oper_info表的列名相对应。
@DBTable("oper_info")。
public class OperInfo {
/**
* 1.属性字段
*/
// 员工编号
@DBColumn("oper_id")
private String operId;
// 员工姓名
@DBColumn("oper_name")
private String operName;
// 员工性别
@DBColumn("oper_sex")
private int operSex;
// 员工角色
@DBColumn("oper_role")
private int operRole;
/**
* 2.生成Getter/Setter方法
*/
public String getOperId() {
return operId;
}
public void setOperId(String operId) {
this.operId = operId;
}
public String getOperName() {
return operName;
}
public void setOperName(String operName) {
this.operName = operName;
}
public int getOperSex() {
return operSex;
}
public void setOperSex(int operSex) {
this.operSex = operSex;
}
public int getOperRole() {
return operRole;
}
public void setOperRole(int operRole) {
this.operRole = operRole;
}
/**
* 3.生成toString()方法
*/
@Override
public String toString() {
return "OperInfo [operId=" + operId + ", operName=" + operName + ", operSex=" + operSex + ", operRole="
+ operRole + "]";
}
}
2.3 InsertSqlUtil
public class InsertSqlUtil {
//通过对象获取SQL语句
public static String getInsertSql(Object o) {
// 1.初始化变量
String invokeResult = null;
String insertFiledName = null;
String insertFiledValue = null;
StringBuilder sqlStrBuilder = new StringBuilder();
// 2.获取Class
Class<? extends Object> clazz = o.getClass();
// 3.判断是否含有DBTable.class的注解
if (!clazz.isAnnotationPresent(DBTable.class)) {
// 代表不存在DBTable.class的注解
return invokeResult;
}
// 4.代表存在DBTable.class的注解
DBTable dbTable = (DBTable) clazz.getAnnotation(DBTable.class);
// 获取数据库表名
String dbTableName = dbTable.value();
// 5.组装插入语句,insert into tableName
sqlStrBuilder.append("insert into ").append(dbTableName);
// 6.获取类属性字段(getDeclaredFields可以获取所有字段)
Field[] fields = clazz.getDeclaredFields();
// 7.增强for循环判断是否存在DBColumn注解
for (Field field : fields) {
// 判断是否包含DBColumn注解
if (!field.isAnnotationPresent(DBColumn.class)) {
// 不存在DBColumn注解则跳过检查
continue;
}
// 获取列名
DBColumn dbColumn = field.getAnnotation(DBColumn.class);
String dbColumnName = dbColumn.value();
// 获取pojo字段名
String fieldName = field.getName();
// 获取相应字段的getXXX()方法,将列名首字母大写,确保可以调用OperInfo表中的Getter/Setter方法
String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
Object dbColumnValue = null;
try {
Method getMethod = clazz.getMethod(getMethodName);
dbColumnValue = getMethod.invoke(o);
} catch (Exception e) {
e.printStackTrace();
}
// 进行sql语句拼接
if (dbColumnValue == null) {
// 代表字段取值为空
continue;
}
if (judgeStringIsNull(insertFiledName)) {
// 代表fileName串为空
insertFiledName = "(" + dbColumnName + ")";
} else {
// 代表fileName串为非空,移掉前一个)
insertFiledName = insertFiledName.substring(0, insertFiledName.length() - 1) + "," + dbColumnName + ")";
}
// 代表字段取值为非空
if (dbColumnValue instanceof String) {
if (judgeStringIsNull(insertFiledValue)) {
insertFiledValue = "('" + dbColumnValue + "')";
} else {
insertFiledValue = insertFiledValue.substring(0, insertFiledValue.length() - 1) + ",'"
+ dbColumnValue + "')";
}
} else if (dbColumnValue instanceof Integer) {
if (judgeStringIsNull(insertFiledValue)) {
insertFiledValue = "(" + dbColumnValue + ")";
} else {
insertFiledValue = insertFiledValue.substring(0, insertFiledValue.length() - 1) + ","
+ dbColumnValue + ")";
}
}
}
sqlStrBuilder.append(insertFiledName).append(" values ").append(insertFiledValue);
return sqlStrBuilder.toString();
}
// 判断字符串是否为空,返回boolean
public static boolean judgeStringIsNull(String input) {
return ((input == null) || (input.isEmpty()));
}
}
2.4 DAO接口及Mapper文件
public interface OperInfoMapper {
int insertOperInfo(String sql);
}
DAO的Mapper定义
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="org.matcha.dao.OperInfoMapper" >
<insert id="insertOperInfo" parameterType="java.lang.String" >
${value}
</insert>
</mapper>
2.5 测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-mybatis.xml")
public class testInsertToDB {
@Autowired
private OperInfoMapper operInfoMapper;
@Test
public void testInsertOperInfoToDB() {
// 第一步:获取OperInfo对象并赋值
OperInfo operInfo = new OperInfo();
operInfo.setOperId("1");
operInfo.setOperName("234");
operInfo.setOperRole(1);
OperInfo operInfo2 = new OperInfo();
operInfo2.setOperId("2");
operInfo2.setOperName("222");
operInfo2.setOperRole(2);
operInfo2.setOperSex(1);
// 第二步:获取Insert语句
String operInfoInsertSql1 = InsertSqlUtil.getInsertSql(operInfo);
String operInfoInsertSql2 = InsertSqlUtil.getInsertSql(operInfo2);
// 第三步:调用OperInfoMapper使用insert语句
int invokeSql1 = operInfoMapper.insertOperInfo(operInfoInsertSql1);
int invokeSql2 = operInfoMapper.insertOperInfo(operInfoInsertSql2);
// 第四步:打印结果
System.out.println("SQL语句为" + operInfoInsertSql1 + "," + (invokeSql1 > 0 ? "调用成功" : "调用失败"));
System.out.println("SQL语句为" + operInfoInsertSql2 + "," + (invokeSql2 > 0 ? "调用成功" : "调用失败"));
}
}
执行结果sql语句及结果由于第一次写帖子,有点慌乱。在本帖中有任何错误欢迎大家指正。