本篇内容介绍了“JDBC的概念是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
JDBC的概念:doMaim对象javaBean实体)
UserDaoDataAccessObject)
工厂模式,Factory消除UserDaoTest业务类对具体实现UserDaoJdbc类的依赖
读配置文件,通过工厂读配置文件来加载信息,具体实现类使用工厂来获取实现接口类的对象
JDBC的概念:工厂一般使用单例模式
工厂–>生产产品Dao这个产品)
类加载器,不光可以load.class,还可以load其他的文件
事务概念与处理
1.原子性:不能拆分,组成事事务处理的语句形成一个逻辑处理单元,不能只执行其中的一部分
2.一致性:事务做完之后,保定数据的完整性约束
3.隔离性:一个事务处理对另一个事务处理的影响
4.持续性:事务处理的结果能被***保存下来
步骤:打开事务connection.setAutoCommitfalse);
提交事务:connection.commit);
回滚事务:connection.rollback);
jdbc缺省是自动提交的,客户端连接也是自动提交的,要想打开事务,要把自动提交关掉
保存点:savePoint
Savepointsp=null
sp=conn.setSavepoint);
conn.rollbacksp);
———————————–
JDBC的概念:跨多个数据库的事务JTA
JTA容器weblogic,websphere
分成两阶段提交。
用到JNDI服务器
javax.transaction.UserTransactiontx=
UserTransaction)ctx.lookup"jndiName");
tx.begin);
//connection1connection2可能来自不同的数据库)
tx.commit);//tx.rollback);
———————————
事务的隔离级别:
connction.setTransactionIsolationConnection.TRANSACTION_READ_COMMITTED);
隔离级别
读未提交Readuncommitted)可能出现脏读,不可重复读,幻读
读已提交Readcommitted)可能出现不可重复读,幻读
可重复读Repeatableread)可能出现幻读幻影数据,执行插入一条数据,在另一个客户端有可能看到)
可串行化Serializable)
隔离级别各个数据库的实现是不一样的。
————————————————–
关于存储过程两层架构的时候用的很多)
三层架构的系统很少使用了。略过不看了先。
—————————————————
其他几个有用的API
jdbc3.0规范提供的方法
插一条记录,它能把主键返回来
PreparedStatement.getGeneratedKeys);
PreparedStatementps=connection.prepareStatementsql,Statement.RETURN_GENERATED_KEYS);
ps.executeUpdate);
ResultSetrs=st.getGeneratedKeys);
rs.getInt1);
批量处理:可以大幅提升大量增删改的速度并非绝对),与具体数据库有关,也不一定能提高性能
PreparedStatement.addBatch);
PreparedStatement.executeBatch);
————————————————————-
可滚动结果集与分页特性
Statementst=conn.createStatementResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSet.TYPE_SCROLL_SENSITIVE–对数据库敏感的,就是说,数据库中记录发生了变化,结果集会觉察到但某些数据库不一定遵循这一规范,mysql就不遵循)
ResultSet.CONCUR_UPDATABLE–可更新的,就是说,改变结果集中的内容可以影响到数据库里
ResultSet.CONCUR_READ_ONLY–只读的,
可滚动的结果集
Statementst=connection.createStatementResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
ResultSetrs=st.executeQuerysql);
rs.beforeFirst);
rs.afterLast);
rs.first);
rs.isFirst);
rs.last);
rs.isLast);
rs.absolute9);
rs.moveToInsertRow);
conn.createStatementResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
rs.updateString"colname","newvalue");
rs.updateRow);
mysql分页例如:
selectid,name,money,birthdayfromuserlimit150,10;
从user表中第150条记录开始,取10条记录
———————————————————
jdbc元数据信息数据库元数据信息、参数元数据信息
DatabaseMetaDatameta=connection.getMetaData);
通过DatabaseMetaData可以获得数据库相关的信息,如:
数据库版本,数据库名,数据库厂商信息,是否支持事务,是否支持某种事务隔离级别,
是否支持滚动结果集等。
ParameterMetaDatapmd=preparedStatement.getParameterMetaData);
通过ParameterMetaData可以获得参数信息.
ParameterMetaDatapmd=ps.getParameterMetaData);
intcount=pmd.getParameterCount);
System.out.println"count="+count);
forinti=1;i<=count;i++)
{
ps.setObjecti,params[i-1]);
}
ResultSetrs=ps.executeQuery);
————————————————–
dataSource代理模式:
组合优先于继承
拦截Connection.close)方法
动态代理
调用处理器
—————————————————-
数据源和连接池
DataSource用来取代DriverManger来获取Connection
通过DataSource获得Connection速度很快
通过DataSource获得的Connection都是已经被包裹过的不是驱动原来的连接),
他的close方法已经被修改
一般DataSource内部会用一个连接池来缓存Connection,这样可以大幅度提高
数据库的访问速度;
连接池可以理解成一个能够存放Connection的Connection
我们的程序只和DataSource打交道,不会直接访问连接池。
——————————————
DBCP的应用
1.加载三个.jar
2.写dbcpconfig.properties配置文件
3.创建DataSource数据源
使用DBCP必须用的三个包
commons-dbcp-1.2.2\commons-dbcp-1.2.1.jar,
spring-framework-2.5.6\lib\jakarta-commons\commons-pool.jar,commons-collection-3.1.jar
dbcpconfig.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=root
#初始化连接
initialSize=10
#***连接数量
maxActive=50
#***空闲连接
maxIdle=20
#最小空闲连接
minIdle=5
#超时等待时间以毫秒为单位
maxWait=60000
#JDBC驱动建立连接时附带的连接属性格式必须为这样:属性名=property
#注注意user与password两个属性会被明确地传递。因此这里不需要包含他们
connectionProperties=useUnicode=true;characterEncoding=utf-8
#指定由连接池所创建的连接的自动提交auto-commit状态
defaultAutoCommit=true
#driverdefault指定由连接池所创建的连接的只读read-only状态
#如果没有设置该值,则setReadOnly方法不被调用。
defaultReadOnly=
#driverdefault指定由连接池所创建的连接的事务级别TransactionIsolation
#可用值为下列之一:这依赖于数据库
#NONE,READ_UNCOMMITED,READ_COMMITTED
defaultTransactionIsolation=READ_COMMITTED
—————————————————-
创建数据源
Propertiesprop=newProperties);
prop.setProperty"driverClassName","com.mysql.jdbc.Driver");
prop.setProperty"url","jdbc:mysql://localhost:3306/jdbc");
prop.setProperty"username","root");
prop.setProperty"password","root");
#dbcp使用这个方法创建数据源,需要一个Property参数,参数中的键值对就为.properties文件中的配置
#可以直接load进来,省的写了
Propertiesprop=newProperties);
InputStreamis=JdbcUtil.class.getClassLoader).getResourceAsStream"dbcpconfig.properties");
prop.loadis);
DataSourcemyDataSource=BasicDataSourceFactory.createDataSourceprop);
————————————————————————-
模板模式对查询抽象,采用继承的方式对查询来说,不够灵活,查询的列一变化,就得修改超类)
策略模式采用接口的方式传递一个接口的参数,通过匿名类为各种需求实现)
———————————————————————–
使用JdbcTemplate工具类,在spring框架中提供了一个JdbcTemplate工具类,这个类对JDBCAPI进行了很好的封装
这个类就像我们自己对JDBC进行封装一样。只是代码列健壮,功能更强大而已。
我们以后在实际项目中可以使用JdbcTemplate类来完全替代直接使用JDBCAPI这与直接使用jdbcapi没有太大性能区别
使用JdbcTemplate工具类需要额外从spring开发包中导入spring.jar和commons-logging.jar
关于jdbcTemplate查询,更新相关使用方法见练习
如果想获取connection,自由进行操作,可以使用
jdbc.executenewConnectionCallback) { publicObjectdoInConnectionConnectionconn)throwsSQLException, DataAccessException {} });//拿到了Connction随你怎么用了 ------------------------------------------------------------------- Spring的NameParameterJdbcTemplate NameParameterJdbcTemplate内部包含了一个JdbcTemplate,所以JdbcTemplate能做的事情它都能做 NameParameterJdbcTemplate相对于JdbcTemplate主要增加了参数可以命名的功能 publicObjectqueryForObjectStringsql,MapparamMap,RowMapperrowMapper) publicObjectqueryForObjectStringsql,SqlParameterSourceparamSource,RowMapperrowMapper)
SqlParameterSource的两个主要实现MapSqlParameterSource和BeanPropertyParameterSource
SimpleJdbcTemplate内部包含了一个NamedParameterJdbcTemplate,所以NamedParameterJdbcTemplate
能做的事情SimpleJdbcTemplate都能干,SimpleJdbcTemplate相对于NamedParameterJdbcTemplate主要
增加了JDK5.0的泛型技术和可变长度参数支持
simpleJdbcTemplate中有些方法不全,比如拿到主键的方法就没有,可以获取到NamedParameterJdbcTemplate
调用它里面的方法
getNamedParameterJdbcOperations)返回的是NamedParameterJdbcOperations其实现就是NamedParameterJdbcTemplate这个类
getJdbcOperations)返回的是JdbcOperation其实现就是JdbcTemplate
++++++++++++++++++++++++++++++++++++++++++++++++++
Map参数源:采用键值对方式传参参数别名可任意,如:m,:n)
staticUserfindUserUseruser) { NamedParameterJdbcTemplatenamed=newNamedParameterJdbcTemplatedataSource); Stringsql="selectid,name,money,birthdayfromuserwheremoney>:mandid<:n"; Mapmap=newHashMap); map.put"m",user.getMoney)); map.put"n",user.getId)); Objectu=named.queryForObjectsql,map,newBeanPropertyRowMapperUser.class));//这个方法当查询对象多于一个或为null时会抛异常 returnUser)u; }
Bean属性参数源使用方法参数别名要与bean类的属性对应,如:money,:id)通过&号也可以命名别名,不建议使用)
staticUserfindUserUseruser) { NamedParameterJdbcTemplatenamed=newNamedParameterJdbcTemplatedataSource); Stringsql="selectid,name,money,birthdayfromuserwheremoney>:moneyandid<:id"; SqlParameterSourceps=newBeanPropertySqlParameterSourceuser); Objectu=named.queryForObjectsql,ps,newBeanPropertyRowMapperUser.class));//这个方法当查询对象多于一个或为null时会抛异常 returnUser)u; } //保存数据获得主键publicintupdateStringsql,SqlParameterSourceparamSource,KeyHoldergeneratedKeyHolder)staticvoidaddUserUseruser){NameParameterJdbcTemplatenamed=newNameParameterJdbcTemplatedataSource);Stringsql="insertintousername,birthday,money)values:name,:birthday,:money";SqlParameterSourceps=newBeanPropertySqlParameterSourceuser);KeyHolderkeyHolder=newGeneratedKeyHolder);named.updatesql,ps,keyHolder);intid=keyHolder.getKey).intValue);user.setIdid);//如果不是整型的主键呢,使用Mapmap=keyHolder.getKeys);}
JDBC的概念:使用泛型技术与可变长度的参数JDK1.5版本以上)
//泛型技术JDK1.5以上版本可使用) //使用泛型技术与可变长度的参数JDK1.5版本以上) staticUserfindUserSimpleStringname) { SimpleJdbcTemplatesimple=newSimpleJdbcTemplateJdbcUtil.getDataSource)); Stringsql="selectid,name,money,birthdayfromuserwheremoney>:moneyandid<:id"; //用这个泛型,返回结果就不用向下转型了 //publicTqueryForObjectStringsql,ParameterizedRowMapperrm,Object...args)throwsDataAccessException Useru=simple.queryForObjectsql, ParameterizedBeanPropertyRowMapper.newInstance User.class),name);//这个行映射器的参数是可变长的Object... returnu; } ----------------------------------------------------------------------------------------------------------------------- //代码 importjava.util.HashMap; importjava.util.Map; importorg.springframework.jdbc.core.BeanPropertyRowMapper; importorg.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource; importorg.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; importorg.springframework.jdbc.core.namedparam.SqlParameterSource; importcom.feihu.domain.User; importcom.feihu.jdbc.JdbcUtil; publicclassSimpleJdbcTemplate { privatestaticNamedParameterJdbcTemplatenamed=newNamedParameterJdbcTemplate JdbcUtil.getDataSource)); ///参数命名方法查询NamedParameterJdbcTemplate //两种参数传递方法BeanPropertySqlParameterSourceuser)、MapSqlParameterSource //bean属性参数源 staticUserfindUserUseruser) { //Bean属性参数源使用方法参数别名要与bean类的属性对应,如:money,:id)通过&号也可以命名别名,不建议使用) Stringsql="selectid,name,money,birthdayfromuserwheremoney>:moneyandid<:id"; SqlParameterSourceps=newBeanPropertySqlParameterSourceuser); Objectu=named.queryForObjectsql,ps,newBeanPropertyRowMapper User.class));//这个方法当查询对象多于一个或为null时会抛异常 returnUser)u; } //Map参数源 staticUserfindUser2Useruser) { Stringsql="selectid,name,money,birthdayfromuserwheremoney>:mandid<:n"; Mapmap=newHashMap); map.put"m",user.getMoney)); map.put"n",user.getId)); Objectu=named.queryForObjectsql,map,newBeanPropertyRowMapper User.class));//这个方法当查询对象多于一个或为null时会抛异常 returnUser)u; } //泛型技术JDK1.5以上版本可使用) //使用泛型技术与可变长度的参数JDK1.5版本以上) staticUserfindUserSimpleStringname) { SimpleJdbcTemplatesimple=newSimpleJdbcTemplateJdbcUtil.getDataSource)); Stringsql="selectid,name,money,birthdayfromuserwheremoney>:moneyandid<:id"; //用这个泛型,返回结果就不用向下转型了 //publicTqueryForObjectStringsql,ParameterizedRowMapperrm,Object...args)throwsDataAccessException Useru=simple.queryForObjectsql, ParameterizedBeanPropertyRowMapper.newInstance User.class),name);//这个行映射器的参数是可变长的Object... returnu; } }