目录
一、SQL常见语句:
二、构建数据库操作步骤:
三、SQL中字符串拼接
四、事务处理
五、数据库类型
六、数据库连接池
一、SQL常见语句:
- 建表:create table t1(a int ,b varchar(20)));
- 插入:insert into t1(a,b) values(1,'abc');
- 选择:select a from t1;
- 条件选择:select a,b from t1 where a>1;
- 删除:delete from t1 where a = 10 and b='ab';
- 更新:update t1 set a=2, b='cd' where a=1 and b='ab';
- 删表:drop table t1;
字段类型: int 4个字节 double 8个字节 datetime时间7个字节 varchar 字符串
JDBC是数据库和Java连接方法是最主流的。
连接数据库的连接字符串:
jdbc:oracle:thin:@127.0.0.1:1234:dbname
jdbc:mysql://localhost:1234/mydb
jbdc:sqlserner://localhost:1234;DatabaseName=dbname
二、构建数据库操作步骤:
1.注册驱动,建桥
2.构建数据库指定者
3.执行SQL语句。
若是执行select语句时则需要获取结果,并且遍历结果输出。
ResultSet rs = stmt.executeQuery("select bookid, bookname, price from t_book order by bookid");
//开始遍历ResultSet数据
while(rs.next())
{
System.out.println(rs.getInt(1) + "," + rs.getString(2) + "," + rs.getInt("price"));
}
建表,插入,删除操作等
import java.sql.*;
public class UpdateTest {
public static void main(String[] args){
executeUpdate("update t_book set price = 300 where bookid = 1");
executeUpdate("insert into t_book(bookid, bookname, price) values(4, '编译原理', 90)");
executeUpdate("delete from t_book where id = 4");
}
public static void executeUpdate(String sql)
{
//构建Java和数据库之间的桥梁介质
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("注册驱动成功!");
}catch(ClassNotFoundException e1){
System.out.println("注册驱动失败!");
e1.printStackTrace();
}
String url="jdbc:mysql://localhost:3306/test";
Connection conn = null;
try {
//构建Java和数据库之间的桥梁:URL,用户名,密码
conn = DriverManager.getConnection(url, "root", "123456");
//构建数据库执行者
Statement stmt = conn.createStatement();
System.out.println("创建Statement成功!");
//执行SQL语句
int result = stmt.executeUpdate(sql);
stmt.close();
} catch (SQLException e){
e.printStackTrace();
}
//最后将连接关闭
finally
{
try
{
if(null != conn)
{
conn.close();
}
}
catch (SQLException e){
e.printStackTrace();
}
}
}
}
三、SQL中字符串拼接
需要注意地是SQL字符串拼接很危险,如果拼接的字符串中又含有和SQL关键字会造成错误。很容易出现SQL注入。
防止的方法主要是通过 PreparedStatement类方法,用?代替变量。同时可以用addBatch批量更新。select可以用ResulSet接收结果。
示例:
public static void safeInsertBook()
{
//构建Java和数据库之间的桥梁介质
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("注册驱动成功!");
}catch(ClassNotFoundException e1){
System.out.println("注册驱动失败!");
e1.printStackTrace();
}
String url="jdbc:mysql://localhost:3306/test?allowMultiQueries=true";
Connection conn = null;
try {
//构建Java和数据库之间的桥梁:URL,用户名,密码
conn = DriverManager.getConnection(url, "root", "123456");
String sql = "insert into t_book(bookid,bookname,price) values(?,?,?)";
//构建数据库执行者
PreparedStatement pstmt = conn.prepareStatement(sql);//比起creatStatement更安全地执行SQL,sql字符串中地?代替字符串拼接
//执行SQL语句
int bookid = 10;
String bookName = "Effective Java',50);delete from t_book;insert into t_book values(101, 'faked book";
int price = 50;
//values(1, 'Effective Java', 50)
pstmt.setInt(1, bookid);
pstmt.setString(2, bookName);
pstmt.setInt(3, price);
int result = pstmt.executeUpdate();
pstmt.close();
System.out.println("操作成功");
} catch (SQLException e){
e.printStackTrace();
}
finally
{
try
{
if(null != conn)
{
conn.close();
}
}
catch (SQLException e){
e.printStackTrace();
}
}
}
public static void batchInsertBook()
{
//构建Java和数据库之间的桥梁介质
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("注册驱动成功!");
}catch(ClassNotFoundException e1){
System.out.println("注册驱动失败!");
e1.printStackTrace();
}
String url="jdbc:mysql://localhost:3306/test?allowMultiQueries=true";
Connection conn = null;
try {
//构建Java和数据库之间的桥梁:URL,用户名,密码
conn = DriverManager.getConnection(url, "root", "123456");
String sql = "insert into t_book(bookid,bookname,price) values(?,?,?)";
//构建数据库执行者
PreparedStatement pstmt = conn.prepareStatement(sql);
//执行SQL语句
String bookName = "aaaaaaaaaaaaaaaa";
int price = 50;
//values(1, 'Effective Java', 50)
for(int i=200;i<210;i++)
{
pstmt.setInt(1, i);
pstmt.setString(2, bookName);
pstmt.setInt(3, price);
pstmt.addBatch();//批量更新
}
pstmt.executeBatch();//批量执行
pstmt.close();
System.out.println("操作成功");
} catch (SQLException e){
e.printStackTrace();
} finally {
try {
if(null != conn) {
conn.close();
}
}
catch (SQLException e){
e.printStackTrace();
}
}
}
四、事务处理
有场景:数据库操作时,需要是一系列操作,要么完全的执行,要么完全地不执行。
事务需要有原子性,一致性,隔离性,持续性
通过conn.setAutoCommit(false);//关闭自动提交
再依次执行,最后手动提交:conn.commit();
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Savepoint;
import java.sql.Statement;
public class TransactionTest {
public static void main(String[] args) throws Exception {
// 构建Java和数据库之间的桥梁介质
try {
Class.forName("com.mysql.jdbc.Driver");
System.out.println("注册驱动成功!");
} catch (ClassNotFoundException e1) {
System.out.println("注册驱动失败!");
e1.printStackTrace();
}
String url = "jdbc:mysql://localhost:3306/test";
Connection conn = null;
try {
// 构建Java和数据库之间的桥梁:URL,用户名,密码
conn = DriverManager.getConnection(url, "root", "123456");
conn.setAutoCommit(false);//关闭自动提交
insertBook(conn, "insert into t_book values(101, 'aaaa', 10)");
insertBook(conn, "insert into t_book values(102, 'bbbb', 10)");
insertBook(conn, "insert into t_book values(103, 'cccc', 10)");
Savepoint phase1 = conn.setSavepoint(); //设置一个保存点
insertBook(conn, "insert into t_book values(104, 'cccc', 10)");
insertBook(conn, "insert into t_book values(105, 'cccc', 10)");
conn.rollback(phase1); //回滚到phase1保存点,即上面2行无效
conn.commit();//手动提交
System.out.println("操作成功");
} catch (SQLException e) {
e.printStackTrace();
conn.rollback();
} finally {
if (null != conn) {
conn.close();
}
}
}
public static void insertBook(Connection conn, String sql) {
try {
// 构建数据库执行者
Statement stmt = conn.createStatement();
//System.out.print("创建Statement成功!");
// 执行SQL语句
int result = stmt.executeUpdate(sql);
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
五、数据库类型
getColumnName()返回列头的名字。
import java.sql.*;
public class ResultSetMetaDataTest {
public static void main(String[] args){
//构建Java和数据库之间的桥梁介质
try{
Class.forName("com.mysql.jdbc.Driver");
System.out.println("注册驱动成功!");
}catch(ClassNotFoundException e1){
System.out.println("注册驱动失败!");
e1.printStackTrace();
return;
}
String url="jdbc:mysql://localhost:3306/test";
Connection conn = null;
try {
//构建Java和数据库之间的桥梁:URL,用户名,密码
conn = DriverManager.getConnection(url, "root", "123456");
//构建数据库执行者
Statement stmt = conn.createStatement();
System.out.println("创建Statement成功!");
//执行SQL语句并返回结果到ResultSet
ResultSet rs = stmt.executeQuery("select bookid, bookname, price from t_book order by bookid");
//获取结果集的元数据
ResultSetMetaData meta = rs.getMetaData(); //获取数据属性
int cols = meta.getColumnCount(); //获取数据有多少列
for(int i=1;i<=cols;i++)//列从1开始
{
//返回每一列的数据名称和数据类型,入bookid是int类型
System.out.println(meta.getColumnName(i) + "," + meta.getColumnTypeName(i));
}
rs.close();
stmt.close();
} catch (SQLException e){
e.printStackTrace();
}
finally
{
try
{
if(null != conn)
{
conn.close();
}
}
catch (SQLException e){
e.printStackTrace();
}
}
}
}
六、数据库连接池
上述例子中连接数据库都需要构建连接,但是构建需要耗费大量成本,所以推出享元模式。
数据库池:初始数、最大数、增量、超时时间等参数
优点:来降低系统中数据库连接Connection对象的数量,降低数据库服务器的连接响应消耗,提高Connection获取响应的速度。
我们一般常用C3P0数据库连接池,公认最好的是Druid数据库池。
需要进行依赖Druid
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
import java.sql.*;
public class SelectTest {
public static void main(String[] args){
Connection conn = null;
try {
//从c3p0获取
//从Druid获取
//conn = DruidFactory1.getConnection();
conn = DruidFactory2.getConnection();
//构建数据库执行者
Statement stmt = conn.createStatement();
System.out.println("创建Statement成功!");
//执行SQL语句并返回结果到ResultSet
ResultSet rs = stmt.executeQuery("select bookid, bookname, price from t_book order by bookid");
//开始遍历ResultSet数据
while(rs.next())
{
System.out.println(rs.getInt(1) + "," + rs.getString(2) + "," + rs.getInt("price"));
}
rs.close();
stmt.close();
} catch (Exception e){
e.printStackTrace();
} finally {
try {
if(null != conn) {
conn.close();
}
} catch (SQLException e){
e.printStackTrace();
}
}
}
}
方式1:在代码中进行数据课池设定
import java.sql.Connection;
import com.alibaba.druid.pool.DruidDataSource;
public class DruidFactory1 {
private static DruidDataSource dataSource = null;
public static void init() throws Exception {
dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword("123456");
dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/test");
dataSource.setInitialSize(5);//初始连接
dataSource.setMinIdle(1); //最大空闲连接
dataSource.setMaxActive(10); //最大活动连接
// 启用监控统计功能 dataSource.setFilters("stat");//
}
public static Connection getConnection() throws Exception {
if(null == dataSource)
{
init();
}
return dataSource.getConnection();
}
}
方法二:在文件中进行设定
设定druid.properties文件
filters:配置插件,stat为监控统计
maxActivive:最大活跃
maxWait:最大等待
timeBetweenEvictionRunsMillis:检查空闲连接的频率,单位毫秒, 非正整数时表示不进行检查
minEvictableIdleTimeMillis:池中某个连接的空闲时长达到 N 毫秒后, 连接池在下次检查空闲连接时,将回收该连接
validationQuery:检查池中的连接是否仍可用的 SQL 语句,drui会连接到数据库执行该SQL, 如果正常返回,则表示连接可用,否则表示连接不可用
testWhileIdle:当程序请求连接,池在分配连接时,是否先检查该连接是否有效。(高效)true
testOnBorrow:程序 申请 连接时,进行连接有效性检查(低效,影响性能)false
testOnReturn:程序 返还 连接时,进行连接有效性检查(低效,影响性能)false
maxPoolPrepareStatementPerConnectionSize:每个连接最多缓存多少个SQL
poolPreparedStatements:
poolPreparedStatements | 缓存通过以下两个方法发起的SQL: | true | |
| public PreparedStatement prepareStatement(String sql) | | |
| public PreparedStatement prepareStatement(String sql, | | |
| int resultSetType, int resultSetConcurrency) | |
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test
username=root
password=123456
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200
在代码中加载文件
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
public class DruidFactory2 {
private static DruidDataSource dataSource = null;
public static void init() throws Exception {
Properties properties = new Properties();
InputStream in = DruidFactory2.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(in);
dataSource = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties);
in.close();
}
public static Connection getConnection() throws Exception {
if(null == dataSource)
{
init();
}
return dataSource.getConnection();
}
}
中国大学mooc《java核心技术》