数据库概述03(jdbc连接)

1、根据所使用的数据库管理系统下载对应的驱动jar包
最好可以版本匹配,当然考虑到优化问题,可以使用相对较高的版本
2、使用IDEA创建project项目,然后在项目中新建目录libs,将驱动jar包拷贝到libs目录下
3、右键点击jar包文件,add as library
4、JDBC基本操作步骤
- 加载驱动程序
- 创建数据库连接,必须保证及时关闭
- 提交执行SQL语句
- 接收并处理SQL的执行结果
- 关闭释放资源

4.1、加载驱动程序,需要知道对应的java.sql.Driver接口的实现类全名,这个实现类应该是驱动jar提供的
写法1:Class.forName(“com.mysql.cj.jdbc.Driver”);

写法2:new Driver();  利用IDEA提供的提示功能查找对应的实现类

4.2、创建数据库连接。一个DBMS可以提供的连接数是有限的,所以连接属于稀有资源,使用的时候打开,使用完毕必须保证即使关闭。不能依赖于垃圾回收机制。应该使用try/finally结构或者try-resources写法保证及时关闭

创建连接可以通过java提供的驱动管理器DriverManager获取,这里需要连接串、用户名和口令三个参数

连接串java实际上有对应的规范,规则为【主协议jdbc:子协议mysql:其它参数】,使用不同的数据库时连接串不相同,例如mysql的连接串为jdbc:mysql://localhost:3306/数据库名称

 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?serverTimezone=UTC", "root", "123456");

测试连接是否成功System.out.println(conn);  输出com.mysql.cj.jdbc.ConnectionImpl@6c130c45

如果数据库服务器没有启动或者连接失败,则会报出异常 Exception in thread "main" com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

如果连接的数据库不存在,则报出异常  Exception in thread "main" java.sql.SQLSyntaxErrorException: Unknown database 'test'

4.3、通过连接对象创建用于向数据库管理系统提交sql语句的语句对象

Statement
	 Statement statement = conn.createStatement();
	 int len = statement.executeUpdate("insert into tb_users(username,password) values('zhangsan','333333')");

	 一般可以将sql语句分为两个大类别,分为修改操作insert/update/delete和查询操作select。除此之外还有ddl语句
		如果是增删改操作,则使用 statement.executeUpdate(sql),返回值为int类型,表示受影响行数
		如果是查询操作,则使用statement.executeQuery(sql),返回值为结果集ResultSet类型,表示查询的结果,ResultSet中实际上存放的是一个行指针,并没有数据。所以访问数据之前不能关闭Connection

PreparedStatement

CallableStatement


为了测试编码方便创建一个用于存储登录信息的用户表
	create table if not exists tb_users(
		id bigint primary key auto_increment,
		username varchar(20) not null unique,
		password varchar(20) not null,
		birth date,
		sex boolean default 1,
		salary numeric(8,2) default 0
	)engine=innodb default charset utf8;

4.4、如果执行查询操作,则获取ResultSet结果集对象,
next()返回值为boolean类型,指针后移同时判断是否有数据,有则true,否则false
getXxx(参数)返回值为xxx类型,参数有2种写法,写法1使用序号,注意序号从1开始,一般不推荐使用,因为开发过程可能会修改表结构;写法2使用列名称。获取数据没有非按照列顺序的方式获取

注意:如果对应列的数据存储为null,则返回值为null。MySQL针对简单类型自动处理,不会出异常

ResultSet resultSet = statement.executeQuery("select * from tb_users where 1=1");
    while(resultSet.next()){
        Long id=resultSet.getLong(1);//特殊方法 getString  getObject
        String username=resultSet.getString("username");
        String password=resultSet.getObject("password").toString();
        Date birth=resultSet.getDate("birth");
        boolean sex=resultSet.getBoolean("sex");
        double salary= resultSet.getDouble("salary");
        System.out.println(id+"--"+username+":::"+password+":::"+birth+":::"+sex+":::"+salary);
    }

4.5、最后执行所有对象的关闭操作,一般遵守正向打开,逆向关闭。实际上最重要的关闭操作是Connection对象的关闭

标准编码结构1
使用try/finally保证Connection及时关闭,也可以使用try(){}的写法
public class Main {
public static void main(String[] args) {
Connection conn=null;
Statement statement=null;
try {
Class.forName(“com.mysql.cj.jdbc.Driver”);
conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/test?serverTimezone=UTC”, “root”, “123456”);
statement = conn.createStatement();
int len = statement.executeUpdate(“insert into tb_users(username,password) values(‘zhangsan’,‘333333’)”);
if (len > 0)
System.out.println(“插入成功”);
else
System.out.println(“插入失败”);
} catch(Exception e){
e.printStackTrace();
} finally {

            try {
                if(statement!=null) {
                    statement.close();
                }
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            } finally{
                if(conn!=null) {
                    try {
                        conn.close();
                    } catch (SQLException throwables) {
                        throwables.printStackTrace();
                    }
                }
            }

    }
}

}

