jdbc

Posted dean0731

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jdbc相关的知识,希望对你有一定的参考价值。

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)tryrs.close();catch(Exception e)
        if(pstmt!=null)trypstmt.close();catch(Exception e)
        if(conn!=null)tryconn.close();tl.remove();catch(Exception e)
    
    
    public static void close(Connection conn,PreparedStatement pstmt)
        if(pstmt!=null)trypstmt.close();catch(Exception e)
        if(conn!=null)tryconn.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);
        
        
    
    

 

以上是关于jdbc的主要内容,如果未能解决你的问题,请参考以下文章

JDBCJDBC连接mySQL数据库常见错误

JDBCJDBC连接mySQL数据库常见错误

JDBC

关于JDBC小总结

java JDBC编程学习笔记

java JDBC编程学习笔记