java三层架构实例

三层架构

分层
层次 特点
界面层(View) 呈现给用户。
业务逻辑层(Service BLL) 实现具体的业务逻辑,加工数据。
持久层(Dao) 与数据库的增删改查相关的代码实现。
好处

1.为了实现高内聚、低耦合
2.使得程序可重用性和可移植性增强

缺点

1.降低了系统的性能
2.导致级联的修改

简单框架

java三层架构实例_第1张图片

面向接口编程

1.辨析

接口 特点
接口 具体的一种代码结构
面向接口编程 一种思想,用于实现多态性,提升软件的灵活性和可维护性

2.优点
1)提升了代码的灵活性和复用性
2)良好的可扩展性
3)低耦合性

数据源与连接池

连接池概念

1)在系统启动的时候创建一批连接对象都保存在一个集合里面
2)如果需要数据库的连接,就可以从那这些对象中获得一个使用
3)数据库操作结束,在将这些对象放回集合中去,这样就可以节省资源
4)数据库连接池负责管理连接(分配连接和释放连接)
5)并没有真正的关闭资源

常见数据库连接池

1.C3P0
2.DBCP

C3P0的使用步骤

1.导入相应的jar包
2.设置连接池的参数
3.创建数据源,初始化数据库连接池
4.获取连接

此处C3P0的配置案例

<c3p0-config>
	<named-config name="mysql-config">
		<property name="driverClass">com.mysql.jdbc.Driverproperty>
		<property name="jdbcUrl">jdbc:mysql://localhost:3306/assetmanager?characterEncoding=utf-8property>
		<property name="user">rootproperty>
		<property name="password">1234property>
		
		<property name="initialPoolSize">10property>
		
		<property name="maxIdleTime">30property>
		
		<property name="maxPoolSize">100property>
		
		<property name="minPoolSize">10property>
		    
  		<property name="acquireIncrement">3property>    
	named-config>
c3p0-config>
C3P0使用案例
package com.hp.util;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

/**
 * 类描述:数据库操作工具类
 * 版本号: 1.0.0
 */
public class JdbcUtils {
	
	// 设置数据源(使用C3P0数据库连接池)
	private static ComboPooledDataSource dataSource=new ComboPooledDataSource("mysql-config");
	// 创建一个与事务相关的局部线程变量
	private static ThreadLocal<Connection> tl=new ThreadLocal<Connection>();
	
	/**
	 * 方法描述:获取数据源
	 * @return
	 */
	public static DataSource getDataSource(){
		return dataSource;
	}
	
	/**
	 * 方法描述:获取连接
	 * @return
	 * @throws SQLException 
	 */
	public static Connection getConnection() throws SQLException{
		// 获取线程局部变量的值 connection
		Connection conn=tl.get();
		if(conn==null){
			// 如果连接为空,则从数据库连接词池中获取连接
			conn=dataSource.getConnection();
		}
		return conn;
	}
	
	/**
	 * 方法描述:开启事务
	 * @throws SQLException
	 */
	public static void beginTranscation()throws SQLException{
		Connection conn=tl.get();
		if(conn!=null){
			throw new SQLException("不能重复开启事务");
		}
		// 获取连接
		conn=getConnection();
		// 关闭自动提交事务
		conn.setAutoCommit(false);
		// 将线程变量的值设置为connection
		tl.set(conn);
	}
	
	/**
	 * 方法描述:提交事务
	 * @throws SQLException 
	 */
	public static void commitTranscation() throws SQLException{
		Connection conn=tl.get();
		if(conn==null){
			throw new SQLException("没有开启事务 不能提交");
		}
		// 提交事务
		conn.commit();
		// 关闭连接
		conn.close();
		// 移除此线程局部变量的值
		tl.remove();
	}
	
	/**
	 * 方法描述:回滚事务
	 * @throws SQLException 
	 */
	public static void rollbackTranscation() throws SQLException{
		Connection conn=tl.get();
		if(conn==null){
			throw new SQLException("没有开启事务,不能回滚");
		}
		// 回滚事务
		conn.rollback();
		// 关闭连接
		conn.close();
		// 移除此线程局部变量的值
		tl.remove();
	}
}

DBUtil

介绍

1.是对JDBC做的简单封装,使用数据库连接池

主要类

1.QueryRunner
1)构造器QueryRunner():在事务中使用
2)构造器QueryRunner(DataSource):从数据库连接池中获取连接
3)update():执行增删改操作的调用

查询

1.query(sql,rsh,params):自动获取连接
2.query(conn,sql,rsh,params):手动获取连接
3.BeanHandler:获取单行数据,构造器需要一个Class类型的参数,用来把一行结果转换为指定类型的JavaBean对象。
4.BeanListHandler:获取多行数据,构造器需要一个Class类型的参数,用来把一行结果转换为指定类型的JavaBean对象,最终将多笔实例组成一个List集合,一堆JavaBean。

