JDBC程序编写步骤
1.1方式一、用Dirver接口
Driver driver=new com.mysql.jdbc.Driver();
//jdbc:mysql的协议
//localhost:ip地址
//3306:默认MySQL的端口号
//test:数据库
String url="jdbc:mysql://localhost:3306/test";
//Perperties接口用于读取配置文件,以键值对的形式出现;
Properties properties=new Properties();
properties.setProperty("user","root");
properties.setProperty("password","123456");
Connection connect = driver.connect(url,properties);
System.out.println(connect);
1.2方式二:对方式一的迭代、在如下程序中不出现第三方的api让程序有更好的移植性
//用反射的方式获取实现类对象
Class> aClass = Class.forName("com.mysql.jdbc.Driver");
//用newInstance调用Driver的空参构造器
Driver o = (Driver) aClass.newInstance();
String url="jdbc:mysql://localhost:3306/test";
Properties properties = new Properties();
properties.setProperty("user","root");
properties.setProperty("password","123456");
Connection connect = o.connect(url, properties);
System.out.println(connect);
1.3方式三:使用DriverManager 替换Driver
//获取Dirver的对象
Class> aClass = Class.forName("com.mysql.jdbc.Driver");
Driver o = (Driver) aClass.newInstance();
//注册驱动
DriverManager.registerDriver(o);
//获取链接
String url="jdbc:mysql://localhost:3306/test";
String password="123456";
String user="root";
Connection connection = DriverManager.getConnection(url, user,password);
System.out.println(connection);
1.4方法四:对方法三进行优化可以省略注册驱动
//加载Dirver的对象
Class.forName("com.mysql.jdbc.Driver");
//注册驱动
//省略原因:在mysql的Driver类中实现了自动加载驱动
// DriverManager.registerDriver(o);
//获取链接
String url="jdbc:mysql://localhost:3306/test";
String password="123456";
String user="root";
Connection connection = DriverManager.getConnection(url, user,password);
System.out.println(connection);
1.5方法五:将数据库连接需要的4个基本信息声明在配置文件中,通过读取配置文件的方式获取连接
//好处:1、事项了数据和代码的分离,实现了解耦
//通过类加载器来获取配置文件的信息.
##这是jdbc.properties文件: url=jdbc:mysql://localhost:3306/test password=123456 user=root driverClass=com.mysql.jdbc.Driver
//通过类加载器来获取配置文件的信息.
InputStream is = ConnectionTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
//加载到Properties的load方法来读取出来
Properties properties = new Properties();
properties.load(is);
//properties是通过键值对的方式获取值
String url = properties.getProperty("url");
String password = properties.getProperty("password");
String user = properties.getProperty("user");
String driverClass = properties.getProperty("driverClass");
//加载驱动
Class.forName(driverClass);
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println(connection);
二、使用PreparedStatement实现CRUD操作
2.1、使用Statement操作数据表的弊端
- 存在拼串操作,繁琐
- 存在SQL注入问题(SQL注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的SQL语句段,从而利用系统的SQL系统完成恶意行为的做法)
SQL注入问题:对于JAVA而言,要防范SQL的注入,只要用PreparedStatement(从Statement扩展而来)取代Statemet就可以了。
2.2、preparedStatement实现CRUD操作
通用版本
public void Update_test(String sql,Object ... test) throws Exception {//test表示表示?的个数
Connection lianjie = internet.lianjie();
PreparedStatement preparedStatement = lianjie.prepareStatement(sql);
for (int i = 0; i < test.length; i++) {
preparedStatement.setObject(i+1,test[i]);
}
preparedStatement.execute();
lianjie.close();
preparedStatement.close();
}
public void cs() throws Exception {
String sql="delete from customers where id=?";
Update_test(sql,24);
}
2.3、preparedStatement实现查询操作
注意:在java中的select中回返回查询的结果集,我们用一个类来充当.
ORM思想:
- 一个数据表对应一个java类
- 表中的一条记录对应java类的一个对象
- 表中的一个字段对应java类的一个属性
代码:
public user_table get_Select(String sql,Object ...text) throws SQLException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
Connection mysql = Add_Mysql.get_Mysql();
PreparedStatement preparedStatement = mysql.prepareStatement(sql);
for (int i = 0; i < text.length; i++) {
//填充占位符
preparedStatement.setObject(i + 1, text[i]);
}
ResultSet resultSet = preparedStatement.executeQuery();
//获取结果集的元数据(String name="TOM",那么String和name就是“TOM”的元数据)
ResultSetmetaData metaData = resultSet.getmetaData();
//通过元数据获取结果中的列数
int columnCount = metaData.getColumnCount();
//将结果集取出来,赋值在类中
if (resultSet.next()) {
user_table user = new user_table();
for (int i = 0; i < columnCount; i++) {
//通过resultSet获取select每个字段值
Object value = resultSet.getObject(i + 1);
//通过元数据获取每一个列的列名getColumnName(不推荐使用)
//或得别名getColumnLable
String catalogName = metaData.getColumnName(i+1);
//给user_table的某一个字段赋上value的值
Field declaredField = Class.forName("jdbc.user_table").getDeclaredField(catalogName);
declaredField.setAccessible(true);
//将数据赋值给那个对象
declaredField.set(user, value);
}
return user;
}
return null;
}
public static void main(String[] args) throws ClassNotFoundException, SQLException, IllegalAccessException, NoSuchFieldException {
Select_text select_text = new Select_text();
String sql="select user,password,balance from user_table where user=?";
user_table select = select_text.get_Select(sql,"BB");
System.out.println(select);
}
查询注意事项
针对于表的字段名和属性名不相同的情况下
1、必须声明sql是,使用类属性命名来命名字段的别名
2、使用Resultsetmetate是,需要使用getColumnLabel()来替换getColumName()获取列的别名
3、如果sql没有sql中没有给字段其别名,getColumnLabel获取就是列名
针对不同表的查询代码:
publicT Select ( Class clazz,String sql,Object ...text) throws Exception { Connection connection = And_Mysql(); PreparedStatement preparedStatement = connection.prepareStatement(sql); for (int i = 0; i < text.length; i++) { preparedStatement.setObject(i+1,text[i]); } ResultSet resultSet = preparedStatement.executeQuery(); ResultSetmetaData metaData = resultSet.getmetaData(); int columnCount = metaData.getColumnCount(); while(resultSet.next()){ //通过反射或得不同的表 T t = clazz.newInstance(); for (int i = 0; i < columnCount; i++) { Object object = resultSet.getObject(i + 1); String columnLabel = metaData.getColumnLabel(i + 1); Field declaredField = Class.forName("jdbc.User").getDeclaredField(columnLabel); declaredField.setAccessible(true); declaredField.set(t,object); } return t; } return null; }
查询多条字段
*/
public List Select (Class clazz, String sql, Object ...text) throws Exception {
Connection connection = And_Mysql();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < text.length; i++) {
preparedStatement.setObject(i+1,text[i]);
}
ResultSet resultSet = preparedStatement.executeQuery();
ResultSetmetaData metaData = resultSet.getmetaData();
int columnCount = metaData.getColumnCount();
//将查询的数据用添加到列表中最后返回在列表中
ArrayList 


