|
今天来看下使用JDBC连接mysql的各种方法,以及对数据的各种操作。
JDBC概述
JDBC是java提供一套用来操作数据库的接口,如下图。

获取数据库的连接
获取数据库连接的必要条件
- 保证mysql是可以正常使用的(服务是否开启)。
- 保证账号密码正确。
- 导入mysql驱动包(一定要注意版本)。
建立java工程,在工程下建libs目录,将mysql驱动包jar包放入libs,将jar设为依赖(右键选Add as Library...)。
获取数据库连接
方式一:Driver
public class JDBCDemo{
public static void main(String[] args) throws Exception{
//获取Driver类的对象,此处用的是jdbc依赖中的Driver而不是Java API中的Driver,因为jdbc的Driver已经实现了Java API的Driver,直接用即可,当然也可自己实现Java API的Driver,不过较复杂
Driver driver = new com.mysql.jdbc.Driver();
//获取Connection连接对象
/*
connect(String url, java.util.Properties info)
url:是mysql连接地址,数据库协议://数据库ip:数据库端口/数据库库名
jdbc:mysql://ip:3306/database_name
info:用来存放连接mysql的数据(账号和密码)
*/
String url = "jdbc:mysql://localhost:3306/db";
Properties properties = new Properties();
//设置账号和密码,用put和setProperty皆可
//properties.put("user","root"); //key值不能随便写只能是user
//properties.put("password","123456"); //key值不能随便写只能是password
properties.setProperty("user","root");
properties.setProperty("password","123456");
Connection connect = driver.connect(url, properties);
System.out.println(connect);
}
}方式二:DriverManager
public class JDBCDemo{
public static void main(String[] args) throws Exception{
Driver driver = new com.mysql.jdbc.Driver();
//将driver注册到DriverManager中
DriverManager.registerDriver(driver);
//通过DriverManager获取数据库连接对象
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db","root", "123456");
System.out.println(connection);
}
}
public class JDBCDemo{
public static void main(String[] args) throws Exception{
//com.mysql.jdbc.Driver中的static静态代码块中写有将Driver注册到DriverManager中,故只要让com.mysql.jdbc.Driver进行类加载就可以直接通过DriverManager获取到连接对象,所以可以像下面这样写
Class.forName("com.mysql.jdbc.Driver"); //加载参数中传的类
//获取数据库连接对象
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db","root", "123456");
System.out.println(connection);
}
}方式三:DriverManager+配置文件
配置文件jdbc.properties:
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db
username=root
password=123456读取配置文件示例:
/*
Properties是Hashtable类的子类
Properties中key和value都是String类型
可以通过Properties去读取配置文件中的内容
*/
public class PropertiesDemon{
public static void main(String[] args) throws Exception{
//读取配置文件中的内容:在项目的根目录下创建一个 xxx.properties文件
//创建Properties对象
Properties p = new Properties();
//加载流
FileInputStream fis = new FileInputStream("jdbc.properties");
p.load(fis);
//读取配置文件中的内容
String username = p.getProperty("username");
String password = p.getProperty("password");
System.out.println(username + " " + password);
//关资源
fis.close();
}
}获取数据库连接:
public class JDBCDemo{
public static void main(String[] args) throws Exception{
String driverClass = "";
String url = "";
String username = "";
String password = "";
//通过Properties读取内容
//创建Properties对象
Properties p = new Properties();
//加载流
FileInputStream fis = new FileInputStream("jdbc.properties");
p.load(fis);
driverClass = p.getProperty("driverClass");
url = p.getProperty("url");
username = p.getProperty("username");
password = p.getProperty("password");
//关资源
fis.close();
//类加载
Class.forName(driverClass);
//获取数据库连接对象
Connection connection = DriverManager.getConnection(url,username,password);
System.out.println(connection);
}
}封装JDBCUtils工具类
配置文件:
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db?rewriteBatchedStatements=true
username=root
password=123456代码:
public class JDBCUtils {
//属性有默认值,方法内没有默认值需要赋值
private static String driverClass;
private static String url;
private static String username;
private static String password;
static{
FileInputStream fis = null;
try {
//获取数据库连接对象
//通过Properties读取内容
//创建Properties对象
Properties p = new Properties();
//加载流
fis = new FileInputStream("jdbc.properties");
p.load(fis);
driverClass = p.getProperty("driverClass");
url = p.getProperty("url");
username = p.getProperty("username");
password = p.getProperty("password");
}catch (Exception e){
//终止程序的运行
e.printStackTrace();
//将编译时异常转换成运行时异常,从而终止程序的运行
throw new RuntimeException("xxxxxxxx");
}finally {
if (fis != null){
//关资源
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//获取连接对象
public static Connection getConnection(){
try {
Class.forName(driverClass);
//获取数据库连接对象
Connection connection = DriverManager.getConnection(url, username, password);
return connection;
}catch (Exception e){
e.printStackTrace();
throw new RuntimeException("获取连接失败");
}
}
//关闭资源
public static void close(PreparedStatement ps, Connection connection) {
if (ps != null){
try {
ps.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection != null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void close(PreparedStatement ps, Connection connection, ResultSet resultSet) {
close(ps,connection);
if (resultSet != null){
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}对数据库的增删改查
/*
CREATE TABLE student(
sid INT,
sname VARCHAR(20),
sage INT
)
*/
public class CRUDDemo {
//添加一条数据
@Test
public void test() throws SQLException {
//获取数据库连接对象
Connection connection = JDBCUtils.getConnection();
//预编译
//?:占位符(只能是设置数据的地方可以写成占位符)
String sql = "insert into student(sid,sname,sage) values(?,?,?)";
PreparedStatement ps = connection.prepareStatement(sql);
//给占位符赋值
/*
setInt(int parameterIndex, int x)
parameterIndex : 参数索引(第几个占位符)
x : 数据
*/
ps.setInt(1,100);
//数据可不可以设置成中文取决于表的编码集
ps.setString(2,"longge");
ps.setInt(3,20);
//执行sql
//返回值 : 有几条数据受到影响
int result = ps.executeUpdate(); //增,删,改的语句使用该方法
System.out.println("有"+result+"条数据受到影响");
//关资源
JDBCUtils.close(ps,connection);
}
//修改数据
@Test
public void test2() throws SQLException {
//获取数据库连接对象
Connection connection = JDBCUtils.getConnection();
//预编译
String sql = "update student set sid=? where sid=?";
PreparedStatement ps = connection.prepareStatement(sql);
//给占位符赋值
ps.setInt(1,10);
ps.setInt(2,100);
//执行sql语句
int result = ps.executeUpdate();
System.out.println("有"+result+"条数据受到影响");
//关闭资源
JDBCUtils.close(ps,connection);
}
//删除数据
@Test
public void test3() throws SQLException {
//获取数据库连接对象
Connection connection = JDBCUtils.getConnection();
//预编译
String sql = "delete from student where sid=?";
PreparedStatement ps = connection.prepareStatement(sql);
//给占位符赋值
ps.setInt(1,10);
//执行sql语句
int i = ps.executeUpdate();
System.out.println("有"+i+"条数据受到影响");
//关闭资源
JDBCUtils.close(ps,connection);
}
//查询数据
@Test
public void test4() throws Exception {
List<Student> students = getStudent();
for (Student s : students) {
System.out.println(s);
}
}
public List<Student> getStudent() throws Exception {
//获取数据库连接对象
Connection connection = JDBCUtils.getConnection();
//预编译
PreparedStatement ps = connection.prepareStatement(&#34;select sid,sname,sage from student&#34;);
//执行sql语句
ResultSet resultSet = ps.executeQuery(); //查询语必须执行此方法
List<Student> list = new ArrayList<>();
//遍历ResultSet
while(resultSet.next()){ //是否有数据
/*
getInt(String columnLabel):根据字段名获取对应的数据
getInt(int columnIndex):根据列的索引获取对应的数据
*/
int sid = resultSet.getInt(&#34;sid&#34;);
String sname = resultSet.getString(&#34;sname&#34;);
int sage = resultSet.getInt(&#34;sage&#34;);
//System.out.println(sid + &#34; &#34; + sname + &#34; &#34; + sage);
list.add(new Student(sid,sname,sage));
}
//关闭资源
JDBCUtils.close(ps,connection,resultSet);
return list;
}
}
//JavaBean:用来装数据对象的类叫JavaBean,此处的Student类可称为JavaBean数据库事务
事务概述
事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态。
案例
/*
AA给CC转账1000
AA 2000
CC 2000
try{
开启事务
AA -= 1000
System.out.println(1/0); //遇到异常
CC += 1000
提交(一旦提交数据不能再回滚(撤销))
}catch(Exception e){
事务回滚(撤销)
}
*/
CREATE TABLE account(
NAME VARCHAR(20),
balance INT
)代码实现
public class AccountDemo {
public static void main(String[] args) throws SQLException {
//获取数据库连接对象
Connection connection = JDBCUtils.getConnection();
PreparedStatement ps = null;
try {
//开启事务:禁止自动提交
connection.setAutoCommit(false);
//做具体的操作:执行sql语句
//预编译
String sql = &#34;update account set balance=? where name=?&#34;;
ps = connection.prepareStatement(sql);
//给占位符赋值
ps.setInt(1, 1000);
ps.setString(2, &#34;aa&#34;);
//执行sql
ps.executeUpdate();
System.out.println(1 / 0); //遇到异常
//给占位符赋值
ps.setInt(1, 3000);
ps.setString(2, &#34;cc&#34;);
//执行sql
ps.executeUpdate();
//事务提交
connection.commit();
}catch (Exception e){
e.printStackTrace();
//事务回滚
connection.rollback();
}finally {
//允许自动提交
connection.setAutoCommit(true);
//关闭资源:最后关闭资源
JDBCUtils.close(ps,connection);
}
}
}数据库连接池
什么是数据库连接池
连接对象的缓冲区,负责申请,分配管理,释放连接的操作。
线程池核心类库有可直接用,但数据库连接池核心类库没有,自己写或者用别人写好的。
为什么要用数据库连接池
通过DriverManager获取新连接,用完直接抛弃断开,连接的利用率太低,过于浪费,对于数据库服务器来说压力太大。
阿里的德鲁伊连接池(DRUID)
方式一:
public class DruidDemo{
public static void main(String[] args){
//创建Druid的DataSource对象
DruidDataSource source = new DruidDataSource();
//配置
source.setDriverClassName(&#34;com.mysql.jdbc.Driver&#34;);
source.setUrl(&#34;jdbc:mysql://localhost:3306/db&#34;);
source.setUsername(&#34;root&#34;);
source.setPassword(&#34;123456&#34;);
//获取连接对象
Connection connection = source.getConnection();
System.out.println(connection);
}
}方式二: 配置文件:key的值不可修改
url=jdbc:mysql://localhost:3306/db
username=root
password=123456
driverClassName=com.mysql.jdbc.Driver代码:
public class DruidDemo{
public static void main(String[] args){
//创建Properties对象
Properties pro = new Properties();
//创建文件输入流
FileInputStream fis = new FileInputStream(&#34;druid.properties&#34;); //配置文件的名字可以随便写
//加载流
pro.load(fis);
//通过DruidDataSourceFactory创建连接池对象
DataSource source = DruidDataSourceFactory.createDataSource(pro);
//获取连接对象
Connection connection = source.getConnection();
System.out.println(connection);
//关闭资源
//...
}
}DBUtils工具类
DBUtils也是一个小的框架
1. 导包:同上
2. 代码:
//通过使用DBUtils工具类实现增删改查的操作
public class DruidDemo{
@Test
public void test() throws SQLException {
//创建操作对象
QueryRunner queryRunner = new QueryRunner();
//增,删,改是一个方法
/*
update(Connection conn, String sql, Object param)
conn:连接对象
sql:sql语句
param:给占位符赋值的内容
*/
String sql = &#34;insert into student(sid,sname,sage) values(?,?,?)&#34;;
//返回值:有几条数据受到影响
int i = queryRunner.update(JDBCUtils.getConnection(),sql, 10, &#34;kongkong&#34;, 18);
System.out.println(&#34;有&#34; + i + &#34;条数据受到影响&#34;);
}
@Test
public void test2() throws SQLException {
QueryRunner queryRunner = new QueryRunner();
/*
query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
conn:连接对象
sql:sql语句
*/
//String sql = &#34;select sid a,sname,sage from student where sid=?&#34;;
//注意:类中的属性名一定要和字段名相同。如果不相同则需要在sql语句中使用别名
//Student student = queryRunner.query(JDBCUtils.getConnection(), sql, new BeanHandler<Student>(Student.class), 10);
String sql = &#34;select sid a,sname,sage from student&#34;;
//通过反射拿到所有的属性,通过sql拿到所有的数据(是通过属性名找到对应的字段数据)
List<Student> list = queryRunner.query(JDBCUtils.getConnection(), sql, new BeanListHandler<Student>(Student.class));
for (Student s : list) {
System.out.println(s);
}
}
}批处理
使用批处理注意:
1. mysql驱动包的版本必须为5.1.3x 才支持批处理
2. 在url连接中添加如下参数
jdbc:mysql://localhost:3306/db?rewriteBatchedStatements=true
调用方法
//添加到批处理中
addBatch();
//执行批处理
executeBatch();
//清空批处理
clearBatch();代码实现
public class DruidDemo{
@Test
public void test2() throws SQLException {
//获取数据库连接
Connection connection = JDBCUtils.getConnection();
//预编译
PreparedStatement ps = connection.prepareStatement(&#34;insert into student(sid,sname,sage) values(?,?,?)&#34;);
//给占位符赋值
for (int i = 1; i <= 100000 ; i++) {
ps.setInt(1,i);
ps.setString(2,&#34;aaa&#34;+i);
ps.setInt(3,i);
//添加到批处理中
ps.addBatch();
if (i % 1000 == 0){
//执行sql
ps.executeBatch(); //执行批处理
//清空批处理
ps.clearBatch();
}
}
//关闭资源
JDBCUtils.close(ps,connection);
}
}最后,今天的内容就到这里,Java系列更新中,喜欢的话点个关注吧,下篇见! |
|