jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/dangdang
jdbc.username=root
jdbc.password=root
----------------------------------------------------------------
class.forName(oracle.jdbc.OracleDriver)
jdbc:oracle:thin:@localhost:1521:xe
"com.mysql.jdbc.Driver"
jdbc:mysql://localhost:3306/student
JDBC
一,JDBC内容
接口:sun定义 java.sql 和javax.sql
实现类:数据库厂商提供
二,jdbc使用
1,如何使用jar
--dos使用
classpath中添加jar路径
2,jdbc流程
a:注册驱动类
b:创建链接
c:创建statement(不常用)
d:执行sql
e:处理结果
f:释放资源statement 也要close
get列时序号从1开始
3,prepareStatementjava.sql statement子接口
PrepareStatement ps =conn.prepareStatement(sql);
ps.setxxx(1,name)
ps.setxxx(2,password)
ps.exq exu (使用午餐的构造)
里面的参数不用拼接
在执行前时插入
4.两者区别
state = com.cre...
stat.execute(sql)
不安全,有注入
prep = conn.create..(sql)
prep.execute()
无sql注入,切性能更高
服务器操作
1检查权限,
2检查语法
3,sql转化为内部指令 前三是编译过程
4,执行指令
statement创建成功时不发送sql,执行时发送
例:for(int i=0;i<10;i++{
stat.ex(insert...)
}
prep 可只把setxxx写在for循环中
只用编译一次即可,所以说也叫作预编译语句
stat:异构sql
prep:同构sql(只有参数不同
日期转换:日期转换 strDate --- util.Date---sql.Date
//插入或修改字段的类型是时间类型Date时,需要使用时间转换
//
1.设置格式,格式应与字符串相匹配。和数据库中to_date方法类似
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//
2.strDate--util.Date
Date util
Date = format.parse(strDate);
//
3.util.Date---sql.Date
java.sql.Date date = new java.sql.Date(utilDate.getTime());
1.事务控制
JDBC默认的是自动的事务提交
相关API:控制事务提交的对象为连接 Connection
//设置事务提交方式为手动
conn.setAutoCommit(false);//true---自动提交 false---手动提交
//事务提交
conn.commit();
//事务回滚
conn.rollback();
2.业务类方法的书写步骤
//1.获取Connection
conn = JdbcUtil2.getConnection();
System.out.println("这是service获得连接:"+conn);
//2.设置事务提交为手动提交
conn.setAutoCommit(false);
//3.调用DAO中的方法完成业务操作
dao.insert(clazz);
//4.提交事务 or 回滚事务
conn.commit();
conn.rollback
3.当前的事务控制存在问题
首先service层获得的连接与Dao不是一条 其次通过单例可以解决这样的问题,但是会存在线程不安全的情况。
为了解决线程安全,且可以控制事务的问题
我们需要使用线程局部表变量,ThreadLocal
~~~
####
九、线程局部变量
~~~java
线程局部变量,再多线程环境下,可以为每个使用该变量的线程 分配线程内部独有的 线程变量值。
1.API:
ThreadLocal th = new ThreadLocal();
th.set(obj);//往线程局部变量中设置
obj = th.get();//返回该线程局变量的值
th.remove();//移除该线程局变量的值
2.作用:
1)保证 同一个线程内部 使用相同的值
2)保证不用线程使用不用的值
3.原理:
当调用 set方法时,会将当前线程对象当做Key,将set中的参数当做value 放入到一个map集合中 ,这个集合由Thread进行管理的。
当使用get方法时,以当前线程为key来向该map集合取值。
4.使用ThreadLoacl来修改getConnection方法
//创建连接的方法
private static ThreadLocal
public static Connection getConnection(){
Connection conn = th.get();
if(conn==null){//如果为空就创建
//1.注册驱动
try {
Class.forName(p.getProperty("driver"));
//2.建立连接
conn = DriverManager.getConnection(p.getProperty("url"),p.getProperty("username"),p.getProperty("password"));
//3.并把连接放入ThreadLocal
th.set(conn);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return conn;
}
if(conn!=null){
try {
conn.close();
th.remove();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
注意:1)在控制事务时,dao内不要关闭连接
2)在关闭连接后,要清空线程局部变量中的废连接
~~~
####
十、JDBC的
分层分包:
都在域名倒写的包下 比如 com.zzu.xjh
1)sql 存放了关于该项目相关的一些sql语句文档
2)conf 放置了配置文件
3)util 放置了该项目的工具类
4)test 放置了该项目相关的测试类
5)entity 放置了该项目的实体类
6)dao 放置该项目的DAO接口 在该包下应有一个impl包 里面放置 对应dao的实现类
7)service 放置该项目的service 接口 在该包下应有一个impl包 里面放置 对应service 的实现类
8)conroller/action 放置该项目的控制器
9)view (可能出现)
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; public class JdbcTemplate{ /* * 专门完成增 删 改操作 * * insert into t_user (id,name,password) values (suns_seq.nextval,?,?); * * jdbcTemplate.update(sql,new Object[]{"suns","123456"}); * * delete from t_user where id = ? * * jdbcTemplate.delete(sql,new Object[]{1}); * * update t_product set name=?,price=? where id = ? * * jdbcTemplate.update(sql,new Object[]{"suns",10.2,1}); * * 可变长参数 1 等同于数组 * 2 只能放在参数表最后 ,只能有一个 * * "delete from t_user where id = 10"; * */ public void update(String sql,Object... args){ Connection conn = null; PreparedStatement pstmt = null; try{ conn = JDBCUtil.getConnection(); pstmt = conn.prepareStatement(sql); if(hasUpdateParam(args)){ for(int i=0;i query(String sql,RowMapper rowMapper,Object... args){ Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; List rets = new ArrayList (); try{ conn = JDBCUtil.getConnection(); pstmt = conn.prepareStatement(sql); if(hasUpdateParam(args)){ for(int i=0;i rowMapper,Object... args){ Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; T ret = null; try{ conn = JDBCUtil.getConnection(); pstmt = conn.prepareStatement(sql); if(hasUpdateParam(args)){ for(int i=0;i
import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.Properties; /* * 性能 效率 内存使用 * 维护性 (便于修改) * 基本功能 */ public class JDBCUtil { private static Properties p = new Properties(); private static ThreadLocaltl = new ThreadLocal (); static{ //1 读入Properties文件 InputStream is = JDBCUtil.class.getResourceAsStream("/jdbc.properties"); //2 传入Properties集合 try { p.load(is); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } //创建连接 public static Connection getConnection() throws Exception{ Connection conn = tl.get(); if(conn==null){ Class.forName(p.getProperty("driver")); conn = DriverManager.getConnection(p.getProperty("url"),p.getProperty("username"),p.getProperty("password")); tl.set(conn); return conn; } return conn; } //关闭资源 public static void close(Connection conn,PreparedStatement pstmt,ResultSet rs){ if(rs!=null){try{rs.close();}catch(Exception e){}} if(pstmt!=null){try{pstmt.close();}catch(Exception e){}} if(conn!=null){try{conn.close();tl.remove();}catch(Exception e){}} } public static void close(Connection conn,PreparedStatement pstmt){ if(pstmt!=null){try{pstmt.close();}catch(Exception e){}} if(conn!=null){try{conn.close();tl.remove();}catch(Exception e){}} } }
1:1,一般是双向关系
建实体类时,两边都建
但建表时只有一个外键,建在不主要一方
定义表时,定义外键,做唯一
private Integer id;
private String name;
private String password;
private Date birthday;
private PassPort passport;
---------------------------
private Integer id;
private String serial;
private Integer expire;
private Person person;
----------------------------
create table t_person(
id integer primary key,
name varchar(12),
password varchar(12),
birthday date
);
create table t_passport(
id integer primary key,
serial varchar(12),
expire varchar(12),
person_id integer unique references t_person(id)
);
--------------------------------------------------------------------------------------------
----------------------------------------------
n:1
多对一单向
private Integer id;
private String name;
private Double salary;
private Dept dept;
private Integer id;
private String code;
private String name;
create table t_employee(
id integer primary key,
name varchar(12),
salary decimal(12,2),
dept_id integer references t_dept(id)
);
create table t_dept(
id integer primary key,
code varchar(12),
name varchar(12)
);
--------------------------------------------------------------------------------------------------------------
1:n单向(n:1注意更换时 表不用改,表天生是双向的,俩表就一外键,在多的一方)
private Integer id;
private String name;
private Double salary;
private Integer id;
private String code;
private String name;
private List
-----------------------------------------------------------------------------------------------------------------
多对多双向,student,course
外键如何建?,不能建,
解决办法:引入第三张关系表
______________________________________________________________________
import java.sql.Connection; import java.sql.SQLException; /* * 事务管理器 用于控制事务 */ public class TransactionManager { public static void begin(){ try { Connection conn = JDBCUtil.getConnection(); conn.setAutoCommit(false); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public static void commit(){ Connection conn = null; try { conn = JDBCUtil.getConnection(); conn.commit(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ JDBCUtil.close(conn, null); } } public static void rollback(){ Connection conn = null; try { conn = JDBCUtil.getConnection(); conn.rollback(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ JDBCUtil.close(conn, null); } } }