Oracle的3个主要用户
普通用户:scott 密码:tiger
普通管理员:system 密码:manager
超级管理员:sys密码:change_on
1. 插入和读取 clob文本数据 Mysql ORACLE的字符数据,最大可达到4G
2. 插入和读取 Blob 二进制数据,
MySql的Blob 存储16KB数据,
与 Oracle 的Blob长度不一样 可存储 二进制数据,最大可达到4G
3.真正存储二进制数据 要用事务,游标
先插入一个empty_blob()函数,再查询,再插入或读取
4.2种批处理addBatch() || addBatch(sql),for循环;
#假如数据太大了虚拟机会内存溢出,办法:如1000条时候分段批量执行executeBatch();
5.获取数据库自动生成的主键
PreparedStatemment.getGeneratedKeys(); //返回st对象封装的sql的主键。MySQL中可以
如果是其他数据库,在执行conn.preparedStatement(sql,Statement.RETURN_GENERATED_KEYS)加上一个常量值,ORACLE也可以
6.存储过程
CallableStatement c = conn.preparedCall("{call demeSp(?,?)}");
获取返回的时候要告诉数据库返回值的类型
c.registerOutParameter(2,Types.VARCHAR2);
7.事务
@Connection 对象处于自动提交模式下,意味着它在执行每个语句后都会自动提交更改,所以要conn.setAutoCommit(false);完了再commit();
有异常在catch()中手动(虽然自动)conn.rollback();
@SavaPoint回滚点
@事务的特性(ACID)
原子性(Atomicity):要么成功、失败
一致性(Consistency):前后数据一致、
隔离性(Isolation): 并发事务,负责隔离操作数据、
持久性(Durability):只要commit,必须要保存下来
未隔离可能发生的:
脏读:一个事物提交(读到)了别人未提交的数据 例:买卖
不可重复读:一个事务读到了提交的数据 例:2人读数据报表
虚读(幻读):一个事物内读到了别人插入的数据 例: 幻语句
当前的数据库连接级别:
set transaction isolation level read uncommitted; 设置最低级别
set transaction isolation level read committed; 设置读级别 (用于查账)
set transaction isolation level repeatable committed; 可重复提交 ,避免不了幻读
set transaction isolation level Serializable; //单线程级别,别的用户访问不了(会死锁)
start starnsaction; 开启事务
级别设置serializable,才会产生共享锁。
不管在什么级别,只要做update都会加排他锁。
共享锁 解决办法--- 乐观锁:加入版本号解决更新丢失,update 后加入version字段。程序是并发的时候,回滚会造成性能下降。
排它锁 --- 悲观锁:select..for update;令一个账号就需要等待
考虑:系统用更新多,还是查询多,查询多用乐观锁,更新多用悲观锁
锁的是索引列的话,是锁住行,其他用户可以操作其他行。(行级锁)否则是锁住整个表。
[安装配置时]设置innodb引擎,才支持事务和行级锁 (考虑事务多)
如果是myisam,只有表级锁 (查询系统用这个)
Oracle不同,Oracle是针对数据加锁
间隙锁:where id>2 for update
============================================================16
实际开发中,要增强一个开发有3中方法:
1.继承一个类,覆盖实现要增强的方法。
2.包装decorate模式,实现接口,增强方法
3使用动态代理技术构建
包装设计模式
* 1.写一个类实现与被增强类相同的接口
* 2.在类中定义一个变量,记住被增强对象
* 3.在类中定义一个构造方法,接收被增强对象
* 4.重写想增强的方法
* 5.对于不想增强的方法,则在方法体内直接调用被增强对象的方法
数据库连接池:
有3种:
@1.DBCP开发库: commons-dbcp.jar,commons-pool.jddbc
1.得到一个new BasicDataSourceFactory();
2.DataSource ds = factory.createDataSource(properties);构建一个池
Connection conn = ds.getConnection();
@2.C3P0 开发库c3p0.jar ,mchange-commons-0.2
1.ComboPooledDataSource ds = new ();
/*2.Dds.setUrl//设置驱动,连接名称密码,初始化池大小。其他值会默认
ds.getConnection();*/
2.另外可以用配置文件c3p0-config.xml,
//指定配置文件中配置的数据库,不指定为缺省配置
ComboPooledDataSource ds = new ("mysql");
@3.tomcat中连接池
原理:DAO通过jdbUtils从JIDI容器中获取DataSource:app/datasource
配置文件也可以在META-INF目录下写context.xml
注意:tomcat中会自动生成这份xml,
步骤
1.把jar包放如tomcat的lib包中
2.在tomacat的文档中找到jndi的配置文件
3.在项目META-INF下加入context.xml配置文件
<Context>
<Resource name="jdbc/EmployeeDB"
auth="Container"
type="javax.sql.DataSource"
username="root"
password="root"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/yuwang"
initialSize="10"
maxActive="8"
maxIdle="4"/>
</Context>
4.以下这样就能得到Connection对象
private static DataSource ds = null;
static {
try {
Context initCtx = new InitialContext();
Context envCtx = (Context) initCtx.lookup("java:comp/env");
ds = (DataSource) envCtx.lookup("jdbc/EmployeeDB");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
模拟的数据库连接池
import java.io.PrintWriter; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.SQLWarning; import java.sql.Savepoint; import java.sql.Statement; import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.sql.DataSource; public class JdbcPool implements DataSource { private static LinkedList<Connection> list = new LinkedList<Connection>(); static{ try { Class.forName("com.mysql.jdbc.Driver"); for(int i=0;i<20;i++){ Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day16", "root", "root"); System.out.println(conn); list.add(conn); } } catch (Exception e) { throw new RuntimeException(e); } } /* 1.写一个子类,覆盖想增强的方法() 2.用包装设计模式 3.用动态代理 */ /* class MyConnection extends mysqlConnection{ public void close(){ } } /* * 1.写一个类实现与被增强类相同的接口 * 2.在类中定义一个变量,记住被增强对象 * 3.在类中定义一个构造方法,接收被增强对象 * 4.重写想增强的方法 * 5.对于不想增强的方法,则在方法体内直接调用被增强对象的方法 */ /* class MyConnection implements Connection{ private Connection conn; public MyConnection(Connection conn){ this.conn = conn; } public void close() throws SQLException { list.add(conn); } public void clearWarnings() throws SQLException { this.conn.clearWarnings(); } public void commit() throws SQLException { this.conn.commit(); } public Statement createStatement() throws SQLException { return this.createStatement(); } public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { // TODO Auto-generated method stub return this.createStatement(resultSetType, resultSetConcurrency); } public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { // TODO Auto-generated method stub return null; } public boolean getAutoCommit() throws SQLException { // TODO Auto-generated method stub return false; } public String getCatalog() throws SQLException { // TODO Auto-generated method stub return null; } public int getHoldability() throws SQLException { // TODO Auto-generated method stub return 0; } public DatabaseMetaData getMetaData() throws SQLException { // TODO Auto-generated method stub return null; } public int getTransactionIsolation() throws SQLException { // TODO Auto-generated method stub return 0; } public Map<String, Class<?>> getTypeMap() throws SQLException { // TODO Auto-generated method stub return null; } public SQLWarning getWarnings() throws SQLException { // TODO Auto-generated method stub return null; } public boolean isClosed() throws SQLException { // TODO Auto-generated method stub return false; } public boolean isReadOnly() throws SQLException { // TODO Auto-generated method stub return false; } public String nativeSQL(String sql) throws SQLException { // TODO Auto-generated method stub return null; } public CallableStatement prepareCall(String sql) throws SQLException { // TODO Auto-generated method stub return null; } public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { // TODO Auto-generated method stub return null; } public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { // TODO Auto-generated method stub return null; } public PreparedStatement prepareStatement(String sql) throws SQLException { // TODO Auto-generated method stub return null; } public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { // TODO Auto-generated method stub return null; } public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { // TODO Auto-generated method stub return null; } public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { // TODO Auto-generated method stub return null; } public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { // TODO Auto-generated method stub return null; } public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { // TODO Auto-generated method stub return null; } public void releaseSavepoint(Savepoint savepoint) throws SQLException { // TODO Auto-generated method stub } public void rollback() throws SQLException { // TODO Auto-generated method stub } public void rollback(Savepoint savepoint) throws SQLException { // TODO Auto-generated method stub } public void setAutoCommit(boolean autoCommit) throws SQLException { // TODO Auto-generated method stub } public void setCatalog(String catalog) throws SQLException { // TODO Auto-generated method stub } public void setHoldability(int holdability) throws SQLException { // TODO Auto-generated method stub } public void setReadOnly(boolean readOnly) throws SQLException { // TODO Auto-generated method stub } public Savepoint setSavepoint() throws SQLException { // TODO Auto-generated method stub return null; } public Savepoint setSavepoint(String name) throws SQLException { // TODO Auto-generated method stub return null; } public void setTransactionIsolation(int level) throws SQLException { // TODO Auto-generated method stub } public void setTypeMap(Map<String, Class<?>> map) throws SQLException { // TODO Auto-generated method stub } } */ public Connection getConnection() throws SQLException { if(list.size()>0){ final Connection conn = list.removeFirst(); //mysqlConnection close System.out.println("从池中获取:" + conn + "当前池的大小是:" + list.size()); //MyConnection myconn = new MyConnection(conn); return (Connection) Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler(){ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodname = method.getName(); //得到dao调用的是哪个方法 if(methodname.equals("close")){ list.add(conn); System.out.println(conn + "被还到池中了,池的大小是:" + list.size()); return null; }else{ return method.invoke(conn, args); } } }); //dao----connection.createstatement commit close() }else{ throw new RuntimeException("数据库忙,请等会再来!!"); } } public Connection getConnection(String username, String password) throws SQLException { // TODO Auto-generated method stub return null; } public PrintWriter getLogWriter() throws SQLException { // TODO Auto-generated method stub return null; } public int getLoginTimeout() throws SQLException { // TODO Auto-generated method stub return 0; } public void setLogWriter(PrintWriter arg0) throws SQLException { // TODO Auto-generated method stub } public void setLoginTimeout(int arg0) throws SQLException { // TODO Auto-generated method stub } }
2.
import java.io.InputStream; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class JdbcUtils { private static Properties prop = new Properties(); static{ try{ InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"); prop.load(in); Class.forName(prop.getProperty("driver")); }catch (Exception e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException{ return DriverManager.getConnection(prop.getProperty("url"), prop.getProperty("username"), prop.getProperty("password")); } public static void release(Connection conn,Statement st,ResultSet rs){ if(rs!=null){ try{ rs.close(); }catch (Exception e) {} } if(st!=null){ try{ st.close(); }catch (Exception e) {} } if(conn!=null){ try{ conn.close(); }catch (Exception e) {} } } //搞定所有增删改 public static void update(String sql,Object params[]) throws SQLException{ Connection conn = null; PreparedStatement st = null; try{ conn = getConnection(); st = conn.prepareStatement(sql); for(int i=0;i<params.length;i++){ st.setObject(i+1, params[i]); } st.executeUpdate(); }finally{ release(conn, st, null); } } //策略模式 public static Object query(String sql,Object params[],ResultSetHandler rsh) throws SQLException{ Connection conn = null; PreparedStatement st = null; ResultSet rs = null; try{ conn = getConnection(); st = conn.prepareStatement(sql); for(int i=0;i<params.length;i++){ st.setObject(i+1, params[i]); } rs = st.executeQuery(); return rsh.handler(rs); }finally{ release(conn, st, null); } } }
DBUtils的工具操作:
import java.sql.SQLException; import java.util.List; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.junit.Test; public class Demo1 { /* create database wangs; use wangs; create table account ( id int primary key auto_increment, name varchar(20), money double ); */ @Test public void insert() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "insert into account(name,money) values(?,?)"; Object params[] = {"aaa",10000}; qr.update(sql, params); } @Test public void update() throws Exception { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "update account set money=? where id=?"; Object params[] = {2000,1}; qr.update(sql, params); } @Test public void delete() throws Exception { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "delete from account where id=?"; qr.update(sql, 1); } @Test public void find() throws Exception { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql= "select * from account where id=?"; Account a = (Account) qr.query(sql,2, new BeanHandler(Account.class)); System.out.println(a); } @Test public void getAll() throws SQLException { QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql= "select * from account"; List list = (List) qr.query(sql, new BeanListHandler(Account.class)); System.out.println(list); } @Test public void batch() throws Exception{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "insert into account(name,money) values(?,?)"; Object params[][] = new Object[10][]; for(int i=0;i<10;i++){ params[i] = new Object[]{"aa"+i,1000+i}; } qr.batch(sql, params); } }
2.常见处理器
import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Set; import java.util.Map.Entry; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.ResultSetHandler; import org.apache.commons.dbutils.handlers.ArrayHandler; import org.apache.commons.dbutils.handlers.ArrayListHandler; import org.apache.commons.dbutils.handlers.KeyedHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import org.junit.Test; public class Demo2 { //测试常见的处理器 @Test public void testArrayHandler() throws Exception{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from account"; Object results[] = (Object[]) qr.query(sql, new ArrayHandler()); System.out.println(Arrays.asList(results)); //toString() } @Test public void testArrayListHandler() throws Exception{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from account"; List<Object[]> list = (List<Object[]>) qr.query(sql, new ArrayListHandler()); System.out.println(Arrays.asList(list)); //toString() } @Test public void testColumnListHandler() throws Exception{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from account"; List list = (List) qr.query(sql, new MyColumnListHandler("id")); System.out.println(list); //toString() } @Test public void testKeyedHandler() throws Exception{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from account"; Map<Integer,Map<String,Object>> map = (Map) qr.query(sql, new KeyedHandler("id")); Set<Entry<Integer, Map<String, Object>>> set = map.entrySet(); for(Map.Entry<Integer, Map<String, Object>> entry : set){ System.out.println("key=" + entry.getKey()); Map<String, Object> innermap = entry.getValue(); for(Map.Entry<String, Object> innerentry : innermap.entrySet()){ System.out.print(innerentry.getKey() +"="+ innerentry.getValue() + " "); } System.out.println(); } } @Test public void testMapHandler() throws Exception{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); } @Test public void testMapListHandler() throws Exception{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); } //select count(*) from account; @Test public void testScalarHandler() throws Exception{ QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select count(*) from account"; long count = (Long)qr.query(sql, new ScalarHandler(1)); System.out.println(count); } } class MyColumnListHandler implements ResultSetHandler{ private String columnName; public MyColumnListHandler(String columnName){ this.columnName = columnName; } public Object handle(ResultSet rs) throws SQLException { //回调方法 List list = new ArrayList(); while(rs.next()){ list.add(rs.getObject(columnName)); } return list; } }