JDBC 进阶

一:ORM(Object Relationship Mapping)

对象关系映射,一行数据与一个实体对象的对应。

        I.将一行零散数据进行一次整理(一行数据--->一个实例)

        II.表名 = 类名;字段名 = 属性名;

        III.提供Getters and Setters、无参构造方法。

 


对于日期类型:Java中存在两种java.util.Date和java.sql.Date。

①.java.util.Date:

扫描二维码关注公众号,回复: 122735 查看本文章

I.Java语言常规应用层的日期类型,支持直接获取当前系统时间、可通过自定义字符串进行创建。

II.无法直接插入数据库。

 

②.java.sql.Date:

I.数据库应用的日期类型,必须借助1970年起的毫秒值进行创建。

II.可以直接插入数据库。

 

③.java.text.SimpleDateFormat:

I.将字符串与java.util.Date相互转换。

II.SimpleDateFormat sdf = new SimpleDateFormat("格式化字符串");

III.sdf.parse(); //字符串转java.util.Date();

IV.sdf.format();//将日期格式化为字符串

 

④.注意:

java.util.Date:Fri Aug 08 11:59:59 CST 2008

java.sql.Date:yyyy-MM-dd(覆盖了父类提供的toString())

 

SimpleDateFormat sdf = new SimpleDateFormat(yyyy-MM-dd hh:mm:ss);

格式化的字符串 = sdf.format(utilDate);

对日期类型转换的封装
public class DateConvertUtil {
	private static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
	
	//将字符串转为java.util.Date  为了将字符串日期存入实体类中
	public static java.util.Date toUtilDate(String date){
		try {
			return sdf.parse(date);
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	//将java.util.Date转为java.sql.Date   为了向数据库中存
	public static java.sql.Date toSqlDate(java.util.Date date){
		return new java.sql.Date(date.getTime());
	} 
	
	//将java.util.Date转为String 为了view页面展示
	public static String toString(java.util.Date date){
		return sdf.format(date);
	}
}

二:DAOData Access Object)数据访问层

将对一张表的操作(增删改查),封装在一个对象的多个方法中。

根据不同需求提供对应的方法(insert、update、delete、select、selectAll)。


三:Service(Biz/Business)业务逻辑层


代表面向用户的一个功能,可以由一次或多次的DAO调用组成。

I.数据操作的复用:DAO数据访问对象

II.业务功能的复用:Service业务逻辑对象


四:事务控制

1.事务的边界:业务方法的首行-->整个方法结束(全部视为原子操作,要成功、都成功;要失败、都失败。)

2.手动控制事务:

        I.修改事务提交方案:conn.setAutoCommit(false);

        II.conn.commit();

        III.conn.rollback();

        IV.try catch final:异常的向上报告,连接对象的释放。


ThreadLocal对象:

 

        I. 线程工具类:可以在整个线程(单条执行路径)所持有的Map中,存储一个键(threadlocal)值(conn)。

        II. 将参数对象(Connection conn)添加到当前线程中:

        private static final ThreadLocal<Connection> tl = new ThreadLocal<Connection>(); //工具类

 

        III. 修改getConnection方法:

        Connection conn = tl.get(); //获取线程中保存的Connection对象

        if(conn == null){ //当线程中没有保存过Connection对象时

        conn = DriverManager.getConnection(url, userName, password); //获取连接对象

        tl.set(conn); //并保存至线程中

        }

        return conn;

 

        IV. 在release中关闭conn时,同时tl.remove(); //移除线程中的连接对象,只有业务提交或回滚之后才关闭、移除连接。

 T

get() 
          返回此线程局部变量的当前线程副本中的值。

 void

remove() 
          移除此线程局部变量当前线程的值。

 void

set(T value) 
          将此线程局部变量的当前线程副本中的值设置为指定值。

//加入ThreadLocal的JDBC封装
public class JDBCUtil {
	private  static final Properties pro=new Properties();
	private  static ThreadLocal<Connection> tl=new ThreadLocal<Connection>();	
	
