前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >猿进化系列12——一文快速学会数据库访问

猿进化系列12——一文快速学会数据库访问

作者头像
山旮旯的胖子
发布2020-07-28 16:45:59
3930
发布2020-07-28 16:45:59
举报
文章被收录于专栏:猿人工厂猿人工厂

看完上一个章节,相信你已经掌握了MYSQL数据库的基本操作,以及SQL的基本写法,可是你只会用图形化工具编写和执行SQL,而在实际的程序开发中,你是需要用程序来操作数据库的,今天我们就来学习下JAVA访问数据库的姿势。

之前我们学习了数据库的基本操作,JAVA的基本语法和一些常用的API。学习web开发,需要从数据库里动态的获取数据,需要现在我们来学习使用JAVA相关的知识来访问数据库。

JAVA通过什么来访问数据库呢?常规套路是使用JDBC来访问。JDBC是JAVAEE定义的数据库访问规范,它定义了数据库访问接口,具体的实现由各个数据库厂商去完成。JDBC仅仅是定义了接口,但是要操作数据库,还需要实现类去完成,也就是数据库驱动去完成。每个厂商都会去完成各自的数据库驱动实现,比如我们使用的MYSQL数据库,它的数据库厂商,也就是oracle,会去提供数据库驱动。使用JAVA操作数据库,我们只要会调用JDBC的方法就可以了。

看到没?这就是规范的发展套路,你不实现我就不支持你访问,你要卖数据库,要想有人用你的数据库你必须要有驱动,要不然没人用。ODBC为啥渐渐的被人忘记,因为大家支持了SUN,不过对于猿人来说也是有好处的:

1.咱们只用关心接口就好,屏蔽了个厂商之间数据库通信的细节

2.面向接口编程(想想面向对象思想那一章,用接口的好处了吧,多态呀多态无处不在),编写一套代码,用较小的修改(是不可能滴,SQL方言不一样哒)就能访问其他支持JDBC的数据库。

使用JDBC访问数据库的步骤如下:

1. 引入数据库驱动相关的jar包

在pom.xml中增加

<!--mysql驱动-->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<version>5.1.26</version>

<scope>compile</scope>

</dependency>

(maven自动帮我们下载)

2. 注册驱动

3. 创建数据库连接(Connection)

4. 定义sql

5. 创建执行sql语句的对象 PreparedStatement

6.设置PreparedStatement的参数

7. 执行sql,接受返回结果

8. 处理数据库返回结果 ResultSet

9. 释放资源

根据ID查询学生记录:

