estore简版商城疑点思考
读取 web应用中的 资源 文件
解答:
本人博文:javaweb读取 web 应用中的资源文件
http://blog.csdn.net/a15920804969/article/details/78605493
事务管理时,ThreadLocal本地线程类的使用?
解答:
ThreadLocal类【线程本地类】的使用:确保同一个线程使用的始终是同一个Connection对象
ThreadLocal类: 内部是维护了 一个 map , 这个map 的key 始终 都是 当前 的线程
key:当前线程 value:connection对象
为什么使用这个类?
因为进行事务处理时,要开启事务,提交事务,回滚事务
因为操作数据库时,是从连接池中获取到的连接:connection,
一般的事务处理,我们无法确定我们拿到的是不是同一个connection,如果是不同的,我们的事务管理就会失败;所以为了确保拿到的是同一个connection,我们需要处理connection的唯一性问题?
而ThreadLocal类就解决了这个问题
ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,在同一个线程,实现了Connection对象的共享
ThreadLocal学习文章:Java并发编程:深入剖析ThreadLocal
网址:https://www.cnblogs.com/dolphin0520/p/3920407.html
多表查询?
多表查询后,同时查询出来的几个表的数据如何处理?如何分别进行获取?
解决方案:
可以使用DBUtils框架
commons-dbutils 是Apache 组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。因此dbutils成为很多不喜欢hibernate的公司的首选。
TxQueryRunner它是QueryRunner的子类!(commons-dbutils.jar)
可用起来与QueryRunner相似的!
我们的类支持事务!它底层使用了JdbcUtils来获取连接!
简化jdbc的操作
QueryRunner的三个方法:
1)update() --> insert、update、delete
2)query() --> select
3)batch() --> 批处理
@Test
publicvoid testUpdate() throws SQLException
{
Stringsql = "insert into t_person(pid,pname,age,sex) values(?,?,?,?)";
Object[]params = {"1", "p1", 1, "男"};//给sql中对应的参数
QueryRunnerqr = new TxQueryRunner();//我们没有给对象提供连接池
qr.update(sql,params);//执行sql,也不提供连接,它内部会使用JdbcUtils来获取连接
}
@Test
publicvoid testUpdate2() throws Exception {
try{
JdbcUtils.beginTransaction();//开启事务
Stringsql = "insert into t_person(pid,pname,age,sex) values(?,?,?,?)";
QueryRunnerqr = new TxQueryRunner();
Object[]params = {"2", "p2", 2, "女"};
qr.update(sql,params);//执行
if(false){
thrownew Exception();
}
params= new Object[]{"3", "p3", 3, "女"};
qr.update(sql,params);//执行
JdbcUtils.commitTransaction();//提交事务
}catch(Exception e) {
try{
JdbcUtils.rollbackTransaction();//回滚事务
}catch (SQLException e1) {
}
throwe;
}
}
/**
* 我们知道JDBC查询的结果的是ResultSet
* 而QueryRunner查询的结果是通过ResultSet映射后的数据。
* QueryRunner第一步是执行select,得到ResultSet
* 把ResultSet转换成其他类型的!
* 通过转换结果:
* javaBean:把结果集封装到javaBean中
* Map:把结果集封装到Map中
* Scalar:把结果集封装到Object中(结果集是单行单列)
* @throws SQLException
*
*/
@Test
publicvoid testQuery1() throws SQLException {
Stringsql = "select * from t_person where pid=?";
QueryRunnerqr = new TxQueryRunner();
/*
* 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
* BeanHandler --> 它是ResultSetHandler的实现类,它的作用是把结果集封装到Person对象中
*/
Personp = qr.query(sql, new BeanHandler
System.out.println(p);
}
/*
* 一行结果集记录对应一个javaBean对象,多行就对应List
* @throws SQLException
*/
@Test
publicvoid testQuery2() throws SQLException {
Stringsql = "select * from t_person";
QueryRunnerqr = new TxQueryRunner();
/*
* 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
* BeanListHandler --> 它是ResultSetHandler的实现类,
* 它的作用是把结果集封装到List
*/
List
System.out.println(list);
}
@Test
publicvoid testQuery3() throws SQLException {
Stringsql = "select * from t_person where pid=?";
QueryRunnerqr = new TxQueryRunner();
/*
* 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
* MapHandler --> 它是ResultSetHandler的实现类,
* 它的作用是把结果集封装到Map对象中
*/
Map
System.out.println(map);
}
/**
*一行对应一个Map,多行对应List
* @throws SQLException
*/
@Test
publicvoid testQuery4() throws SQLException {
Stringsql = "select * from t_person";
QueryRunnerqr = new TxQueryRunner();
/*
* 第二个参数类型为ResultSetHandler,它是一个接口,表示映射的结果类型。
*
* MapListHandler--> 它是ResultSetHandler的实现类,
* 它的作用是把结果集封装到List
*/
List
System.out.println(mapList);
}
@Test
publicvoid testQuery5() throws SQLException {
Stringsql = "select count(*) from t_person";//结果集是单行单列的
QueryRunnerqr = new TxQueryRunner();
Objectobj = qr.query(sql, new ScalarHandler());
/*
* 我们知道select count(1),结果一定是个整数!
* > Integer > Long > BigInteger
* 不同的驱动,结果不同!
* 无论是哪种类型,它都是Number类型!强转成Number一定不出错
*/
Numbernumber = (Number)obj;
longcnt = number.longValue();
System.out.println(cnt);
}
/**
1. 把结果集封装到map中
2. 使用map生成Person对象
3. 使用map生成address对象
4. 把两个实体对象建立关系
@Test
publicvoid testQuery6() throws SQLException {
Stringsql = "SELECT * FROM t_person p, t_address a WHERE p.aid=a.aid ANDp.pid=?";
QueryRunnerqr = new TxQueryRunner();
//1.得到Map
Mapmap = qr.query(sql, new MapHandler(), "aaa");
//2. 把Map中部分数据封装到Person中
Personp = CommonUtils.toBean(map, Person.class);
//3.把Map中部分数据封装到Address中
Addressaddr = CommonUtils.toBean(map, Address.class);
//4.建立两个实体的关系
p.setAddress(addr);
System.out.println(p);
}
Dao 、DaoFactory、DaoImpl的用意?
eg:CustomersDao(dao层接口)+ CustomersDaoImplement(到层接口实现类) + DaoFactory(dao层工厂)++dao.properties(配置文件):
其中不直接写dao类的目的,而是写dao接口,然后再写dao接口的实现类,并写个dao工厂类:目的是为了解耦合操作
解耦合
new对象—>工厂的静态方法【接口+配置文件+反射技术】
读取配置文件,得到对象实例。
好处:增强扩展性,方便代码的书写和维护
应用场景:某个模块不会写,可以自己定义一个接口,然后外包给其它人去实现,利用解耦合技术,然后集成进来实现好接口的类,再进行修改下配置文件,即可达成目的。
1、写代码时,不够仔细,导致出现了重复代码,而引发了一些不必要的问题。
2、map集合的el表示式遍历,不熟悉
3、html的一些事件的使用,很多不熟悉!
4、javascript事件的使用,很多不熟悉!