create table student( int id primary key auto_increment, name varchar(30), age int, sex varchar(30) );
package com.syh.jdbc; /** * 实体类 * @author syh * */ public class Student { //学号 private int id ; //姓名 private String name ; //年龄 private int age ; //性别 private String sex ; public Student() {} public Student(int id, String name, int age, String sex) { this.id = id; this.name = name; this.age = age; this.sex = sex; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", age=" + age + ", sex=" + sex + "]"; } }
package com.syh.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * 工具类 * @author syh * */ public class JdbcUtils { public static final String DRIVER = "com.mysql.jdbc.Driver" ; public static final String URL = "jdbc:mysql://localhost:3306/itcast" ; public static final String USR = "root" ; public static final String PASSWORD = "root" ; //获取链接 public static Connection getConnection() { Connection conn = null ; try { Class.forName(DRIVER) ; conn = DriverManager.getConnection(URL, USR, PASSWORD) ; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn ; } // 释放资源 public static void close(ResultSet rs, Statement stmt, Connection conn) { try { if(null != rs) { rs.close() ; rs = null ; } if(null != stmt) { stmt.close() ; stmt = null ; } if(null != conn) { conn.close() ; conn = null ; } }catch (Exception e) { e.printStackTrace() ; } } }
package com.syh.jdbc; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.apache.commons.beanutils.PropertyUtils; /** * 数据库访问类 * @author syh * */ public class JdbcDao { /** * 根据 sql, clazz, args 返回和数据库中记录对应的一个对象 ,这个方法不能对事务进行管理 * @param <T>: 返回的对象的泛型类型 * @param sql: JDBC 查询使用的 sql 语句 * @param clazz: 返回对象对应的类型 * @param args: 填充 sql 语句中占位符的可变参数 * @return: 一个对象 */ //这里声明了一个泛型的方法 public static <T> T getBy(String sql, Class<T> clazz, Object ... args) { Object obj = null ; Connection conn = null ; PreparedStatement pstmt = null ; ResultSet rs = null ; Map<String, Object> map = new HashMap<String, Object>() ; try { conn = JdbcUtils.getConnection() ; pstmt = conn.prepareStatement(sql) ; for(int i = 0 ; i < args.length ; i ++) { pstmt.setObject(i + 1, args[i]) ; } //执行查询 rs = pstmt.executeQuery() ; // 得到描述结果集的 ResultMetaData 对象 ResultSetMetaData rsmd = rs.getMetaData() ; // 得到查询的列的数量 int columnIndex = rsmd.getColumnCount() ; //遍历结果集, 得到每一列的值. 把这些值放在一个 Map<String, Object> 中, 键为该列的名字 //看清楚这里用的是 if 而不是 while ,因为这里仅仅返回的是一条数据,所以用 if 就可以了 if(rs.next()) { for(int i = 0 ; i < columnIndex ; i ++) { Object o = rs.getObject(i + 1) ; String columnName = rsmd.getColumnName(i + 1) ; //这里一定要想清楚往 Map 对象中放的是甚么! map.put(columnName, o) ; } } // 创建 clazz 对应类的对象 obj obj = clazz.newInstance() ; // 为 obj 对应的属性赋值 for(Map.Entry<String, Object> entry : map.entrySet()) { String attrName = entry.getKey() ; Object attrValue = entry.getValue(); //方法1:通过调用工具类的方法, 调用 setter 方法为属性赋值——这里要引入 jar 包,下面提供下载 // PropertyUtils.setProperty(obj, attrName, attrValue) ; //方法2 :直接通过反射为属性(非 Java Bean 意义)赋值 //获取属性名 // Field field = clazz.getDeclaredField(attrName) ; // //抑制Java对起属性的检查 // field.setAccessible(true) ; // field.set(obj, attrValue) ; //方法3:通过反射调用 setter 方法 //1). 获取方法名,通过 拼字符串的方式 String methodName = "set" + attrName.toUpperCase().substring(0, 1) + attrName.substring(1) ; //2). 获取方法的参数类型,是通过获取类的属性得到其相应的类型 Field field = clazz.getDeclaredField(attrName) ; //抑制 Java 对属性的检查 field.setAccessible(true) ; Class<?> type = field.getType() ; //3). 获取方法并传入参数 Method method = clazz.getDeclaredMethod(methodName, type) ; //4). 调用 setter 方法,将要设置的属性值 set 进去 method.invoke(obj, attrValue) ; } } catch (Exception e) { e.printStackTrace(); } return (T) obj ; } /** * 这个方法的功能有——INSERT UPDATE DELETE * @param sql: SQL 语句 * @param args: 传进来的参数 */ public static void update(String sql, Object ... args) { Connection conn = null ; PreparedStatement pstmt = null ; try { conn = JdbcUtils.getConnection() ; pstmt = conn.prepareStatement(sql) ; if (null != args){ for(int i = 0 ; i < args.length ; i ++) { pstmt.setObject(i + 1, args[i]) ; } } pstmt.executeUpdate() ; } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.close(null, pstmt, conn) ; } } }
package com.syh.jdbc; import static org.junit.Assert.*; import org.junit.Test; /** * 测试类 * @author syh * */ public class JdbcDaoTest { @Test public void testGetBy() { //根据 id 找到相应的 Student 对象 // int id = 3 ; // String sql = "SELECT id, name, age, sex FROM student WHERE id = ?" ; // Student stu = JdbcDao.getBy(sql, Student.class, id) ; // System.out.println(stu); //根据 name 找到相应的 Student 对象 String name = "BOb"; String sql2 = "SELECT id, name, age, sex FROM student WHERE name = ?" ; Student stu2 = JdbcDao.getBy(sql2, Student.class, name) ; System.out.println(stu2); } @Test public void testUpdate() { // String sql = "INSERT INTO student (name, age, sex) VALUES (?, ?, ?)" ; // JdbcDao.update(sql, "Mike", 21, "Male") ; // String sql = "UPDATE student SET age = age + 1" ; // JdbcDao.update(sql) ; String sql = "DELETE FROM student WHERE id = ?" ; JdbcDao.update(sql, 2) ; } }