写法2:使用try-resources写法
public class Main3 {
public static void main(String[] args) throws Exception {
new Driver();
try(
Connection connection = DriverManager.getConnection(“jdbc:mysql:///test?serverTimezone=UTC”, “root”, “123456”);
Statement statement = connection.createStatement();
) {
int len = statement.executeUpdate(“delete from tb_users where id=1”);
System.out.println(len > 0 ? “删除成功” : “删除失败”);
}
}
}

加载驱动:
Class.forName(“驱动串”);

另外写法一般不建议使用,new操作相当于Class.forName("类名称").newInstance()

 JDBC驱动器根据其实现方式分为4种类型:
	JDBC-ODBC bridge plus ODBC driver 桥接方式的驱动已经包含在java中,不需要额外下载。
	Native-API partly-Java driver

	Pure Java Driver for Database Middleware
	Direct-to-Database Pure Java Driver

使用高版本jdbc支持的驱动可以不用显式加载驱动,只要将jar包添加到构建路径中,则自动启动时加载
	META-INF/services/java.sql.Driver文件

获取连接:
可以通过驱动管理器DriverManager类获取和数据库系统的连接Connection conn=DriverManager.getConnection(“连接串”,“连接数据库的用户名称”,“对应的口令”)。连接串用于代表需要连接的数据库,连接串的标准jdbc主协议:子协议:其它部分,但是不同的数据库系统其对应的连接串不同。例如连接oracle则驱动串为oracle.jdbc.OracleDriver,连接串为jdbc:oracle:thin:@localhost:1521:test

注意:数据库连接属于稀有资源,所以需要使用时进行创建,使用完毕必须结束关闭,不能依赖于垃圾回收。建议使用try/finally或者try-resources结构

构建sql语句对象
在与特定数据库建立连接后,就可以发送SQL语句,在发送SQL语句之前需要创建一个语句对象

最古老的方式是使用Statement对象
	Statement stmt=conn.createStatement();
	ResultSet res=stmt.executeQuery("select * from tb_student");
一般不建议使用Statement对象,这个对象用于提交静态sql语句。有sql注入漏洞,建议使用Statement的子接口PreparedStatement
	select * from tb_users where username='输入的用户名' and password='输入的口令'

	可以输入数据
		select * from tb_users where username='shazi' and password='baichi' or '1'='1'

Statement对象中提供了executeQuery方法来执行查询操作,这个方法会返回查询结果集ResultSet类对象,其中包含SQL语句的查询结果
Statement对象中提供了executeUpdate方法来执行修改操作,这个方法会返回一个int值,表示sql的增删改操作所影响的数据行数

一般推荐使用PreparedStatement接口,PreparedStatement是Statement的子接口。支持动态sql和预编译功能,能够在一定程度上避免sql注入漏洞

	定义sql语句时可以使用?占位符表示形参,从左向右序号从1开始计数

String sql="insert into tb_users(username,password) values(?,?)";
    PreparedStatement prepareStatement = connection.prepareStatement(sql);  只编译一次,可以提供10条不同数据
    for(int i=0;i<10;i++) {
        prepareStatement.setString(1, "yan_"+i);  给?占位符赋值,注意类型匹配
        prepareStatement.setString(2,"pwd_"+i);
        prepareStatement.executeUpdate();
    }

CallableStatement是PreparedStatement接口的子接口,一般用于调用存储过程procedure

接收查询结果集
JDBC中使用ResultSet对象来表示查询结果集,可以理解为一个指向满足查询结果的行指针,其中并不存放实际数据,所以在使用结果集之前不能关闭连接
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(“select * from tb_student”);

遍历处理结果集
注意:连接不能关闭
ResultSet对象包含了执行查询后满足条件的所有行,提供了对应的访问方法,有一组对应的getXxx方法获取指定列的值

while(rs.next()){
	Long id=rs.getLong(1);  可以使用序号获取对应列的值
	String name=rs.getString("username");  可以使用列名称获取当前行上对应列的值
		getString 和  getObject
}

获取数据时将一行数据对应一个实体对象,将一个二维表格降维到一个一维集合

例如定义表
	create table tb_users(
		id bigint primary key auto_increment,
		username varchar(32) not null,
		password varchar(32) not null);

定义一个和tb_users表对应的类User
	public class User{
		private Long id; //和id列对应,bigint对应java.lang.Long
		private String username; //一般建议列名称和属性名称一致,但是不绝对
		private String password; 
		// get/set方法
	}

定义查询方法
	public List getAllUsers(){
		......
		whiile(rs.next()){
			User tmp=new User();
			tmp.setId(rs.getLong("id"));
			tmp.setUsername(rs.getString("username"));
			tmp.setPassword(rs.getStrign("password"));
			list.add(tmp);
		}
		......
		return list;
	}

日期类型的处理
java.util.Date是java.sql.Date的父类
java.util.Date dd=new java.sql.Date(2022-1900,9-1,23);

	java.sql.Date dd=new java.util.Date();  //语法错误
	
	java.util.Date now=new java.util.Date();
	java.sql.Date dd=new java.sql.Date(now.getTime());


针对sql操作,java.sql包提供了三种日期类型,都是java.util.Date的子类
	java.sql.Date只包含年月日  rs.getDate("birth"):java.sql.Date
	java.sql.Time只包含时分秒   rs.getTime("birth"):java.sql.Time
	java.sql.Timestamp包含年月日时分秒  rs.getTimestamp("birth"):java.sql.Timestamp

你可能感兴趣的:(MySql,数据库,mysql,java)