一、数据库的事务性
---------------------------------------
四个特性acid
a:atomic //原子性---整个事务,要么都成功,要么都失败
c:consistent //一致性---事务提交前后数据一致
i:isolate //隔离性---不同事务之间相互独立,互不干扰
d:durable //永久性---事务成立之后,永久保存
二、 事务机制---提交--回滚机制
------------------------------------------
Connection 中默认是自动提交的。
可以设置关闭自动提交:conn.setAutoCommit(false);
然后写完一段代码之后手动提交: conn.commit();
如果提交出现了错误,那么可以在trycatch的finally中进行回滚:conn.rollback();
/**
*删除数据
*/
public static void deleteData()
{
Connection con = null;
Statement st = null;
try {
con = getConn();
con.setAutoCommit(false);
st = con.createStatement();
st.execute("delete from mytable where id = 1");
st.execute("delete from mytable");
con.commit();
System.out.println("delete over");
} catch (Exception e) {
try {
con.rollback();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
finally
{
try {
if(con != null )
{
con.close();
}
if(st != null)
{
st.close();
}
} catch (Exception e2) {
}
}
}
----------------------------------------------------------------------------
/**
*更新数据
*/
public static void updateData()
{
Connection con = null;
Statement st = null;
try {
con = getConn();
con.setAutoCommit(false);
st = con.createStatement();
st.executeUpdate("update mytable set name = 'tom1',age = 12 where id = 11");
con.commit();
System.out.println("update over");
} catch (Exception e) {
try {
con.rollback();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
finally
{
try {
if(con != null )
{
con.close();
}
if(st != null)
{
st.close();
}
} catch (Exception e2) {
}
}
}
--------------------------------------------------------------------------------
/**
*查找数据
*/
public static void selectData()
{
Connection con = null;
Statement st = null;
try {
con = getConn();
con.setAutoCommit(false);
st = con.createStatement();
ResultSet set = st.executeQuery("select * from mytable");
while(set.next())
{
int id = set.getInt("id");
int age = set.getInt("age");
String name = set.getString("name");
System.out.println("id="+ id + " name=" + name + " age=" + age);
}
con.commit();
System.out.println("select over");
} catch (Exception e) {
try {
con.rollback();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
finally
{
try {
if(con != null )
{
con.close();
}
if(st != null)
{
st.close();
}
} catch (Exception e2) {
}
}
}
三、保存点
-------------------------------------------
savepoint:编写数据库命令语句的过程中,可以设置保存点。这样回滚的时候,就可以指定回滚到指定的保存点的位置
/**
* 插入数据
*/
public static void insertData()
{
long start = System.currentTimeMillis();
Connection con = null;
Statement st = null;
try {
con = getConn();
con.setAutoCommit(false);
st = con.createStatement();
for(int i = 0 ; i < 1000; i++)
{
String str = "insert into mytable (name,age) values('tom "+ i + "',"+ (i % 100) +")";
st.execute(str);
}
con.commit();
System.out.println("耗时:" + (System.currentTimeMillis() - start) );
System.out.println("insert over11");
} catch (Exception e) {
try {
con.rollback();
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
}
finally
{
try {
if(con != null )
{
con.close();
}
if(st != null)
{
st.close();
}
} catch (Exception e2) {
}
}
}
四、聚集函数查询
---------------------------------------------
select count(1) from mytable;
五、排序查询
---------------------------------------------
select * from mytable order by id desc, name asc; //按照id降序,name升序 查询(默认是升序)
六、查询mysql的系统表
-------------------------------------------
//查询指定的库中是否含有指定的表,通过查询系统库实现
* use information_schema;
* may: select table_name, table_schema from tables where table_schema = 'mydata' and table_name = 'mytable';
* or : select table_name,table_schema from information_schema.tables where table_name = 'mytable' and table_schema = 'mydata';
七、分页查询
---------------------------------------------
mysql: //limit
oracle:: //rownum;
sqlserver: //top
select * from mytable limit 10; //查询前10条记录;
select * from mytable limit 10,20; //偏移10,查询20个。即查询 11-31个
八、修改表 alter
-------------------------------------------------
alter table mytabel add column password varchar(20); //在mytable表中增加varchar类型的列 password
九、SQL注入
---------------------------------------------------
Statement 执行静态语句,会导致 sql注入问题
select * from mytable where name = '1' or '1' = '1' -- and password ='123456';
/**
* 测试Sql注入
*/
private static void tsInjection(){
Ts02.loadDriversClass();
Connection conn = Ts02.getConn();
try {
Statement st = conn.createStatement();
String name = "1' or 1=1 -- ";
String password = "123";
ResultSet set = st.executeQuery("select * from mytable where name = '" + name +"' and password = '"+ password +"'");
while(set.next())
{
System.out.println(set.getString(1));
System.out.println(set.getString(2));
}
st.close();
conn.close();
System.out.println("select over");
} catch (SQLException e) {
e.printStackTrace();
}
}
----------------------------------------------------------------------------------
/**
* 测试预处理语句防止Sql注入
*/
private static void tsSQLInjection(){
Ts02.loadDriversClass();
Connection conn = Ts02.getConn();
try {
//?表示占位符,可以是 任意数值或者字符
PreparedStatement ps = conn.prepareStatement("select * from mytable where name = ? and password = ?");
ps.setString(1, "1' or 1=1 -- ");
ps.setString(2, "123");
ResultSet set = ps.executeQuery();
while(set.next())
{
System.out.println(set.getString(1));
System.out.println(set.getString(2));
}
//ps.close();
conn.close();
System.out.println("select over");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
九、预处理语句 prepareStament
------------------------------------------------------
1.动态的,非静态的
/**
* 测试预处理插入
*/
private static void tsprepareStamentInsert()
{
Ts02.loadDriversClass();
Connection conn = Ts02.getConn();
try {
//?表示占位符,可以是 任意数值或者字符
PreparedStatement ps = conn.prepareStatement("insert into mytable (name , age ) values(?,?)");
ps.setString(1, "tomsen");
ps.setInt(2, 1000);
ps.executeUpdate();
ps.close();
conn.close();
System.out.println("insert over");
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
------------------------------------------------------------------------------
/**
* 测试预处理批量插入
*/
public static void tsBatchInsert()
{
int max = 9000;
Ts02.loadDriversClass();
Connection conn = Ts02.getConn();
PreparedStatement pt = null;
try {
conn.setAutoCommit(false);
//清空表格
// pt = conn.prepareStatement("delete from mytable");
// pt.executeUpdate();
// conn.commit();
//开始插入数据
long time1 = System.currentTimeMillis();
pt = conn.prepareStatement("insert into mytable (name,age) values(?,?)");
conn.setAutoCommit(false);
int count = 0;
for (int i = 0; i < max; i++) {
pt.setString(1, "tom" + i);
pt.setInt(2, 20);
//向批次里面增加元素
pt.addBatch();
count ++;
//手动清空批次元素
if(i == 8998)
{
pt.clearBatch();
}
//将该批次提交,提交之后批次元素自动清空
if(count == 2000)
{
pt.executeBatch();
count = 0;
}
}
pt.executeBatch();
conn.commit();
System.out.println("耗时:" + (System.currentTimeMillis() - time1));
//开始查询数据
// pt = conn.prepareStatement("select * from mytable");
//
// ResultSet set = pt.executeQuery();
//
// while(set.next())
// {
// System.out.print(set.getString(1));
// System.out.println(set.getString(2));
// }
pt.close();
conn.close();
System.out.println("update over");
} catch (SQLException e) {
e.printStackTrace();
}
}
十、截断表 truncate , 数据无法回滚
--------------------------------------------------------
truncate table mytable