一、DBUtils概述与入门
1.QueryRunner类
构造方法:new QueryRunner(DataSource ds);//参数DataSource可传可不传; 但要保证链接在同一个事物中的数据源是同一个
主要方法:batch、update、query.(根据QueryRunner类的构造方法来确定是否使用数据源)
适用
批处理: int[]
batch(Connection conn,String sql,Object params[]);
int[] batch(String sql,Object params[]); //sql语句大体一致,参数不同
适用
查询: T
query(String sql,ResultSetHandler(<T> rsh),Object[] params);
适用
增删改: int
update(String sql,Object[] params);
int update(Connection conn,String sql,Object[] param);
二、DBUtils框架中的结果处理器 ResultSetHandler
1、BeanHandler和BeanListHandler:具体操作一个和多个JavaBean对象,返回Bean对象和List<Bean>。关键代码:Object
qr.query(sql, new BeanHandler());
2、ArrayHandler和ArrayListHandler:具体操作“
qr.query(sql, new ArrayListHandler());”返回 Object[] 和 List<Object[]>
3、MapHandler和MapListHandler:具体操作"
qr.query(sql, new MapListHandler());" 返回 Map<String,Object>和List<Map<String,Object>>
4、ColumnHandler和KeyedHandler:
ColumnHandler具体操作"
qr.query(sql, new ColumnHandler
(
"指定列名"
));"
用于操作单独的某一列数据,很有用 --
KeyedHandler具体操作"
qr.query(
sql, new KeyedHandler
("指定列名")//大Map的key
); " 该结果处理器教复杂,返回Map嵌套集合,key为指定的列名,value为Map集合(此集合为一条数据)
5、ScalarHandler:取只有一条记录的情况,取某一列的值
String sql = "select * from user where id=1";
Object obj = qr.query(sql, new ScalarHandler("name"));
三、实际开发中的事务控制
private Connection conn = null;
public void transfer(String source, String target, float money) {
try {
conn = DbcpUtil.getConnection();
conn.setAutoCommit(false);
AccountDao adao = new AccountDaoImpl(conn); //该DaoImpl使用的是外界传入的数据源
Account sourceAccount =
adao.queryAccount(source);
Account targetAccount =
adao.queryAccount(target);
sourceAccount.setMoney(sourceAccount.getMoney() - money);
targetAccount.setMoney(targetAccount.getMoney() + money);
adao.update(sourceAccount);
int i = 1/0;
adao.update(targetAccount);
} catch (Exception e) {
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
throw new RuntimeException(e);
} finally {
try {
conn.commit();
conn.close();
}
四、ThreadLocal:是一个Thread的局部变量,而不是Thread的线程,他提供的tl.get()、set(Object)、remove()方法可以解决多线程程序的并发问题
AccountDaoThreadLocalImpl类
private QueryRunner qr = new QueryRunner(ThreadLocalUtil.getDataSource());
// 修改账户的余额
public void update(Account account) {
try {
String sql = "update account set money=? where name=?";
Object[] params = { account.getMoney(), account.getName() };
qr.update(ThreadLocalUtil.getConnection(), sql, params);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
// 按用户名查询账户
public Account queryAccount(String name) {
String sql = "select * from account where name=?";
Object[] params = { name };
try {
return qr.query(ThreadLocalUtil.getConnection(), sql,new BeanHandler<Account>(Account.class), params);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
五、JdbcUtil改造(ThreadLocalUtil工具类)
ThreadLocalUtil工具类优点,保证线程安全也可以控制事物
private static DataSource ds ;
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
1、 在获得连接和开启事物中可以保证肯定返回连接或开启了事物(注:对应两个方法)
try {
Connection conn = tl.get();
if (conn == null) {
conn = ds.getConnection();
tl.set(conn);
}
return conn;
}
//conn.setAutoTransaction(false);//开启事物
2、在rollback、commit事物、close连接中可以保证使用的连接是同一个(注:对应三个方法)
try{
Connection conn = tl.get();
if(conn!=null){
conn.rollback();//事物回滚
conn.commit();//提交事物
//在关闭连接时要先tl.remove();
tl.remove();
conn.close();
}
}
六、多表操作CRUD
1、一对多
private List<Employee> emps = new ArrayList<Employee>();
2、多对多
private List<Teacher> teachers= new ArrayList<Teacher>();
private List<Student> stus= new ArrayList<Student>();
3、一对一:数据库表结构需要借助第三方表
private Idcard idcard;
七、HttpURLConnection//模式浏览器的功能:发送请求和接收响应
//接收服务器信息
URL url = new URL("http://localhost:8080/1.html");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.getResponseCode();//获得响应码
conn.getResponseMessage();//获得响应吗描述
InputStream in = conn.getInputStream();//获qu正文
while((line=in.read(buf))!=-1){ //读取正文
syso(new String(buf,0,line));
}
conn.disconnect();//关连接
//向服务器发送信息
URL url = new URL("http://localhost:8080/day15_web/servlet/ServletDemo1");
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestProperty("名","值");//可向服务器写东西了
conn.setDoOutput(true);//要写数据先打开DoOutput
OutputStream out = conn.getOutputStream();//获得字节输出流
out.write("username=shanjie".getBytes()); //写数据
out.close();
conn.disconnect(); //关连接
s