1.数据库事务问题:数据库事务隔离级别– 脏读、幻读、不可重复读(清晰解释) - JIESA的专栏 - 博客 2.Android之 映射技术Class.forName()与.newInstance()区别和使用 - pengaianzhuo的博客 - 博客 3.[数据库操作]Java中的JDBC的使用方法. - 一枝花算不算浪漫 - 博客园
JDBC简单列子
//导入驱动类库
//注册驱动
DriverManager
.registerDriver(new
com.mysql.jdbc.Driver())
//连接数据库
String user=
"root"
String password=
"mysql520"
Connection conn = DriverManager
.getConnection(
"jdbc:mysql://localhost:3306/test", user, password)
//操作数据库
Statement
st = conn
.createStatement()
String sql=
"insert into student values(null,'guomei',22)"
st.execute(sql)
//关闭资源
st.close()
conn
.close()
注意:增删改使用st.executeUpdate或者st.execute(增删改查都可以,返回值 true=> 查询有结果集,false=> 查询没有结果集),现在查询需要使用st.executeQuery
// 操作数据库
Statement
st = conn
.createStatement()
String sql=
"select * from student"
ResultSet resultSet =
st.executeQuery(sql)
while (resultSet
.next()) {
String name = resultSet
.getString(
"name")
int age = resultSet
.getInt(
"age")
int id = resultSet
.getInt(
"id")
System
.out.println(
"id:"+id+
"======="+
"name:"+name+
"====="+age)
}
DriverManager细节
//
1.注册驱动
DriverManager
.registerDriver(new
com.mysql.jdbc.Driver())
System
.setProperty(
"jdbc.drivers",
"com.mysql.jdbc.Driver")
Class
.forName(
"com.mysql.jdbc.Driver")
Uri地址
//url完整 格式: 大协议:子协议://IP地址:端口号/库名?参数键=参数值 //完整:jdbc:mysql://127.0.0.1:3306/day05?useUnicode=true&characterEncoding=utf8 //简单:jdbc:mysql:///day05?useUnicode=true&characterEncoding=utf8,如果是连接本地localhost:3306的话,可以忽略
一般建议写完整的以及不需要写参数键=参数值
Conection细节
功能:
1.代表数据库的链接 2.可以根据该对象创建运送sql语句的Statement对象
方法:
Statement createStatement() 创建statement对象 CallableStatement prepareCall(String sql) 调用数据库的存储过程(存储过程没学) PreparedStatement prepareStatement(String sql) 创建 PreparedStatement 对象(下面会介绍)
Statement 对象
该对象可以理解为一个 向数据库运送sql语句的 "小车";
方法:
[1] void addBatch(String sql) 向车上添加语句. (用于批量执行sql语句); [2] insert update delete int[] executeBatch() 将车上的语句 运送给数据库执行. 返回值存放每个语句执行后影响的行数. 因为是多个语句,所以用数组装. [3] void clearBatch() 清除车上的语句. —-以上3个方法是批量执行sql相关的(下午最后一节课演示)———————- [4] boolean execute(String sql) 执行一个sql语句. 如果该语句返回结果集 返回值为true(select). 如果该语句不返回结果集 返回false(insert update delete); [5] ResultSet executeQuery(String sql) 执行一个有结果集的查询. 会将结果集包装到resultset对象中.(select) [6] int executeUpdate(String sql) 执行一个没有结果集的语句. 会将语句影响的行数返回.(insert update delete)
结论:
执行查询语句时使用: executeQuery方法 执行增删改等语句时使用: executeUpdate方法
ResultSet对象
功能:
当执行的语句是查询语句时, resultSet对象用于封装查询结果.
方法:
[1] boolean next() 该方法让结果集中的指针(游标)往下移动一行.并且判断改行是否有数据。 有返回true,没有返回false [2] String getString(int cloumnCount) 从当前指向的行中获得String 类型的数据. 根据列所在的索引位置取. [3] String getString(String columnName) 从当前指向的行中获得String 类型的数据. 根据列名取. [4] getXXX系列方法 有很多种, 没对针对的都是数据库中的不同类型.
JDBCUtils工具类
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JDBCUtils {
private static String driver;
private static String url;
private static String user;
private static String password;
static{
try {
Properties prop =
new Properties();
InputStream
is =
new FileInputStream(
"src/db.properties");
prop.load(
is);
is.close();
driver = prop.getProperty(
"driver");
url = prop.getProperty(
"url");
user = prop.getProperty(
"user");
password = prop.getProperty(
"password");
Class.forName(driver);
}
catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
Connection conn =
null;
try {
conn = DriverManager.getConnection(url, user, password);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(
"创建连接失败!");
}
return conn;
}
public static void close(Connection conn , Statement st , ResultSet rs){
try {
if(rs!=
null){
rs.close();
}
}
catch (SQLException e) {
e.printStackTrace();
}
finally{
try {
if(st!=
null){
st.close();
}
}
catch (SQLException e) {
e.printStackTrace();
}
finally{
try {
if(conn!=
null){
conn.close();
}
}
catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
db.properties文件
driver=com.mysql.jdbc.Driver;
url=jdbc:mysql://localhost:3306/test;
user=root;
password=mysql520;
SQL小细节:
拼装SQL语句
//拼装sql语句
String sql = "
SELECT * FROM student WHERE NAME='"+name+"' AND PASSWORD='"+password+"';";
解决SQL注入问题
public void fun2() throws Exception{
String name =
"xxx' OR 1=1 -- ";
String password =
"1234";
Connection conn= JDBCUtils.getConnection();
String sql =
"SELECT * FROM student WHERE NAME=? AND PASSWORD=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(
1, name);
ps.setString(
2, password);
ResultSet rs = ps.executeQuery();
if(rs.next()){
System.
out.println(
"登录成功!");
}
else{
System.
out.println(
"登录失败!");
}
JDBCUtils.close(conn, ps, rs);
}
利用JDBC向数据库存储大文本
public void fun1() throws Exception{
Connection conn = JDBCUtils.getConnection();
String sql =
"insert into mytext values(null,?)";
PreparedStatement ps = conn.prepareStatement(sql);
File file =
new File(
"src/text.txt");
FileReader reader =
new FileReader(file);
ps.setCharacterStream(
1, reader, (
int)file.length());
int result = ps.executeUpdate();
System.
out.println(result);
JDBCUtils.close(conn, ps,
null);
}
数据库的表需要有一列为text(列名字) text(列类型)
create table mytext(
id int primary key AUTO_INCREMENT,
text text
)
利用JDBC向数据库存储图片
public void fun1() throws Exception{
Connection conn = JDBCUtils.getConnection();
String sql =
"insert into myblob values(null,?)";
PreparedStatement ps = conn.prepareStatement(sql);
File f =
new File(
"src/wg.PNG");
InputStream
is =
new FileInputStream(f);
ps.setBinaryStream(
1,
is, (
int)f.length());
int result = ps.executeUpdate();
System.
out.println(result);
JDBCUtils.close(conn, ps,
null);
}
图片一般定义为file类型
create table myblob(
id int primary key AUTO_INCREMENT,
file blob
)
批量执行SQL:
//
1 使用Statement对象批量执行sql
public void fun1() throws Exception{
//
1 获得连接
Connection conn = JDBCUtils
.getConnection()
//
2 获得Statement
Statement
st = conn
.createStatement()
//
3 添加多条sql语句到
st中
st.addBatch(
"create table t_stu ( id int primary key auto_increment , name varchar(20) )")
st.addBatch(
"insert into t_stu values(null,'tom')")
st.addBatch(
"insert into t_stu values(null,'jerry')")
st.addBatch(
"insert into t_stu values(null,'jack')")
st.addBatch(
"insert into t_stu values(null,'rose')")
//
4 执行sql
int[] results =
st.executeBatch()
System
.out.println(Arrays
.toString(results))
//
5关闭资源
JDBCUtils
.close(conn,
st, null)
}
//
2 使用PrepareStatement对象批量执行sql
public void fun2() throws Exception{
//
1 获得连接
Connection conn = JDBCUtils
.getConnection()
//
2 书写sql语句
String sql =
"insert into t_stu values(null,?)"
//
3 创建PrepareStatement
PreparedStatement ps = conn
.prepareStatement(sql)
//
4 循环.添加参数
for(int i=
0
ps
.setString(
1,
"用户"+i)
ps
.addBatch()
}
//
5 批量执行
int[] results =ps
.executeBatch()
System
.out.println(Arrays
.toString(results))
//
5关闭资源
JDBCUtils
.close(conn, ps, null)
}