	static{
		try {
			InputStream is=new FileInputStream("bin//jdbc.properties");
			pro.load(is);
			String classname=pro.getProperty("classname");
			Class.forName(classname);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
		
	public static Connection getConnection(){
		Connection conn=tl.get();
		try{
			if(conn==null){
				String url=pro.getProperty("url");
				String user=pro.getProperty("user");
				String pwd=pro.getProperty("pwd");
				conn=DriverManager.getConnection(url, user, pwd);
				tl.set(conn);
			}			
		}catch (Exception e){
			e.printStackTrace();
		}
		
		return conn;
	}
	
	public static void relise(ResultSet rs,PreparedStatement prsm, Connection conn){
		try{
			if(rs!=null)
				rs.close();
			if(prsm!=null)
				prsm.close();
			if(conn!=null){
				conn.close();
				tl.remove();
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}

}

事务由service层开启,service层完成提交或回滚

public boolean addStudent(Student stu) {
		boolean flag=false;
		try{
			TransactionManager.begin();//开启事务
			int count= dao.insert(stu);
			if(count>0)
				flag=true;
			TransactionManager.commit();//提交事务
		}catch(Exception e){
			TransactionManager.rollback();//回滚事务
			throw new RuntimeException(e);
		}
		return flag;
	}

五:事务的封装

public class TransactionManager {
	//开启事务
	public static void begin(){
		Connection	conn=JDBCUtil.getConnection();
		try {
			conn.setAutoCommit(false);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	//提交事务
	public static void commit(){
		Connection conn=JDBCUtil.getConnection();
		try {
			conn.commit();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			JDBCUtil.relise(null, null, conn);
		}	
	}
	//回滚事务
	public static void rollback(){
		Connection conn=JDBCUtil.getConnection();
		try {
			conn.rollback();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally{
			JDBCUtil.relise(null, null, conn);
		}
		
	}
}

六:DAO层的再封装


 ①:对于增删改操作,除了SQL语句不同,绑定的参数不确定,返回值以及其它代码完全一致。

prsm.setObject(1, “id”);

因此,我们可以动态传入sql语句,  对需要绑定参数用可变长参数 包装成Object 进行统一封装。

②:对查询操作   

为了使工具具有通用性,我们利用泛型+接口回调的方式,让实体类自己实现对应对象封装的方法。

接口:

public interface Encaplation<T> {
	public T encap(ResultSet rs);
}

实体实现接口的封装方法:

public class EncaplationStudent  implements Encaplation<Student>{
	@Override
	public Student encap(ResultSet rs) {
		try{
			return new Student(rs.getString(1),rs.getString(2),rs.getString(3),rs.getString(4),rs.getDate(5),rs.getString(6));
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}
}


对增删改查操作的再封装:

public class JDBCTemplate<T> {
	
	public int commontUpadte(String sql,Object... parm){
		Connection conn=JDBCUtil.getConnection();
		PreparedStatement prsm=null;
		try{			
			prsm=conn.prepareStatement(sql);
			for(int i=0;i<parm.length;i++){
				prsm.setObject(i+1, parm[i]);
			}
			return prsm.executeUpdate();
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCUtil.relise(null, prsm, null);
		}
		return 0;	
	}
	
	public List<T> commontQuery(String sql , Encaplation<T> en, Object... params){
		List<T> list = new ArrayList<T>();		
		Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;		
		try {
			conn = JDBCUtil.getConnection();
			ps = conn.prepareStatement(sql);
			// 绑定参数
			for (int i = 0; i < params.length; i++) {
				ps.setObject(i + 1, params[i]);
			}		
			rs = ps.executeQuery();	
			while(rs.next()){
				//ORM(一行数据对应一个实体的封装)
				T t = en.encap(rs);
				list.add(t);
			}			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBCUtil.relise(rs, ps, null);
		}
		return list;
	}
}

 


猜你喜欢

转载自blog.csdn.net/sugar_map/article/details/79874020