1. jdbc介绍
jdbc其实就是一个接口,这个接口规定了连接数据库的一些规则,因为在我们实际的开发当中会有各种各样的数据库,我们不可能在开发中安装每一个不同的数据库驱动。因此sun公司就制定了一套规则,这套规则就是用来java和数据连接,只需对应的每个数据库公司实现这个规则就可了。这个规则就是我们要讲的jdbc技术。
常用的类和接口:
DriverManger 驱动管理类
Connection数据连接接口
Statement(接口) 向数据库发送要执行的sql语句
ResultSet(接口) 结果集 Statement执行完sql语句得到的结果保存在Result当中
2. jdbc使用
1、注册驱动
Class.forName("com.mysql.jdbc.Driver");
2、获取数据连接
String url = "jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC";
Connection con = DriverManager.getConnection(url,"root","root");
getConnection的三个参数代表的意思:
第一个参数 数据的链接地址和库名
jdbc:mysql://localhost:3306/mybatis 这种是最简单的写法 mybatis代表的是你数据库的库名字,3306代表的数据库的端口号,我的数据库是mysql数据库因此连接的端口就是3306,如果你不是mysqll数据那么就写你对应数据库的端口号(每种数据库都有其固定的端口号,可以百度出来)
第二参数和第三个参数依次代表数据库的账号和密码 我的账号和密码都是root
3、创建向数据库发送sql的statement对象
因为statement有安全隐患,在这里我们使用带有预编译的PreparedStatement 这种方法比较安全。
String sql = "select * from tb_studnets";
PreparedStatement pre = con.prepareStatement(sql);
4、返回结果集
ResultSet res = pre.executeQuery()
注意 executeQuery只针对select语句有效
初学者最好直接使用下面的方法
pre.execute();
5、关闭连接
con.close();
切记一定要关闭,不关闭在实际项目的当中会导致数据库无法连接的情况。
3. 增删改查
1、编写工具类
在使用jdbc有一些代码每次都需要写一遍,但是他们的内容是一样的,可以提取出来写在一个工具类中使用
public class JDBCUtils {
public static Connection connection() throws Exception {
String url = "jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC";
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url,"root","root");
return con;
}
}
工具类的内容都是重复内容,以后我们在使用的时候只需要直接使用工具类的方法即可
2、查询数据
代码示例
public void queryStudent() throws Exception {
String sql = "select * from tb_studnets";
Connection con = JDBCUtils.connection();
PreparedStatement pre = con.prepareStatement(sql);
pre.execute();
ResultSet res = pre.getResultSet();
while(res.next()){
String name = res.getString("name");
String Gender = res.getString("gender");
System.out.println(name+"======"+Gender);
}
con.close();
}```
name和gender是数据库中对应两列的列名称,因为查询的结果不是一个,因此需要一个循环将所有的查询结果遍历出来
res.next()作用就是让游标指向当前行的数据。每使用一次游标向下移动一次
也可以使用select专有的方法executeQuery()
```java
public void queryStudent2() throws Exception {
String sql = "select * from tb_studnets";
Connection con = JDBCUtils.connection();
PreparedStatement pre = con.prepareStatement(sql);
ResultSet res = pre.executeQuery();//发送并执行sql语句 并且直接获取到结果
while(res.next()){
String name = res.getString("name");
String Gender = res.getString("gender");
System.out.println(name+"======"+Gender);
}
con.close();
}
如果有需要的话可以将查询的结果封装在一个集合当中,
首相创建一个类,while循环当中利用这个类的setter方法将获取得到的列值添加到对应的属性中,将所有的属性添加完毕,在将这个类添加到对应集合中。
假设数据有如下数据
创建其对应的保存类
public class Course {
public Integer Cno;
public Integer Cpno;
public Integer getCno() {
return Cno;
}
public void setCno(Integer cno) {
Cno = cno;
}
public Integer getCpno() {
return Cpno;
}
public void setCpno(Integer cpno) {
Cpno = cpno;
}
@Override
public String toString() {
return "Course{" +
"Cno=" + Cno +
", Cpno=" + Cpno +
'}';
}
}
查询数据保存到list中
public void queryCourse() throws Exception {
List<Course> list = new ArrayList<>();
Course course = new Course();
String sql = "select * from Course";
Connection con = JDBCUtils.connection();
PreparedStatement pre = con.prepareStatement(sql);
ResultSet res = pre.executeQuery();//发送并执行sql语句 并且直接获取到结果
while(res.next()){
int cno = res.getInt("Cno");
int Cpno = res.getInt("Cpno");
course.setCno(cno);
course.setCpno(Cpno);
list.add(course);
}
System.out.println(list);
con.close();
}
运行结果:
可以看出查询得到的结果成功保存到list当中
3插入数据
public void insertStudent() throws Exception {
String sql = "insert into course(cno,cpno) value (?,?)";
Connection con = JDBCUtils.connection();
PreparedStatement pre = con.prepareStatement(sql);
for(int i=3;i<8;i++){
pre.setInt(1,i);
pre.setInt(2,i+1);
pre.execute();
}
con.close();
}
使用?占位符
pre.setInt(1,i); 1代表第一个? 将i插入
4删除数据
public void deleteStudent() throws Exception {
String sql = "delete from course where cno=?";
Connection con = JDBCUtils.connection();
PreparedStatement pre = con.prepareStatement(sql);
for(int i=3;i<8;i++){
pre.setInt(1,i);
pre.execute();
}
con.close();
}
5更新数据
public void updateStudent(Integer cno,Integer cpno) throws Exception {
String sql = "update course set Cpno=? where Cno=?";
Connection con = JDBCUtils.connection();
PreparedStatement pre = con.prepareStatement(sql);
pre.setInt(1,cpno);
pre.setInt(2,cno);
pre.execute();
con.close();
}
拓展知识
实现分页查询:
实质就是利用sql语句进行了条件限定
4. 利用配置文件读取内容
利用property进行参数的读取
首先创建一个 jdbc.properties
内容如下
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&serverTimezone=UTC
username=root
password=root
driver=com.mysql.jdbc.Driver
修改工具类中的代码
public static Connection connection1() throws Exception {
Properties pro = new Properties();
//InputStream in = JDBCUtils.class.getResourceAsStream("jdbc.properties");
ClassLoader cl = JDBCUtils.class.getClassLoader();
InputStream inStream = cl.getResourceAsStream("com/tyut/MyJDBC/jdbc.properties");
pro.load(inStream);
String url = (String) pro.get("url");
String driver = (String) pro.get("driver");
String username = (String) pro.get("username");
String password = (String) pro.get("password");
Class.forName(driver);
Connection con = DriverManager.getConnection(url,username,password);
return con;
}
经过测试发现,依然能够使用。
这里的难点主要是使用类加载器读取配置文件的问题
具体可以参考文章
https://blog.csdn.net/csdn__wang/article/details/119652667
5. 编码问题以及版本的问题
1、版本问题
使用mysql6版本以下的注册驱动器使用
com.mysql.jdbc.Driver
而使用6版本以上mysql数据使用
com.mysql.cj.jdbc.Driver
2、时区问题
有时发现自己检查了好几遍,所有问题都检查了,任然还是有问题,这是就需要注意时区的问题了
jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
可以在连接的url后面添加serverTimezone=UTC
3、乱码问题
主要针对中文出现的乱码
原因有以下3种:
1、项目编码
一般统一编码为utf-8
2、数据库编码
创建库的时候就应该将编码修改成为utf-8
3、传输问题
可能在传输过程出现问题
解决方法
url后面添加?useSSL=true&useUnicode=true&characterEncoding=UTF-8
修改成为如下的格式
jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8