18、完成整个DAO的实现及测试代码
public class DaoFactory {
//这句代码一定要放到构造DaoFactory()对象之前,否则在构造完成之后给userDao原本已经
//赋值完成 现在又要变成null了
private UserDao userDao = null;
private static DaoFactory instance = new DaoFactory();
private DaoFactory() {
try {
Properties props = new Properties();
InputStream in = DaoFactory.class.getClassLoader().
getResourceAsStream("daoconfig.properties");
//用下面的方式来构建一个输入流也是 可以的,但是你会发现我们的路径都是写死的,如果我们的配置文件
//改变了地方,就找不到文件了 而如果我们用上面类加载器的方法来得到一个文件的输入流,只要这个文件在
//classpath路径下面就能找到他
//InputStream in = new FileInputStream("src/daoconfig.properties");
props.load(in);
in.close();
String className = props.getProperty("className");
Class clazz = Class.forName(className);
userDao = (UserDao) clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
throw new ExceptionInInitializerError(e.getMessage());
}
}
public static DaoFactory getInstance() {
return instance;
}
public UserDao getUserDao() {
return userDao;
}
}
19、事务的概念与JDBC事务处理
(1)原子性(atomicity):组成事务处理的语句形成了一个逻辑单元,不能只执行其中的一部分。
(2)一致性(consistency):在事务处理执行前后,数据库是一致的(两个账户要么都变,或者都不变)。
(3)隔离性(isolcation):一个事务处理对另一个事务处理没有影响。
(4)持续性(durability):事务处理的效果能够被永久保存下来 。
举例:银行转账
connection.setAutoCommit(false);//打开事务。
.....
....把进行转账的两步操作放在同一个事务中,如果一个出现异常,马上回滚
.....
connection.commit();//提交事务。
connection.rollback();//回滚事务。
20、事务的保存点处理:定义保存点可以用来回滚一部分内容
static void test() throws SQLException {
Connection conn = null;
Statement st = null;
ResultSet rs = null;
//定义保存点
Savepoint sp = null;
try {
conn = JdbcUtils.getConnection();
conn.setAutoCommit(false);
st = conn.createStatement();
//修改张三的money值
String sql = "update user set money=money-10 where id=1";
st.executeUpdate(sql);
//设置保存点
sp = conn.setSavepoint();
//修改王五的money值
sql = "update user set money=money-10 where id=3";
st.executeUpdate(sql);
sql = "select money from user where id=2";
rs = st.executeQuery(sql);
float money = 0.0f;
if (rs.next()) {
money = rs.getFloat("money");
}
//如果李四的money的值>300就抛出异常
if (money > 300)
throw new RuntimeException("已经超过最大值!");
sql = "update user set money=money+10 where id=2";
st.executeUpdate(sql);
conn.commit();
} catch (RuntimeException e) {
if (conn != null && sp != null) {
//rollback的时候要定义保存点,否则会全部回滚
conn.rollback(sp);
conn.commit();
}
throw e;
} catch (SQLException e) {
if (conn != null)
conn.rollback();
throw e;
} finally {
JdbcUtils.free(rs, st, conn);
}
}
总结:如果上面的调用产生了异常,那么张三账号的会减少,而王五的钱不会变少:保存点之后的内容会被回滚
而保存点之前的内容不会被回滚。
22、JTA分布式事务的简要介绍
跨越多个数据源的事务,使用JTA容器实现事务。
分成两阶段提交。
javax.transaction.UserTransaction tx = (UserTransaction)ctx.lookup(“jndiName");
tx.begin();
//connection1 connection2 (可能来自不同的数据库)…
tx.commit();//tx.rollback();
23、事务的隔离级别
查看与设置mysql数据库的的隔离级别:
查看:select @@tx_isolation
未提交读:set transaction isolation level read uncommitted
提交读:set transaction isolation level read committed
不可重复读:set transaction isolation level repeatable committed
在默认情况下mysql的事务是自动提交的,输入命令strat transaction 表示你要
自己手动控制事务,mysql不会帮你自动提交事务 commit命令是提交当前事务
rollback:回滚事务
24、使用JDBC调用存储过程
(1)下面是在mysql客户端工具 Mysql query Brower 中创建的一个存储过程,模拟添加用户
DELIMITER $$
DROP PROCEDURE IF EXISTS `jdbc`.`addUser` $$
CREATE PROCEDURE `jdbc`.`addUser` (in name varchar(45), in sex varchar(10), out pid int)
BEGIN
insert into user(name, sex) values(name, sex);
select last_insert_id() into pid;
END $$
DELIMITER ;
//在`addUser` (in name varchar(45), in sex varchar(10), out pid int)中
//in:表示输入参数 out:表示输出参数
//last_insert_id()是mysql所特有的一个函数,可以查询出最后一次插入到数据库的那条数据的id
(2)java客户端对于存储过程的调用
public static void CallableStatementTest() throws Exception {
Connection conn = JdbcUtils.getConnection();
// call :是固定写法, addUser 是我们在数据库中定义的存储过程的名字后面指定参数
//如果没有任何参数 addUser后的括号也要写上
String sql = "{call addUser(?,?,?)}";
CallableStatement cs = conn.prepareCall(sql);
//注册一个输出参数并知名类型 第一参数指的是sql中三个问号中规定返回值的那个问号
//这个要与存储过程中所定义的顺序一样。
cs.registerOutParameter(3, Types.INTEGER);
cs.setString(1, "zhangsan");
cs.setString(2, "男");
cs.executeUpdate();
int id = cs.getInt(3);
System.out.println(id);
}
下面的示例是返回当前这条记录插入后形成的id
public static void returnId() throws Exception{
Connection conn = JdbcUtils.getConnection();
String sql = "insert into user(name, sex) values (?,?)";
//虽然说第二个参数不写可能也能返回,但是这和不同的数据库产品以及相应的驱动有关
//所以这个参数最好还是要写上
PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
pstmt.setString(1, "lisi");
pstmt.setString(2, "女");
pstmt.executeUpdate();
//getGeneratedKeys()这个方法为什么不是返回int类型而是要返回一个ResultSet类型呢?因为他考虑到了联合主键
//的问题,有可能是一张表中的几个字段合起来构成一个id,这样就不能返回一个int类型了,如果是联合主键返回的是
//多列的内容,我们可以遍历ResultSet得到联合主键列的值
ResultSet rs = pstmt.getGeneratedKeys();
int id = 0;
if(rs.next()) {
id = rs.getInt(1);
}
System.out.println(id + "===");
JdbcUtils.free(rs, pstmt, conn);
}
25、使用JDBC的批处理功能
//main方法调用测试批量插入与普通的insert所消耗的时间比
public static void main(String[] args) throws SQLException {
long start = System.currentTimeMillis();
for (int i = 0; i < 100; i++)
create(i);
long end = System.currentTimeMillis();
System.out.println("create:" + (end - start));
start = System.currentTimeMillis();
createBatch();
end = System.currentTimeMillis();
System.out.println("createBatch:" + (end - start));
}
//普通方法
static void create(int i) throws SQLException {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "insert into user(name,birthday, money) values (?, ?, ?) ";
ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, "no batch name" + i);
ps.setDate(2, new Date(System.currentTimeMillis()));
ps.setFloat(3, 100f + i);
ps.executeUpdate();
} finally {
JdbcUtils.free(rs, ps, conn);
}
}
//批量插入数据
static void createBatch() throws SQLException {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "insert into user(name,birthday, money) values (?, ?, ?) ";
ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
//每循环一次都会形成一条新的sql语句被打包,直到循环完成然后进行批量的处理
//那么可不可以无限量的增加呢?其实会产生内存溢出的情况,到底循环多少次进行打包才合适
//这个值要经过测试
for (int i = 0; i < 100; i++) {
ps.setString(1, "batch name" + i);
ps.setDate(2, new Date(System.currentTimeMillis()));
ps.setFloat(3, 100f + i);
ps.addBatch();
}
int[] is = ps.executeBatch();
} finally {
JdbcUtils.free(rs, ps, conn);
}
}
- 大小: 105.3 KB
分享到:
相关推荐
【标题】"传智播客 李勇老师 JDBC代码全部和ppt" 提供的是一个关于JDBC编程的全面学习资源,由知名教育机构传智播客的讲师李勇主讲。JDBC(Java Database Connectivity)是Java编程语言中用于与各种数据库进行交互的...
传智播客-Jdbc-李勇.ppt 传智播客-Jdbc-李勇.ppt 传智播客-Jdbc-李勇.ppt
传智播客李勇hibernate源码1-20课,目录如下:01_hibernate介绍与动手入门体验;02_hibernate入门案例的细节分析; 03_hibernate入门案例的代码优化; 04_Session接口及get|load|persist方法 05_实体对象的三种状态...
【传智播客李勇hibernate PPT】是一份由知名教育机构传智播客推出的关于Hibernate框架的培训资料,由讲师李勇精心制作。这份PPT详细讲解了Hibernate在实际开发中的应用,旨在帮助学员深入理解并掌握这一强大的Java...
传智播客_hibernate李勇笔记是在学习李勇老师讲的hibernate3.2.5后整理的笔记
hibernate_传智播客_李勇
【传智播客李勇hibernate】课程详解了ORM框架Hibernate的核心概念和技术,适合初学者和想要深入了解Hibernate的开发者。以下是对课程内容的详细解析: 1. **引入ORM框架**: - 阻抗不匹配:由于Java是面向对象的...
传智播客hibernate讲解视频配套ppt,李勇
【传智播客 李勇 Hibernate 讲解】 在IT领域,ORM(Object-Relational Mapping,对象关系映射)框架是将面向对象的模型与关系数据库之间进行映射的关键技术,有效地解决了“模型不匹配”(也称为“阻抗不匹配”)的...
本资源“传智播客JDBC_所有源码与ppt”是针对JDBC学习的一个综合包,包含了源代码和相关的教学演示PPT,非常适合初学者或希望深入理解JDBC的开发者使用。传智播客是一家知名的教育机构,其课程内容通常具有系统性和...
传智播客 hibernate PPT 很经典
**JDBC笔记 李勇** JDBC(Java Database Connectivity)是Java编程语言中用来规范应用程序如何访问数据库的应用程序编程接口,提供了诸如连接数据库、发送SQL语句、处理结果集等功能。李勇老师的JDBC学习笔记主要...
- **传智播客李勇hibernate**:李勇老师的Hibernate课程可能包括了Hibernate的基本原理、实体类与表的映射、CRUD操作、查询语言(HQL)、Criteria查询、级联操作、缓存策略等。他可能强调了如何优雅地处理数据库操作...
在IT行业中,SSH三大框架是Java Web开发领域中不可或缺的一部分...这些PPT资源,如"传智播客李勇hibernate.ppt"、"spring.ppt"、"struts2.ppt",提供了详细的讲解和示例,对学习SSH框架的开发者来说是一份宝贵的资料。
本Java培训资料集合了多位知名讲师的精华内容,包括比向东、方力勋、黎活明、张孝祥、杨忠科、李勇、韩顺平等,覆盖了Java的基础到高级知识点,旨在帮助学习者全面掌握Java编程。 1. **Java基础** - **语法基础**...