使用案例
返回单个记录:
public Admin login(Admin admin) {
		// 1.编写sql语句
		StringBuffer sql = new StringBuffer();
		sql.append("SELECT * ");
		sql.append("FROM admin ");
		sql.append("WHERE adminName = ? AND adminPassword = ?");
		// 2.创建一个QueryRunner对象,通过构造器提供数据源(从数据库中获取连接)
		QueryRunner queryRunner = new QueryRunner(JdbcUtils.getDataSource());
		Admin result = null;
		// 存放查询条件
		Object[] params = {admin.getAdminName(),admin.getAdminPassword()};
		try {
			// 3.执行query查询操作,BeanHandler:将结果集中第一行数据封装到一个对应的JavaBean实例中
			result = queryRunner.query(sql.toString(), new BeanHandler<>(Admin.class),
					params);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return result;
	}

返回多个记录:
public List<User> getAllUser() {
		String sql = "SELECT * FROM user";
		// 存放查询结果集合
		List<User> users = null;
		try {
			QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
			users = qr.query(sql, new BeanListHandler<>(User.class));
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return users;
	}
增删改时的使用:
public int addBank(Bank bank) {
		String sql = "INSERT INTO bank(bankName,bankTel) VALUES(?,?)";
		// 准备填充占位符的数组
		Object[] params = {bank.getBankName(),bank.getBankTel()};
		// 接收返回结果
		int result = 0;
		try {
			QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
			// 执行增删改操作同一调用update方法
			result = qr.update(sql, params);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
获取单个值的使用(一般用于注册后获取自动增长的主键id):
public Long addUser(User user) {
		StringBuffer sql = new StringBuffer();
		sql.append("INSERT INTO `user` ");
		sql.append("(userName,userPassword,realName,sex,tel,idCard,address) ");
		sql.append("VALUES(?,?,?,?,?,?,?)");
		Object[] params = {
				user.getUserName(),
				user.getUserPassword(),
				user.getRealName(),
				user.getSex(),
				user.getTel(),
				user.getIdCard(),
				user.getAddress()
		};
		// Long 包装类型
		Long result = null;
		try {
			QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
			// 第一种方式:获取新增的主键值,ScalarHandler获得单个值
			//qr.update(sql.toString(), params);
			//result = qr.query("SELECT LAST_INSERT_ID()", new ScalarHandler<>());
			// 第二种方式:线程安全的、返回插入数据的主键
			result = qr.insert(sql.toString(), new ScalarHandler<Long>(), params);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return result;
	}
删除某一银行及其用户(此处采用事物):
public boolean deleteBank(int bankId) {
		try {
			// 开启事务
			JdbcUtils.beginTranscation();
			// 删除银行对应的资产信息
			assetDao.deleteAssetByBankId(bankId);
			//int i = 10 / 0;
			// 删除银行信息
			bankDao.deleteBank(bankId);
			// 提交事务
			JdbcUtils.commitTranscation();
			return true;
		} catch (Exception e) {
			// 回滚事务
			try {
				JdbcUtils.rollbackTranscation();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		} 
		return false;
	}

工具类

public class JdbcUtils {
	
	// 设置数据源(使用C3P0数据库连接池)
	private static ComboPooledDataSource dataSource=new ComboPooledDataSource("mysql-config");
	// 创建一个与事务相关的局部线程变量
	private static ThreadLocal<Connection> tl=new ThreadLocal<Connection>();
	
	/**
	 * 方法描述:获取数据源
	 * @return
	 */
	public static DataSource getDataSource(){
		return dataSource;
	}
	
	/**
	 * 方法描述:获取连接
	 * @return
	 * @throws SQLException 
	 */
	public static Connection getConnection() throws SQLException{
		// 获取线程局部变量的值 connection
		Connection conn=tl.get();
		if(conn==null){
			// 如果连接为空,则从数据库连接词池中获取连接
			conn=dataSource.getConnection();
		}
		return conn;
	}
	
	/**
	 * 方法描述:开启事务
	 * @throws SQLException
	 */
	public static void beginTranscation()throws SQLException{
		Connection conn=tl.get();
		if(conn!=null){
			throw new SQLException("不能重复开启事务");
		}
		// 获取连接
		conn=getConnection();
		// 关闭自动提交事务
		conn.setAutoCommit(false);
		// 将线程变量的值设置为connection
		tl.set(conn);
	}
	
	/**
	 * 方法描述:提交事务
	 * @throws SQLException 
	 */
	public static void commitTranscation() throws SQLException{
		Connection conn=tl.get();
		if(conn==null){
			throw new SQLException("没有开启事务 不能提交");
		}
		// 提交事务
		conn.commit();
		// 关闭连接
		conn.close();
		// 移除此线程局部变量的值
		tl.remove();
	}
	
	/**
	 * 方法描述:回滚事务
	 * @throws SQLException 
	 */
	public static void rollbackTranscation() throws SQLException{
		Connection conn=tl.get();
		if(conn==null){
			throw new SQLException("没有开启事务,不能回滚");
		}
		// 回滚事务
		conn.rollback();
		// 关闭连接
		conn.close();
		// 移除此线程局部变量的值
		tl.remove();
	}
}

你可能感兴趣的:(java三层架构实例)