hibernate通过反射,动态生成insert语句原理 并向数据库添加数据
2017-03-09 23:52
561 查看
hibernate中的反射机制,实现逆向访问数据库,并封装insert方法
首先,我们写dao层的时候会发现,有很多insert语句,比如: insert into Users(username,password) values('zhangsan','zs123') 。开发过程中会遇到很多这样的插入语句,为了简化开发,Hibernate框架实现语句的封装,
为了更好的理解,我们下面通过反射机制来模拟封装insert方法 和通过Hibernate实现逆向访问数据库,并调用上面封装好的insert方法向数据库中动态插入数据。
1.Hibernate实现逆向访问数据库
1)首先我们需要的实体类 Users
2) 配置连接数据库的属性文件 test.properites
通过上面的步骤,我们的准备工作已经做好了, 现在只需要编写工具类ReflexUtil来封装动态生成的insert语句 就可以了
重点:
最后编写测试类
通过上面步骤:实现了Hibernate底层的东西,也让我们理解了Hibernate的实现原理
首先,我们写dao层的时候会发现,有很多insert语句,比如: insert into Users(username,password) values('zhangsan','zs123') 。开发过程中会遇到很多这样的插入语句,为了简化开发,Hibernate框架实现语句的封装,
为了更好的理解,我们下面通过反射机制来模拟封装insert方法 和通过Hibernate实现逆向访问数据库,并调用上面封装好的insert方法向数据库中动态插入数据。
1.Hibernate实现逆向访问数据库
1)首先我们需要的实体类 Users
public class Users { private Integer id; // 编号 private String username; // 账户 private String password;// 密码 private Integer state_id; // 职位状态
public void setId(Integer id) {this.id = id;} public Integer getId() {return id;} public void setUsername(String username) {this.username = username;} public String getUsername() {return username;} public void setPassword(String password) {this.password = password;} public String getPassword() {return password;} public void setState_id(Integer state_id){this.state_id = state_id;} public Integer getState_id() {return state_id;}
public Users() {} public Users(Integer id, String username, String password, Integer state_id) { this.id = id; this.username = username; this.password = password; this.state_id = state_id; } @Override public String toString() { return "Users [id=" + id + ", username=" + username + ", password=" + password + ", state_id=" + state_id + "]"; } }
2) 配置连接数据库的属性文件 test.properites
mysql.username=root mysql.password=mysqlpass mysql.url=jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8 mysql.driverClassName=com.mysql.jdbc.Driver3)编写连接数据库的工具类
public class ConnectMysqlUtil { private static Connection con; static { // 使用反射加载属性文件: InputStream in = Object.class.getResourceAsStream("/test.properties"); Properties pro = new Properties(); try { pro.load(in); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 从输入流中读取属性列表(键和元素对)。 // 获取properties中的属性 String mysql_username = pro.getProperty("mysql.username").trim(); String mysql_password = pro.getProperty("mysql.password").trim(); String mysql_url = pro.getProperty("mysql.url").trim(); String mysql_driverClassName = pro.getProperty("mysql.driverClassName").trim(); try { Class.forName(mysql_driverClassName); con = DriverManager.getConnection(mysql_url, mysql_username, mysql_password); } catch (ClassNotFoundException | SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static Connection getCon(){ return con; } }
通过上面的步骤,我们的准备工作已经做好了, 现在只需要编写工具类ReflexUtil来封装动态生成的insert语句 就可以了
重点:
public class ReflexUtil { //获取并且返回完整的insert 语句 //String拼接 public static String getInsertSQL(Object o) { Class c = o.getClass(); Field[] fl = c.getDeclaredFields(); String fieldName = "";//属性名拼接 String valueName = ""; //字段值拼接 for (Field field : fl) { String str = field.getName(); //获取属性名 Method[] ms = c.getDeclaredMethods(); //获取方法 for (Method method : ms) { String name = method.getName();//获取方法名 if(name.startsWith("get")&&!name.startsWith("getClass")){//过滤 筛选get方法 String str1 = name.substring(3); //通过方法名截取出字段名 if(str.equalsIgnoreCase(str1)&&!"id".equalsIgnoreCase(str)){ //判断前面的属性名 是否 与截取出来的字段名相同 ,则说明顺序相同 ,则拼接 //去掉ID fieldName += str + ","; String str2; try { str2 = method.invoke(o, null).toString(); //获取方法值 String type = method.getReturnType().getSimpleName(); //方法类型 if("String".equalsIgnoreCase(type)){ valueName += "'"+str2+"'"+","; //数据库中 String类型 需要加单引号 插入 }else{ valueName +=str2+","; } } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } fieldName = fieldName.substring(0, fieldName.length()-1); //去除末尾的逗号 valueName = valueName.substring(0, valueName.length()-1); String sql= "insert into "+c.getSimpleName()+"("+fieldName+")"+" values"+"("+valueName+")"; return sql; } //获取并且返回完整的insert 语句 //StringBuffer拼接 public static String getInsertSql(Object o){ Class c = o.getClass(); Field[] fl = c.getDeclaredFields(); StringBuffer fieldName= new StringBuffer();//属性名拼接 StringBuffer valueName=new StringBuffer() ; //字段值拼接 for (Field field : fl) { String str = field.getName(); //获取属性名 Method[] ms = c.getDeclaredMethods(); //获取方法 for (Method method : ms) { String name = method.getName();//获取方法名 if(name.startsWith("get")&&!name.startsWith("getClass")){//过滤 筛选get方法 String str1 = name.substring(3); //通过方法名截取出字段名 if(str.equalsIgnoreCase(str1)&&!"id".equalsIgnoreCase(str)){ //判断前面的属性名 是否 与截取出来的字段名相同 ,则说明顺序相同 ,则拼接 //去掉ID fieldName.append(str + ",") ; String str2; try { str2 = method.invoke(o, null).toString(); String type = method.getReturnType().getSimpleName(); if("String".equalsIgnoreCase(type)){ valueName.append("'"+str2+"'"+","); }else{ valueName.append(str2+","); } } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } } String endFieldName = fieldName.substring(0, fieldName.length()-1); //去除末尾的逗号 String endValueName = valueName.substring(0, valueName.length()-1); String sql= "insert into "+c.getSimpleName()+"("+endFieldName+")"+" values"+"("+endValueName+")"; return sql; } }
最后编写测试类
public static void main(String[] args) throws SQLException { Users users = new Users(1,"张三","zs1231",8); String sql = ReflexUtil.getInsertSQL(users); Connection con = ConnectMysqlUtil.getCon(); PreparedStatement psta = con.prepareStatement(sql); int i = psta.executeUpdate(); if(i>0){ System.out.println("插入成功"); } }测试结果:
通过上面步骤:实现了Hibernate底层的东西,也让我们理解了Hibernate的实现原理
相关文章推荐
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- 动态SQL语句根据数据库列来查询数据,动态的生成列名称
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- java优化Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- SQL Server 动态生成数据库所有表Insert语句
- 【转】Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- Jquery 动态生成表单 并将表单数据 批量通过Ajax插入到数据库
- Jquery 动态生成表单 并将表单数据 批量通过Ajax插入到数据库
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- Hibernate动态建表,通过hbm.xml配置文件创建数据表,进行数据库操作, 动态模型
- Jquery 动态生成表单 并将表单数据 批量通过Ajax插入到数据库
- hibernate通过判断参数动态组合Hql语句,生成基本通用查询
- SQL语言使用insert语句向数据库表格中插入或添加新的数据行
- Hibernate动态建表,通过hbm.xml配置文件创建数据表,进行数据库操作, 动态模型
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- SQL Server 动态生成数据库所有表Insert语句