一、BaseDao类优化版1.0:
前戏:把mysqlconnect、dbutils的jar包导进来,buildpath,添加属性文件,entry的pet类也要实现序列化接口。
1、在原来基础上,把driver、url、user、password抽出来变为静态私有属性,再用一个静态方法给这些
变量赋值,最后把这静态方法放在静态代码块中(确保在类加载完之后这方法也执行完毕,否则空指针异常)。
2、说一下方法怎么写:
public static init(){
//配置文件的路径
String path="属性文件的名字(赋值就好)";
//new一个pp对象出来
Properties pp=new Properties();
//用到反射获取属性文件路径,然后得到ips对象
InputStream ips=BaseDao.class.getClassLoader().getResourceAsStream(path);//参数就是配置文件的路径
//pp特有的读取属性文件的方法
pp.load(ips);//参数是输入流对象ips,所以回到上面想办法获取到ips对象
//拿到属性文件键值对的值,然后分别给每个属性赋值
driver=pp.getProperties("driver");
url=pp.getProperties("url");
user=pp.getProperties("user");
password=pp.getProperties("password");
}
3、在属性下面设置一静态代码块,里面调用静态方法init()。
4、至此如果测试一下,会报空指针异常,因为我确保不了这个静态方法已经执行了,所以在属性下面加一个静态代码块,里面调用init方法
答:为什么确保不了呢?????
二、BaseDao类优化版2.0:
1、思想就是把获得driver、url、user、password的方法抽取到一个新的utils包,在包里创建一个
ConfigManager类,类里就是写一个双重锁的懒汉单例模式。
2、下面是步骤:
1、私有化构造方法
private ConfigManager (){
//把属性文件的内容读到pp集合就是在私有构造方法完成的
//new pp对象出来
Properties pp=new Properties();
//获得属性文件路径
String path=”属性文件名字”;
//通过反射获得属性文件的内容,参数是属性文件路径的字符串类型,并返回ips对象
InputStream ips=ConfigManager.class.getClassLoader.getResourceAsStream(path);
//利用pp的load方法读取内容
pp.load(ips);//参数是ips,所以在上面用反射获取属性文件的内容参数是路径,并得到ips的返回类型
}
2、私有化静态的当前类对象
private static ConfigManager configManager=null;
3、提供一个对外的被获取对象的方法(双重锁方法,适用于分布式也非常的安全)
public static ConfigManager getConfigManager(){
if(configManager==null){
//锁类目的不是安全,是为了反射能找到这个类,如果锁当前对象,反射找不到这类,就报异常。???
synchronized(configManager.class){
if(configManager==null){
configManager=new ConfigManager;
}
}
}
}
4、再写一个获得属性文件键值对的值的方法
public String getValue(String key){
//利用pp的getProperties方法
return pp.getProperties(key);
}
3、对于优化版2.0注意地方:
1、我如何确保获取值时的方法用到的pp集合已经读取到属性文件的内容呢?
答:由于pp集合(对象)是在构造函数里,所以下面new ConfigManager时,就会做四件事,其中包括
调用本类的构造函数,所以构造函数已经执行,所以pp已经得到属性文件内容了。
2、对于静态的ConfigManager对象声明时,如果设为null,有可能会报异常,原因?
1、因为只要是静态的都放在静态区,设置之后有可能造成再赋值的时候不会改变,所以使用静态需要慎用。
3、为什么第二个锁要锁当前类呢?
1、如果锁当前对象,反射找不到这当前类,会报空指针异常。为什么呢???????
4、为何对entity的类实现序列化接口呢?除了效率高一点。
三、对实现类的优化:
1、思想大概就是利用dbutils的核心QueryRunner对象里的多种方法实现对数据库的增删改查功能。
2、增删改操作的用qr.update(connection,sql,(占位符的值,多少个都可以));
3、查询的用qr.query(connection,sql,new BeanListHandler(Hotel.class),(如果有占位符就在这里给参数赋值就好));
4、查询多少行用qr.query(connection,sql,new ScalarHaandler());//返回类型定义为Long,最后想办法转为int作为返回值就好。
四、dbutils框架:
1、属于持久层框架,对jdbc的封装,减轻程序员的压力,核心是orm(o代表object,r代表数据库字段,m代表映射)
2、核心主要是对数据库进行操作,都是orm映射关系,后面的mybatis hibernnate都是orm关系,这两个框架是链接到数据库
五、事务:
1、概念:一组操作,要么全部成功,要么全部失败。
2、事务的几大原则:acdl
1、a:原子性,就是最小的,不可分割的(同时执行sql语句,要么同时成功,要么同时失败)
2、c:一致性,同时执行两条sql语句,执行过程出现异常,要么回到最初状态、要么回到执行后的状态,不可能出现在中间状态。
3、d:隔离性,每个事务都不相互影响
4、l:持久性,只要commit成功,就不会再改变了。
3、常用存储引擎:
1、MyISAM和Inn
4、模拟转账功能:
1、数据库是自动提交数据库,现在set autoCommit=0,改为手动提交(意思就是jdbc那边还要有commit语句才能提交),设置开始事务start transaction;
2、执行一段update先
2、事务回滚 rollback;(永远回到上一步操作)