所有的CRUD的功能实现 1. 获得连接 2. 准备sql 3. 预编译sql(将sql发送到数据库中) 4. 占位符进行赋值---->麻烦 5. 执行sql executeUpdate()/executeQuery() 6. dql: select rs.get ---->麻烦
public static7.2 概念T findOne(String sql, Class tClass, Object... params) { Connection connection = getConn(); T t = null; try { PreparedStatement statement = connection.prepareStatement(sql); //占位符赋值 int length = params.length; for (int index = 0; index < length; index++) { statement.setObject((index + 1), params[index]); } //执行sql ResultSet rs = statement.executeQuery(); if (rs.next()) { //创建对象的方式: 反射 t = tClass.getDeclaredConstructor().newInstance(); //查询的临时表的数据在rs对象中 //需要将指定的行记录转换成指定的对象 //在rs里面: 获得查询的列 查询列对应的数据 ResultSetmetaData metaData = rs.getmetaData(); int columnCount = metaData.getColumnCount();//查询列数 for (int i = 1; i <= columnCount; i++) { String columnName = metaData.getColumnName(i);//获得每列的名称 //获得每个列的具体的数据类型---->java语言里面具体的类型 String columnClassName = metaData.getColumnClassName(i); //获得每列的数据 Object columnValue = rs.getObject(i); //列的数据赋值给类属性----> private set //调用set方法进行对属性赋值 setId setName setPassword setUserImage StringBuilder methodName = new StringBuilder("set"); String[] array = columnName.split("_"); for (String str : array) { String firstChar = String.valueOf(str.charAt(0)); str = str.replaceFirst(firstChar, firstChar.toUpperCase()); methodName.append(str); } // System.out.println(columnName + "=====" + columnValue + "-----" + columnClassName+"----"+ Arrays.toString(array)+"----"+methodName); //调用这个方法 类名.静态方法 / 引用.方法 //使用反射的知识点 唤醒方法 invoke指定的方法 -----> Class //反射的基础是 Class //获得Class类对象的3种方式: getClass 类名.class Class.forName() //根据指定的方法名 调用方法 //public Method getDeclaredMethod(String name, Class>... parameterTypes) name:方法名 parameterTypes:方法的参数类型 if (columnClassName.contains("Date") || columnClassName.contains("Timestamp")) { columnClassName = "java.util.Date"; } Method method = tClass.getDeclaredMethod(methodName.toString(), Class.forName(columnClassName));//一个方法就封装成method对象 //调用方法 //public Object invoke(Object obj, Object... args) obj: 对象 args:实参 应该是列的数据 method.invoke(t, columnValue); } } } catch (Exception throwables) { throwables.printStackTrace(); } return t; }
java语言具有动态性。
java语言 不是一门动态的语言。 有反射机制,java有动态性。 动态语言: 在程序运行期间 可以使用一些技术更改整个类的结构。 动态性: 在程序运行期间 可以内省整个class文件的里面的所有的内容。 首先,反射机制极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力。 其次,通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类。 再次,使用反射机制能够在运行时构造一个类的对象、判断一个类所具有的成员变量和方法、调用一个对象的方法。 最后,反射机制是构建框架技术的基础所在,使用反射可以避免将代码写死在框架中。 缺点: 1. 性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。 2. 使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键
7.3 操作换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语
把class文件分割以下几个部分: //1.属性----Field //2.方法----Method //3.构造----Constructor1. 操作属性
private static void testField() {
//反射操作属性: 取值/赋值----> Class
//1.必须获得Class对象
// 对象.getClass();
// 类名/接口.class
// Class.forName(String path)
try {
Class> aClass = Class.forName("com.javasm.reflect.Animal");
//使用反射创建Animal对象----> 默认调用无参构造
//Object instance = aClass.newInstance();
Constructor> constructor = aClass.getDeclaredConstructor(int.class, String.class);
constructor.setAccessible(true);
Object newInstance = constructor.newInstance(11111, "张三");
System.out.println(newInstance);
//num进行取值/赋值
Field field = aClass.getDeclaredField("num");
System.out.println(field);
field.setAccessible(true);
//public Object get(Object obj) obj:具体类型的对象
Object data = field.get(newInstance);
System.out.println(data);
//field.set(instance,1000);
//System.out.println(field.get(instance));
} catch (Exception e) {
e.printStackTrace();
}
}
2. 操作方法
private static void testMethod() {
try {
//使用反射技术调用myMethod
Class aClass = (Class) Class.forName("com.javasm.reflect.Animal");
Animal animal = aClass.getDeclaredConstructor().newInstance();
Method myMethod = aClass.getDeclaredMethod("myMethod", String.class);
Object returnData = myMethod.invoke(animal, "张三");
System.out.println(returnData);
} catch (Exception e) {
e.printStackTrace();
}
}
8. DBUtils
简化JDBC操作。
所有的CRUD的功能实现 1. 获得连接 2. 准备sql 3. 预编译sql(将sql发送到数据库中) 4. 占位符进行赋值---->麻烦 5. 执行sql executeUpdate()/executeQuery() 6. dql: select rs.get ---->麻烦----> 将每一行记录自动的装配成对象8.0 常用API
1. QueryRunner sql执行器
执行任意一条sql语句。
1.1 常用构造
public QueryRunner(DataSource ds) {
super(ds);
}
1.2 常用方法
int update(Connection conn, String sql, Object... params);
执行DMLsql 返回值是受影响记录数。
T query(String sql, ResultSetHandler rsh, Object... params)
2. DbUtils 工具类。 里面封装了一些释放资源以及与事务相关的方法。 void closeQuietly(Connection conn);关闭连接
3. ResultSetHandler: 将ResultSet里面的每一行记录装配成指定的类对象 反射 public interface ResultSetHandler8.1 新增{ T handle(ResultSet rs) throws SQLException; } ScalarHandler: 将指定1列的数据转换成对象。 一行一列 count last_insert_id max min avg sum
@Override
public int addUserInfo(UserInfo userInfo) throws SQLException {
Connection connection = DBUtil.getConn();
//执行sql: 结构化查询语言
//对于DBUtils而言 所有的sql语句执行 都必须使用QueryRunner进行执行sql
//1. 更新 DML INSERT DELETE UPDATE executeUpdate() update()
//2. 查询 DQL SELECT executeQuery() query()
int result = new QueryRunner().update(connection, UserInfoSql.ADD_USER_SQL,
userInfo.getName(),
userInfo.getGender(),
userInfo.getPhone(),
userInfo.getAge(),
userInfo.getBalance(),
userInfo.getPassword(),
userInfo.getBirthday(),
userInfo.getUserImage());
//在DBUtils.jar里面 提供一个工具类 DBUtils
DbUtils.closeQuietly(connection);
return result;
}
9. 数据库连接池
打开一次连接 操作使用一次 就释放资源。 资源很浪费。
9.1 原理 9.2 使用在程序运行期间 多次重复有效的使用可用的连接对象? 实现资源的重复利用率、
https://mvnrepository.com/artifact/com.alibaba/druid/1.2.8



