hibernate通过反射,动态生成insert语句原理 并向数据库添加数据
来源:互联网 发布:java intent bundle 编辑:程序博客网 时间:2024/04/30 11:59
hibernate中的反射机制,实现逆向访问数据库,并封装insert方法
首先,我们写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;}@Overridepublic String toString() {return "Users [id=" + id + ", username=" + username + ", password=" + password + ", state_id=" + state_id + "]";}}
2) 配置连接数据库的属性文件 test.properites
mysql.username=rootmysql.password=mysqlpassmysql.url=jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8mysql.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 blocke.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 blocke.printStackTrace();}}public static Connection getCon(){return con;}}
重点:
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)){ //判断前面的属性名 是否 与截取出来的字段名相同 ,则说明顺序相同 ,则拼接//去掉IDfieldName += 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 blocke.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)){ //判断前面的属性名 是否 与截取出来的字段名相同 ,则说明顺序相同 ,则拼接//去掉IDfieldName.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 blocke.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的实现原理
0 0
- hibernate通过反射,动态生成insert语句原理 并向数据库添加数据
- SQL语言使用insert语句向数据库表格中插入或添加新的数据行
- 向数据库添加数据有三种方法利用 SQL语句添加、通过SqlParameter参数添加和通过存储过程添加。(一)
- 向数据库添加数据有三种方法利用 SQL语句添加、通过SqlParameter参数添加和通过存储过程添加。(二)
- 向数据库添加数据有三种方法利用 SQL语句添加、通过SqlParameter参数添加和通过存储过程添加。(三)
- 使用Hibernate向数据库中添加数据
- 运用INSERT INTO语句向数据库中插入数据失败。
- SQL Server 动态生成数据库所有表Insert语句
- SQL Server 动态生成数据库所有表Insert语句
- 从Oracle数据库中读取数据,自动生成INSERT语句
- sqlite生成数据库,并添加数据
- 表数据生成 insert 语句
- Jquery 动态生成表单 并将表单数据 批量通过Ajax插入到数据库
- 前台post通过web api向数据库中添加数据
- 向MSHFlexGrid控件中动态添加数据库数据
- [转帖]向Access数据库写数据时发生Insert into 语句的语法错误
- [数据库]添加记录Insert into 语句详解
- 动态向table添加数据
- OOM
- hdu 1874 最短路径
- javaScript中的BOM对象-History和screen(3)
- iOS 环信集成问题(连文档都不说明的坑。。)
- Android命名规范
- hibernate通过反射,动态生成insert语句原理 并向数据库添加数据
- SQL2012 设置外键FK约束
- 读《深入理解java虚拟机》第一章大致
- Andorid事件处理 基于回调的事件处理
- 我终于有了一个GitHub了
- GCD线程与runloop中添加timer的见解
- python 那些待深入理解的东西
- 【网络流】bzoj3901(?)Magic
- poj1664