1.最好的方式(完全版)
创建一个jdbcutils工具类,里面已经实现了创建Properties对象,创建流,加载流,获取Connection对象并返回,调用此类可以获取Connection对象。
public class jdbcutils {
private static String user="";
private static String url="";
private static String className="";
private static String password="";
static {
//1.创建Properties对象
Properties p = new Properties();
//2.创建流
FileInputStream fis = null;
try {
fis = new FileInputStream("jdbc.properties");
//3.加载流--将流加载到Properti中
p.load(fis);
//4.通过Properties读取文件中的内容
user = p.getProperty("user");
password = p.getProperty("password");
url = p.getProperty("url");
className = p.getProperty("className");
System.out.println(user + password + url + className);
} catch (IOException e) {
//将编译时异常转为运行时异常,因为若编译时出现错误则说明没有获取文件内容之类的,所以要终止运行。
throw new RuntimeException(e.getMessage());
}finally {
//5.关闭资源
if (fis!=null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static Connection getConnection() throws Exception {
//1.让Driver类中的静态代码块执行
Class.forName(className);
//3.获取Connection对象
Connection connection = DriverManager.getConnection(url, user, password);
System.out.println(connection);
return connection;
/*
}
}
*/
}
public static void close(Connection connection, PreparedStatement ps) throws SQLException {
if (connection !=null){
connection.close();
}
}
上面读取的文件内容为下图:
下面可以直接调用上面的类来实现对数据库的增删改查
public class crudd {
/*
向数据库中插入一条数据
*/
@Test
public void test1() throws Exception {
//1.获取Connection对象
Connection connection=jdbcutils.getConnection();
//2.sql语句
//?:占位符
String sql="insert into student(id,name,age,sid) value(?,?,?,?)";
//3.对sql预编译
//调用prepareStatement返回PrepareStatement对象,有了该对象就可以给占位符赋值,执行sql语句
PreparedStatement ps=connection.prepareStatement(sql);
//4.给占位符赋值
/*
setInt(int parameterIndex,int x)
parameterIndex:第几个占位符
x:赋值的内容
*/
ps.setInt(1,10);
ps.setString(2,"longge");
ps.setInt(3,20);
ps.setInt(4,100);
//5执行sql语句
int result=ps.executeUpdate();
System.out.println("共有"+result+"行数据受到影响");
//6.关闭资源
jdbcutils.close(connection,ps);
}
@Test
public void test2() throws Exception {
//1.获取Connection对象
Connection connection=jdbcutils.getConnection();
//2.sql语句
String sql="update student set id=? where name=?";
//3.预编译
PreparedStatement ps=connection.prepareStatement(sql);
//4.给占位符赋值
ps.setInt(1,9);
ps.setString(2,"longge");
//5.执行sql语句
ps.executeUpdate();
//关闭资源
jdbcutils.close(connection,ps);
}
@Test
public void test3() throws Exception {
Connection connection=jdbcutils.getConnection();
String sql="delete from student ";
PreparedStatement ps=connection.prepareStatement(sql);
ps.executeUpdate();
jdbcutils.close(connection,ps);
}
/*
*/
}
以下是JDBC的一些操作
2.通过Properties读取配置文件
@Test
public void test() throws IOException {
//1.创建Properties对象
Properties p=new Properties();
//2.创建流
FileInputStream fis = new FileInputStream("jdbc.properties");
//3.加载流--将流加载到Properti中
p.load(fis);
//4.通过Properties读取文件中的内容
String user=p.getProperty("user");
String password = p.getProperty("password");
//5.关闭资源
fis.close();
}
通过上面的方式(单元测试)来获取配置文件中的内容,因为此PropertiesDemo.java文件是在工程下面,可以直接访问文件,如果是如图的Demo.java文件用单元测试就访问不了,但若是main就可以访问到。
读取配置文件 注:在module中,若是单元测试方法那么相对路径是当前module下 若是main方法那么相对路径是当前工程下。
3.获取Connection对象
为什么要获取Connection对象?答:有了该对象才能操作数据库。
方式一:创建Driver获取Connection对象
@Test
public void test() throws SQLException {
//1.创建Driver对象 Driver作用是获取Connect方法,因为后者可以操作数据库
Driver driver = new com.mysql.jdbc.Driver();//全类名:包含包名在内的类的全名称
//2.调用方法--获取Connection对象(有了该对象才能操作数据库)
/*
connect(String url,java.util.Properties info)
url:mysql的连接地址
jdbc:mysql://localhost:3306/atguigu
jdbc:mysql:协议
localhost:mysql服务器的地址
3306:端口号
atguigu:库的名字
info:在"map"中存放MySQL的账号密码
*/
String s = "jdbc:mysql://localhost:3306/myemployees";
Properties p = new Properties();
//下面的user,password参数不能随意写,凡是提供方法,我们写参数的情况,一般参数不能随意写
p.setProperty("user", "root");//账号
p.setProperty("password", "111111");//密码
Connection connect = driver.connect(s,p);
System.out.println(connect);
}
方式二:通过DriverManager获取Connection对象
@Test
public void test2() throws SQLException {
//1.创建Driver对象
Driver driver2=new com.mysql.jdbc.Driver();
//2.将driver注册到DriverManager
DriverManager.registerDriver(driver2);
//3.获取Connection对象
String url = "jdbc:mysql://localhost:3306/myemployees";
Connection connection=DriverManager.getConnection(url,"root","111111");
System.out.println(connection);
}
方式二优化:通过静态代码块来执行方式二中的1,2步
@Test
public void test3() throws SQLException, ClassNotFoundException {
//1.让Driver类中的静态代码块执行
Class.forName("com.mysql.jdbc.Driver");
//3.获取Connection对象
String url = "jdbc:mysql://localhost:3306/myemployees";
Connection connection = DriverManager.getConnection(url, "root", "111111");
System.out.println(connection);
}
4.最终版(读取配置文件+DraveManage方式获取Connection)
最终版包含了读取配置文件+获取Connection对象
@Test
public void test4() throws SQLException, IOException, ClassNotFoundException {
//1.创建Properties对象
Properties p=new Properties();
//2.创建流
FileInputStream fis = new FileInputStream("jdbc.properties");
//3.加载流--将流加载到Properti中
p.load(fis);
//4.通过Properties读取文件中的内容
String user=p.getProperty("user");
String password = p.getProperty("password");
String url = p.getProperty("url");
String className = p.getProperty("className");
System.out.println(user+password+url+className);
//5.关闭资源
fis.close();
//1.让Driver类中的静态代码块执行
Class.forName(className);
//3.获取Connection对象
Connection connection = DriverManager.getConnection(url,user,password);
System.out.println(connection);
}
5.思考:预编译为什么要用PreparedStatement对象?
5.1什么是PreparedStatement?
PreparedStatement是表示预编译的SQL语句的对象
5.2PreparedStatement与statement的区别?(两者功能相似)
1.以前的statement的执行,是先拼接sql语句然后在一起执行。在这种情况下,如果sql语句中的变量带有了数据库的关键字,那么一并认为是是关键字,而不是普通的字符串。
2.使用prepareStatement时,预先处理给定的SQL语句并且对其进行语法检查,在SQL语句中使用?作为占位符来替代后续传进来的变量,后面进来的变量将会被看成是字符串而不会产生任何的关键字。
3.PreparedStatement对象可以防止sql注入(一些无用的甚至带有恶意的sql语句),而Statement不能防止sql注入。
5.3PreparedStatement详细介绍
传送给数据库的 SQL 语句通过一个包含两个步骤的过程来返回结果。首先准备它们,然后处理它们。借助 Statement 对象,这两个阶段对应用程序而言变成一个阶段。PreparedStatement 允许将这两个步骤分开。准备步骤在创建对象时发生,而处理步骤在对 PreparedStatement 对象调用 executeQuery、executeUpdate 或 execute 方法时发生。
如果不添加参数标记,能够将 SQL 处理分割成单独的阶段并没有意义。参数标记放在应用程序中,从而使它能够告诉数据库它在准备时并不具有特定的值,但它在处理之前提供一个值。在 SQL 语句中,参数标记是使用问号表示的。通过使用参数标记,有可能创建用于特定请求的一般 SQL 语句。例如,给定以下 SQL 查询语句:SELECT * FROM EMPLOYEE_TABLE WHERE LASTNAME = 'DETTINGER'这是一个特定的 SQL 语句,它只返回一个值;即关于名为 Dettinger 的雇员的信息。通过添加参数标记,可以使语句更为灵活:SELECT * FROM EMPLOYEE_TABLE WHERE LASTNAME = ?通过简单地将参数标记设置为某个值,可以获取关于表中的任何雇员的信息。由于前一个 Statement 示例可以只经过一次准备阶段并接着使用不同的参数值来重复地进行处理,所以 PreparedStatement 能够提供比 Statement 更高的性能。