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<Connection> th = new ThreadLocal<Connection>();
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<T> { /* * 专门完成增 删 改操作 * * 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<args.length;i++){ pstmt.setObject(i+1,args[i]); } } pstmt.executeUpdate(); }catch(Exception e){ e.printStackTrace(); }finally{ JDBCUtil.close(null, pstmt); } } private boolean hasUpdateParam(Object... args) { return args.length!=0; } public List<T> query(String sql,RowMapper<T> rowMapper,Object... args){ Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; List<T> rets = new ArrayList<T>(); try{ conn = JDBCUtil.getConnection(); pstmt = conn.prepareStatement(sql); if(hasUpdateParam(args)){ for(int i=0;i<args.length;i++){ pstmt.setObject(i+1, args[i]); } } rs = pstmt.executeQuery(); while(rs.next()){ T ret = rowMapper.mapRow(rs); rets.add(ret); } return rets; }catch(Exception e){ e.printStackTrace(); return null; }finally{ JDBCUtil.close(null, pstmt, rs); } } public T queryForObject(String sql,RowMapper<T> 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<args.length;i++){ pstmt.setObject(i+1, args[i]); } } rs = pstmt.executeQuery(); if(rs.next()){ ret = rowMapper.mapRow(rs); } return ret; }catch(Exception e){ e.printStackTrace(); return null; }finally{ JDBCUtil.close(null, pstmt, rs); } } }
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 ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); 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)
);
——————————————————————————————–
<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE mapper PUBLIC “-//mybatis.org//DTD Mapper 3.0//EN” “mybatis-3-mapper.dtd” >
<mapper namespace=”com.dzf.dao.o2o.PersonDao”>
<resultMap id=”personResultMap” type=”Person” >
<id property=”id” column=”person_id”/>
<result property=”name” column=”person_name”/>
<result property=”password” column=”person_password”/>
<result property=”birthday” column=”person_birthday”/>
<!– 当只有passport一个对象 –>
<association property=”passport” javaType=”PassPort”>
<id property=”id” column=”passport_id”></id>
<result property=”serial” column=”passport_serial”/>
<result property=”expire” column=”passport_expire”/>
</association>
</resultMap>
<select id=”queryPersonById” resultMap=”personResultMap”>
select p.id as person_id,p.name as person_name,p.password as person_password,p.birthday as person_birthday
,pp.id as passport_id,pp.serial as passport_serial,pp.expire as passport_expire
from t_person p inner join t_passport pp
on p.id = pp.person_id
where p.id = #{id}
</select>
</mapper>
———————————————-
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)
);
<resultMap id=”employeeResultMap” type=”Employee” >
<id property=”id” column=”employee_id”/>
<result property=”name” column=”employee_name”/>
<result property=”salary” column=”employee_salary”/>
<association property=”dept” javaType=”Dept”>
<id property=”id” column=”dept_id”></id>
<result property=”code” column=”dept_code”/>
<result property=”name” column=”dept_name”/>
</association>
</resultMap>
<select id=”queryEmployeeByName” resultMap=”employeeResultMap”>
select e.id as employee_id,e.name as employee_name,e.salary as employee_salary,
d.id as dept_id,d.code as dept_code,d.name as dept_name
from t_employee e inner join t_dept d
on e.dept_id = d.id
where e.name = #{name}
</select>
<select id=”queryDeptById” resultType=”Dept”>
select id,name,code
from t_dept
where id = #{id}
</select>
————————————————————————————————————–
1:n单向(n:1注意更换时 表不用改,表天生是双向的,俩表就一外键,在多的一方)
private Integer id;
private String name;
private Double salary;
private Integer id;
private String code;
private String name;
private List<Employee> list = new ArrayList<Employee>();记得初始化
<resultMap id =”deptResultMap” type=”Dept” >
<id property=”id” column = “dept_id”/>
<result property = “code” column=”dept_code”/>
<result property = “name” column=”dept_name”/>
<collection property=”list” ofType=”Employee”><!– 集合中元素类型 –>
<id property=”id” column=”employee_id”/>
<result property=”name” column=”employee_name”/>
<result property=”salary” column=”employee_salary”/>
</collection>
</resultMap>
<select id=”queryDeptByName” resultMap=”deptResultMap”>
select d.id as dept_id ,d.code as dept_code,d.name as dept_name,
e.id as employee_id,e.name as employee_name,e.salary as employee_salary
from t_dept d inner join t_employee e
on d.id = e.dept_id
where d.name = #{name}
</select>
<select id=”queryEmployeeById” resultType=”Employee”>
select id,name,salary
from t_employee
where id= #{id}
</select>
—————————————————————————————————————–
多对多双向,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); } } }