public class JDBCCRUDDemo { private static void queryStudentById(Long id) throws SQLException{ Connection connection = null; ResultSet rs = null; PreparedStatement ps=null; try{ //1)注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2) 得到连接对象 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test01","root","123456"); //sql无需区分大小写 String sql="select * from student where ID = ?"; //3) 得到语句对象 ps = connection.prepareStatement(sql); //4)设置参数,parameterIndex 注意:index从1开始算起 1代表第一个参数,即第一个问号 ps.setLong(1,id); //5) 执行SQL语句得到结果集ResultSet对象 rs = ps.executeQuery(); //6) 循环遍历取出每一条记录 while(rs.next()) { Long dbId = rs.getLong("id"); String name = rs.getString("name"); int sex = rs.getInt("sex"); Date birthday = rs.getDate("admission_date"); String remark = rs.getString("remark"); //7) 输出的控制台上 System.out.println("编号:" + dbId + ", 姓名:" + name + ", 性别:" + sex + ", 入学日期:" + birthday+",备注:"+remark); } }catch(Exception e){ e.printStackTrace(); } finally{ //8) 释放资源 一定要牢记 if(null!=rs){ rs.close(); } if(null!=ps){ ps.close(); } if(null!=connection){ connection.close(); } } } public static void main(String args[]){ try { queryStudentById(2L); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

新增学生记录:

private static void addStudent(String name,int sex,Date admissionDate,String remark ) throws SQLException{ Connection connection = null; int rows = 0; PreparedStatement ps=null; try{ //1)注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2) 得到连接对象 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test01?characterEncoding=utf8","root","123456"); //sql无需区分大小写 String sql="insert into student(name,sex,admission_date,remark) values(?,?,?,?)"; //3) 得到语句对象 ps = connection.prepareStatement(sql); //4)设置参数,parameterIndex 注意:index从1开始算起 1代表第一个参数,即第一个问号 ps.setString(1,name); ps.setInt(2,sex); ps.setDate(3,new java.sql.Date(admissionDate.getTime())); ps.setString(4,remark); //5) 执行SQL语句得到结果集ResultSet对象 rows = ps.executeUpdate(); //6) 循环遍历取出每一条记录 //7) 输出的控制台上 System.out.println("插入记录条数:" +rows); }catch(Exception e){ e.printStackTrace(); } finally{ //8) 释放资源 一定要牢记 if(null!=ps){ ps.close(); } if(null!=connection){ connection.close(); } } }

按ID修改学生记录:

private static void updateStudent(String name,int sex,Date admissionDate,String remark,Long id ) throws SQLException{ Connection connection = null; int rows = 0; PreparedStatement ps=null; try{ //1)注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2) 得到连接对象 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test01?characterEncoding=utf8","root","123456"); //sql无需区分大小写 String sql="update student set name=?, sex=? ,admission_date=? ,remark =? where id=?"; //3) 得到语句对象 ps = connection.prepareStatement(sql); //4)设置参数,parameterIndex 注意:index从1开始算起 1代表第一个参数,即第一个问号 ps.setString(1,name); ps.setInt(2,sex); ps.setDate(3,new java.sql.Date(admissionDate.getTime())); ps.setString(4,remark); ps.setLong(5, id); //5) 执行SQL语句得到结果集ResultSet对象 rows = ps.executeUpdate(); //6) 循环遍历取出每一条记录 //7) 输出的控制台上 System.out.println("修改记录条数:" +rows); }catch(Exception e){ e.printStackTrace(); } finally{ //8) 释放资源 一定要牢记 if(null!=ps){ ps.close(); } if(null!=connection){ connection.close(); } } }

按ID删除学生记录:

private static void deleteStudent(Long id ) throws SQLException{ Connection connection = null; int rows = 0; PreparedStatement ps=null; try{ //1)注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2) 得到连接对象 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test01?characterEncoding=utf8","root","123456"); //sql无需区分大小写 String sql="delete from student where id=?"; //3) 得到语句对象 ps = connection.prepareStatement(sql); //4)设置参数,parameterIndex 注意:index从1开始算起 1代表第一个参数,即第一个问号 ps.setLong(1, id); //5) 执行SQL语句得到结果集ResultSet对象 rows = ps.executeUpdate(); //6) 循环遍历取出每一条记录 //7) 输出的控制台上 System.out.println("删除记录条数:" +rows); }catch(Exception e){ e.printStackTrace(); } finally{ //8) 释放资源 一定要牢记 if(null!=ps){ ps.close(); } if(null!=connection){ connection.close(); } } }

什么是数据库连接池?数据库连接池是存放数据库连接的容器,当容器被创建后,会向数据库申请数据库连接资源。我们从数据库连接池里获取数据库连接使用完毕后,会将连接还给容器。好处:

连接池复用了数据库连接,减少了访问数据库时,创建连接的开销,提高了程序的访问效率。

数据库连接池原理:

实现javax.sql包下的DataSource接口

获取数据库连接使用:

获取连接:getConnection()

归还连接:Connection.close()注意,使用数据库连接,不会关闭连接,而是归还。

一般来说,我们不用自己去实现数据库连接池,有很多很成熟的第三方产品可以使用。这里推荐阿里巴巴开源的Druid。

接下来我们看看怎么来使用它:

1.引入jar包

在pom.xml文件中增加

<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.9</version> </dependency>

2.定义配置文件

在src/main/resources下新建文件druid.properties

在文件中增加内容

driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/test01?characterEncoding=utf8 username=root password=123456 initialSize=5 maxActive=10 maxWait=3000

说明:

driverClassName驱动名称 MYSQL 使用com.mysql.jdbc.Driver

url数据库访问url

username数据库用户名

password数据库密码

initialSize 初始化连接数

maxActive 最大活动连接数

maxWait 数据库访问超时时间 毫秒

我们再简单地封装数据库访问工具类:

package com.pz.web.demo.Util; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class JDBCUtils { // 1. 声明静态数据源成员变量 private static DataSource dataSource; // 2. 创建连接池对象 static { // 加载配置文件中的数据 InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"); Properties pp = new Properties(); try { pp.load(is); // 创建连接池,使用配置文件中的参数 dataSource = DruidDataSourceFactory.createDataSource(pp); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } // 3. 定义公有的得到数据源的方法 public static DataSource getDataSource() { return dataSource; } // 4. 定义得到连接对象的方法 public static Connection getConnection() throws SQLException { return dataSource.getConnection(); } // 5.定义关闭资源的方法 public static void close(Connection conn, Statement stmt, ResultSet rs) { if (rs != null) { try { rs.close(); } catch (SQLException e) {} } if (stmt != null) { try { stmt.close(); } catch (SQLException e) {} } if (conn != null) { try { conn.close(); } catch (SQLException e) {} } } // 6.重载关闭方法 public static void close(Connection conn, Statement stmt) { close(conn, stmt, null); } }

Spring JDBC 是Spring框架对jdbc的模板封装,能够简化数据访问的开发,支持使用对象访问数据库。

我们看看使用Spring JDBC 访问数据库的步骤:

1.引入依赖

<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.1.2.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.1.2.RELEASE</version> </dependency>

2.创建JdbcTemplate对象

3.使用JdbcTemplate提供的相关方法,访问数据库。JdbcTemplate支持以对象的方式访问数据库,数据库里的一条记录是唯一的,对象也是唯一的,我们可以简单的把数据库里的字段名,看作是domain类的属性名,数据库里的一行记录,看作是一个domain类的一个实例。

由于JdbcTemplate支持对象和查询结果集字段的小驼峰匹配或者是完全匹配,建议domain类命名遵循和数据库字段的小驼峰匹配规则(首字母小写如果遇到下划线,则每一个下划线后第一个字母大写)。

我们看到student表的字段如下:

所以我们定义的domian类如下:

package com.pz.web.demo.domain; import java.util.Date; /** * * @author pangzi * 字段名和数据库字段命名规则 * 由于JdbcTemplate支持对象和查询结果集字段的小驼峰匹配或者是完全匹配, * 建议domain类命名遵循和数据库字段的小驼峰匹配规则 * */ public class Student { /** * id编号 */ private Long id; /** * 姓名 */ private String name; /** * 性别 */ private int sex ; /** * 年龄 */ private int age ; /** * 入学日期 */ private Date admissionDate; /** * 备注 */ private String remark; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getSex() { return sex; } public void setSex(int sex) { this.sex = sex; } public Date getAdmissionDate() { return admissionDate; } public void setAdmissionDate(Date admissionDate) { this.admissionDate = admissionDate; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + ", admissionDate=" + admissionDate + ", remark=" + remark + "]"; } }

JdbcTemplate提供的数据访问方法如下:

queryForObject:将查询结果封装为对象,注意查询结果只能有一条记录,如果无查询结果返回,程序可能异常

queryForList():将查询结果封装为List集合。

update();用于执行dml语句,增删改。

queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value,注意查询结果只能有一条记录

package com.pz.web.demo.jdbc; import com.pz.web.demo.Util.JDBCUtils; import com.pz.web.demo.domain.Student; import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import java.sql.SQLException; import java.util.Date; import java.util.List; /** * * @author pangzi * */ public class SpringJDBCCRUDDemo { private static JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); /** * 按id查询学生信息 * @param id * @return * @throws SQLException */ private static Student queryStudentById(Long id) throws SQLException{ Student student = null; try { String sql = " select * from student where ID = ?"; student = template.queryForObject(sql, new BeanPropertyRowMapper<Student>(Student.class), id); } catch (DataAccessException e) { e.printStackTrace(); } return student; } /** * 查询所有学生记录 * @return * @throws SQLException */ private static List<Student> queryStudentList() throws SQLException{ String sql = " select * from student "; return template.query(sql,new BeanPropertyRowMapper<Student>(Student.class)); } /** * 新增学生记录 * @param student * @throws SQLException */ private static void addStudent(Student student ) throws SQLException{ String sql="insert into student(name,sex,age,admission_date,remark) values(?,?,?,?,?)"; template.update(sql,student.getName(),student.getSex(),student.getAge(),student.getAdmissionDate(),student.getRemark() ); } /** * 修改学生记录 * @param student * @throws SQLException */ private static void updateStudent(Student student) throws SQLException{ String sql="update student set name=?, sex=? ,admission_date=? ,remark =? where id=?"; template.update(sql,student.getName(), student.getSex(), student.getAdmissionDate() ,student.getRemark(), student.getId() ); } /** * 按id删除学生记录 * @param id * @throws SQLException */ private static void deleteStudent(Long id ) throws SQLException{ String sql="delete from student where id=?"; template.update(sql,id ); } public static void main(String args[]){ try { Student dbStundent=queryStudentById(2L); System.out.println(dbStundent); Student stundent = new Student(); stundent.setName("新来的"); stundent.setSex(1); stundent.setAge(18); stundent.setRemark("我用JDBCTemplate报名"); stundent.setAdmissionDate(new Date()); addStudent(stundent); dbStundent.setName("我怎么变成新来的了"); updateStudent(dbStundent); deleteStudent(8L); List<Student> allStundents=queryStudentList(); System.out.println("==所有学生记录=="); for(Student s:allStundents){ System.out.println(s); } } catch (SQLException e) { e.printStackTrace(); } } }

注意:JdbcTemplate所有方法支持的都是可变参数,参数个数是不固定的,每一个参数的传入顺序对应sql里的问号。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-03-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 猿人工厂 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档