预备知识
利用java的反射机制可以获取到类的结构信息,动态调用属性和方法
- 获取Class的实例的三种方法
Class class=类名.class;
Class class=Class.forName("全类名");
Class class=对象.getClass();
- 获取对象的类名
String className=class.getName();//获取结果为全类名
String className=class.getSimpleName();//获取简单类名
- 获取Field
Field field=class.getField("属性名");//通过属性名获取public的属性
Field[] fields=class.getFields();//获取所有用public修饰的属性
Field field=class.getDeclaredField("属性名");//获取的属性包括public和private
Field[] field = c.getDeclaredFields();//获取所有属性包括public和private
- 获取Field的信息
String name=field.getName();//获取属性名
Class<?> type=filed.getType();//获取属性类型
Object value=field.get(obj);//获取obj对象field属性的值
field.set(obj,value);//设置obj对象的field属性的值
- 设置private修饰的属性为可访问
field.setAccessible(true);//默认为false只能对public修饰的操作,设置为true可对private修饰的操作
源代码分析
文件结构
在eclipse一个项目中创建一个JDBCUtils.java文件,其所需要的包和类中的成员
package step2;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class JDBCUtils {
private static Connection getConnection();
public void insert(Object obj);
public <T> List<T> selectAll(Class<T> c) ;
public void delete(Object obj) ;
public void update(Object obj) ;
public static void close(ResultSet rs,PreparedStatement ps,Connection conn);
public <T> Object selectById(Class<T> c,int id) ;
}
说明
- 注意Object对象属性名称要求和数据库中表结构字段名以及类型一致
- 默认第一个属性为主键,更改时通过第一个属性进行更改
获取数据库连接对象
private static Connection getConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String url="jdbc:mysql://localhost:3306/mysql_db";
Connection conn=null;
String user = "root";
String password = "";//数据库密码
try {
conn = DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
插入一条数据
public void insert(Object obj) {
Connection conn = getConnection(); //连接数据库
PreparedStatement ps = null;
Class<?> c = obj.getClass();
StringBuffer sb= new StringBuffer("insert into "+c.getSimpleName()+"(");
Field [] field = c.getDeclaredFields();
for(int i=0;i<field.length;i++){
if(i!=field.length-1){
sb.append(field[i].getName()).append(",");
}
else{
sb.append(field[i].getName()).append(") values(");
}
}
for(int i=0;i<field.length;i++){
if(i!=field.length-1){
sb.append("?,");
}
else{
sb.append("?);");
}
}
String sql = sb.toString();
try {
ps = conn.prepareStatement(sb.toString());
for(int i = 0; i < field.length; i++) {
field[i].setAccessible(true);//设置可以访问私有属性
ps.setObject(i+1,field[i].get(obj));
}
ps.execute();//执行sql语句
}catch (Exception e) {
e.printStackTrace();
}finally {
close(null,ps,conn);
}
}
获取数据库表所有记录
public <T> List<T> selectAll(Class<T> c) {
Connection conn = getConnection();
List<T> list = new ArrayList<T>();
Field[] field = c.getDeclaredFields();
PreparedStatement ps = null;
ResultSet rs = null;
String sql ="select * from "+ c.getSimpleName();
try {
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next()) {
T obj = (T)c.newInstance();
for(int i = 0; i < field.length; i++) {
field[i].setAccessible(true);
field[i].set(obj, rs.getObject(field[i].getName()));
}
list.add(obj);
}
} catch (Exception e) {
e.printStackTrace();
}finally {
close(rs,ps,conn);
}
return list;
}
删除一条记录
public void delete(Object obj) {
Connection conn = getConnection();
PreparedStatement ps = null;
Class<?> c = obj.getClass();//获取obj的Class
StringBuffer sb = new StringBuffer("delete from "+ c.getSimpleName() +" where ");//利用StringBuffer进行删除SQL语句的构造
Field[] field = c.getDeclaredFields();//通过反射获取对象的属性数组
sb.append(field[0].getName() + " = ?;");
String sql = sb.toString();
try {
ps = conn.prepareStatement(sql);
field[0].setAccessible(true);
ps.setObject(1, field[0].get(obj));//对预编译的SQL语句中的 ? 进行赋值
ps.execute();//执行sql语句
}catch (Exception e) {
e.printStackTrace();
}finally {
close(null,ps,conn);
}
}
修改记录
public void update(Object obj) {
Class<?> c = obj.getClass();//获取obj的Class
StringBuffer sb = new StringBuffer("update "+ c.getSimpleName() +" set ");//利用StringBuffer进行修改SQL语句的构造
Field[] field = c.getDeclaredFields();//通过反射获取对象的属性数组
for(int i = 1; i < field.length; i++) {
if(i != field.length-1) { //判断是否为最后一个属性,若不是则后增加逗号
sb.append(field[i].getName()).append("=?,");
}else { //若为最后一个属性则添加 where
sb.append(field[i].getName()).append("=? where ");
}
}
//默认第一个属性为主键,切更改时通过第一个属性进行更改
sb.append(field[0].getName() + "=?");
String sql = sb.toString()+";";
Connection conn = getConnection();//获取连接对象
PreparedStatement ps = null;
try {
ps = conn.prepareStatement(sql);
for(int i = 1; i < field.length; i++) {
field[i].setAccessible(true);//设置可以访问私有属性
ps.setObject(i, field[i].get(obj));//对预编译的SQL语句中的 ? 进行赋值
}
field[0].setAccessible(true);
ps.setObject(field.length, field[0].get(obj));
ps.execute();//执行sql语句
} catch (Exception e) {
e.printStackTrace();
}finally {
close(null,ps,conn);//关闭连接数据
}
}
获取单条记录
public <T> Object selectById(Class<T> c,int id) {
String sql = "select * from "+ c.getSimpleName()+" where id="+id;
Field[] field = c.getDeclaredFields();
Connection conn = getConnection();
PreparedStatement ps = null;
ResultSet rs = null;
Object obj=null;
try {
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
obj = c.newInstance();
while(rs.next()) {
for(int i = 0; i < field.length; i++) {
field[i].setAccessible(true);
field[i].set(obj, rs.getObject(field[i].getName()));
}
}
} catch (Exception e) {
e.printStackTrace();
}finally {
close(rs,ps,conn);
}
return obj;
}
关闭数据库对象
public static void close(ResultSet rs,PreparedStatement ps,Connection conn){
try {
if(rs!=null) rs.close();
if(ps!=null) ps.close();
if(conn!=null) conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}