连接池概念与JDBC Template模板

今日内容:

  • ###jdbc事务

  • 连接池概念

  • c3p0

  • Driud

  • JDBC Template

  • DBUtils

JDBC 事务控制

什么是事务:一个包含多个步骤或者业务操作。如果这个业务或者多个步骤被事务管理,则这多个步骤要么同时成功,要么回滚(多个步骤同时执行失败),这多个步骤是一个整体,不可分割的。

操作:

开启事务:mysql----->start transaction

提交事务:commit

回滚事务:rollback

使用Connection对象来管理事务

开启事务: setAutoCommit(boolean autoCommit): 指定该方法里面传入false值,手动开启事务。

在执行sql语句之前开启事务。

提交事务:commit();---->当所有的sql语句执行完毕才提交事务

回滚事务:rollback();---->当事务中发生异常时回滚事务 回滚事务放在catch语句。

示例:以银行转账为例:让张三给李四转账10000钱

// 含有事务的转账
	public static void transform02() {
		// 让张三给李四转账10000钱
		/*
		 * 首先让张三的钱减少10000
		 * 然后让李四的钱增加10000
		 */
		//定义实现转账的两条sql语句
		double money = 10000;
		String username01 = "张三";
		String username02= "李四";
		
		String sql01 = "update account set balance = balance-? where username = ?";
		String sql02 = "update account set balance = balance+? where username = ?";
		// 使用Connection对象手动开启事务 setAutoCommit(boolean autoCommit):
		Connection con = DBUtil.getConnection();
		try {
			con.setAutoCommit(false);
			// 通过con获取预处理对象 先让张三的钱减少10000
			ps01 = con.prepareStatement(sql01);
			ps01.setDouble(1, money);
			ps01.setString(2, username01);
			// 执行sql语句
			int count = ps01.executeUpdate();
			// 手动制造一个异常
			int i = 1 / 0;
			// 再让李四的钱增加10000
			// 通过con获取预处理对象
			ps02 = con.prepareStatement(sql02);
			ps02.setDouble(1, money);
			ps02.setString(2, username02);
			// 执行sql语句
			int coun02 = ps02.executeUpdate();
			// 提交事务
			con.commit();
			System.out.println("转账成功!");
		} catch (Exception e) {
			// 事务回滚
			try {
				con.rollback();
				System.out.println("转账失败!");
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
			e.printStackTrace();
		}finally {
			// 把打开的各种连接对象释放掉
			try {
				ps02.close();
				ps01.close();
				con.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

连接池

什么连接池:其实就是一个容器,在这个容器当中存放着多个连接对象。

当系统开始运行时,可以让系统提前创建多个连接对象,放到容器中(连接池),当客户端需要连接对象时,可以从连接池中申请一个连接,去访问数据库,当该连接使用完毕时,不再释放归还给系统,而是把这个连接对象归还给连接池。

好处:

可以大大节省系统开销

可以提高访问的速度。

实现操作:

javax.sql 连接池

JNDI -----> Java Naming and Directory Interface Java命名和目录接口

使用JNDI 降低程序和数据库的耦合度,使你的程序更加方便配置和维护以及部署。

是JavaEE中规范中的重要规范之一。是EJB的相关的知识。

DataSource接口 它里面并不提供具体的实现,而是由驱动程序供应商(数据库厂商)提供

c3p0: 它是数据库连接池的一套技术

druid:也是一套数据据库连接池的技术,由阿里巴巴提供的。

C3p0:数据库连接池技术

步骤:

去官网下载两个jar包:c3p0-0.9.5.2.jar 和 mchange-commons-java-0.2.12.jar

植入到工程的classpath类路径下,不要忘记导入mysql驱动jar包 mysql-connector-java.jar

定义配置文件:

文件类型:c3p0.properties 或者 c3p0-config.xml

路径:放到classpath类路径下 对于工程来说直接放到src下面即可

获取DataSource对象 : 数据库连接池对象 通过实例化ComboPooledDataSource来获取

从连接池中获取连接对象。 getConnection()

Druid 德鲁伊连接池技术

步骤:

去官网去下载一个德鲁伊的jar ---> druid-1.0.9.jar

定义配置文件:使用properties文件类型的,名字随便起

手动加载配置文件信息: Properties集合

获取DataSource对象 :通过工厂方式来实现的,DruidDataSourceFactory

从连接池中获取连接对象:getConnection()

JDBC Template

Spring框架提供了对JDBC操作的简单封装,使用JDBCTemplate对象来简化JDBC开发流程。

步骤:

从官网下载对应的spring-jdbc相关的jar包,导入工程类路径下,放到lib文件夹下面即可

创建JDBCTemplate对象。依赖于DataSouce连接池(数据源)

使用JDBCTemplate对象中的api方法实现crud操作

DML操作: update()

DQL操作: 查询 不用select,使用query

query(): 将查询的结果集封装成JavaBean对象

query()方法的参数:RowMapper

手动装配:使用匿名内部类,自定义装配查询的每条记录值

自动装配:使用Spring提供的BeanPropertyRowMapper实现类,完成对数据的自动装配

具体操作-->new BeanPropertyRowMapper<类型>(类型.class)

queryForMap(): 将查询的结果集封装成map集合,只能封装一条记录:键key是字段名,值value是字段值,结果集记录数只能是1

queryForList():将结果集封装成List集合,在list集合中有多条记录,每一条记录都是一个map集合

List<Map<Object,Object>> list ;

queryFoObject():将结果集封装成一个对象,一般用于聚合函数 查询总记录数 int count()

具体操作

   // 增删改动作
   // 修改数据
	public static void modifyData() {
		
		int count = jdbcTemplate.update("update account set username = ? where username = ?", "小五","王五");
		System.out.println(count);
	}
	// 删除数据
	public static void deleteData() {
		int count = jdbcTemplate.update("delete from account where username = ?", "小五");
		System.out.println(count);
	}
	// 插入一条数据
	public static void insertDate() {
		int count = jdbcTemplate.update("insert into account values(null,?,?)", "王五",5000);
		System.out.println(count);
	}
	public static void test() {
		// 查询张三的这条信息 封装到账户对象中
		String username = "张三";
		String sql = "select * from account where username = ?";	
		Map<String, Object> map = jdbcTemplate.queryForMap(sql,username);
		System.out.println(map);// {id=1, username=张三, balance=20000.0}
	}
	
	// 简化手动封装的方法
	public static void queryAll() {
		String sql = "select * from account";
		// Incorrect column count: expected 1, actual 3
		List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
		System.out.println(list);
		
	}
	
	// 使用query方法优化queryBean方法
	public static void queryBean2() {
		List<Account> list = jdbcTemplate.query("select * from account", new BeanPropertyRowMapper<Account>(Account.class));
		System.out.println(list);
		
	}
	
	// 将查询到结果集封装成JavaBean对象
	public static void queryBean() {
		String sql = "select * from account where username = '张三'";
		// RowMapper<T>
		List<Account> list = jdbcTemplate.query(sql, new RowMapper<Account>() {
			@Override
			public Account mapRow(ResultSet set, int arg1) throws SQLException {
				// 封装查询到每一条记录值
				Account account = new Account();
				int id = set.getInt(1);
				String username = set.getString(2);
				double balance = set.getDouble(3);
				account.setId(id);
				account.setUsername(username);
				account.setBalance(balance);
				return account;
			}
		});
		
		System.out.println(list);// [Account [id=1, username=张三, balance=20000.0]]
	}
	
	// 查询总记录   查询account表中的所有记录数
	public static void queryTotalNum() {
		// queryFoObject()
		Integer count = jdbcTemplate.queryForObject("select count(*) from account", Integer.class);
		System.out.println(count);// 4
	}

德鲁伊链接操作

druid.properties

# 键值对格式的  键和值用=连接
# 连接数据库的四大组件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///java31?characterEncoding=utf8
username=root
password=123456
#初始化池子的连接数量
initialSize=10
#最大池子连接数量
maxActive=50
#最长等待时间
maxWait=3000

# 德鲁伊配置
# 连接数据库 四大组件 1.驱动 2.数据库 3.账号  4.密码
# 参数方面 :1.初始化链接数量 2.最大池子连接数量 3.最长等待时间 
public class DruidDemo01 {
	
	public static void main(String[] args) throws Exception {
		// 手动加载配置文件信息  使用Properties集合
		Properties properties = new Properties();
		// 读取配置文件信息  使用类加载器  classpath 类路径下
		InputStream is = DruidDemo01.class.getClassLoader().getResourceAsStream("druid.properties");
		// 使用Properties集合读取输入流  load
		properties.load(is);
		// 获取DataSource对象 :通过工厂方式来实现的,DruidDataSourceFactory 调用createDataSource(properties);
		DataSource pool = DruidDataSourceFactory.createDataSource(properties);
		// 从池中获取一个连接对象
		Connection connection = pool.getConnection();
		System.out.println(connection);// com.mysql.jdbc.JDBC4Connection@5b80350b
}
public class DruidDemo02 {

	private static DataSource pool = null;
	
	//把加载德鲁伊配置文件放进静态代码块中
	static {
		//手动添加配置文件 Properties集合
		Properties properties=new Properties();
		//使用当前类的字节码对象获取该字节码对象的类的加载器 去东区配置文件信息 Loader加载器《利用输入流进行读取》
		InputStream is=DruidDemo02.class.getClassLoader().getResourceAsStream("druid.properties");
		
		try {
			//把输入流中的信息读取properties集合当中
			properties.load(is);
			//获取DataSource对象:通过工厂方式类实现的,DruidDataSourceFactory
			pool=DruidDataSourceFactory.createDataSource(properties);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	//主方法
	public static void main(String[] args) throws Exception {
		// 添加一条数据
		//insertData();
		// 修改一条数据  王五--->小五
		updateData();
		// 删除一条数据  把小五的这条信息删除掉
		//deleteData();
		// 查询全部某个表中的全部数据
		//queryAll();
	}
	
	// 查询全部某个表中的全部数据
	public static void queryAll() throws Exception {
		Connection conn = pool.getConnection();//连接器
		String sql = "select * from account";//查询语句
		PreparedStatement ps = conn.prepareStatement(sql);//准备对象
		ResultSet set = ps.executeQuery();//结果集合 ps.调用执行语句
		// 遍历
		while(set.next()) {
			int id = set.getInt(1);
			String username = set.getString(2);
			double balance = set.getDouble(3);
			System.out.println(id + "---" + username + "----" + balance);
		}
		// 释放
		set.close();
		ps.close();
		conn.close();
	}
	
	// 删除数据
	public static void deleteData() throws Exception {
		Connection conn = pool.getConnection();
		String sql = "delete from account where name = ?";
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1, "张三");
		int count = ps.executeUpdate();
		if (count > 0 ) {
			System.out.println("删除成功!");
		} else {
			System.out.println("删除失败!");
		}
		ps.close();
    	conn.close();// 归还给连接池中
	}
	
    // 修改数据
    public static void updateData() throws Exception {
    	Connection conn = pool.getConnection();
    	String sql = "update account set name = ? where name = ?";
    	PreparedStatement ps = conn.prepareStatement(sql);
    	ps.setString(1, "张久");
    	ps.setString(2, "李四");
    	int count = ps.executeUpdate();
    	if (count > 0 ) {
			System.out.println("修改成功!");
		} else {
			System.out.println("修改失败!");
		}
    	ps.close();
    	conn.close();// 归还给连接池中
    }
	
	// 添加一条数据
	public static void insertData() throws Exception {
		// 注册驱动
		// 获取连接
		Connection conn = pool.getConnection();
		// 准备sql语句
		String sql = "insert into account values(null,?,?)";
		// 获取执行sql对象
		PreparedStatement ps = conn.prepareStatement(sql);
		ps.setString(1,"老王");
		ps.setDouble(2, 5000);
		// 执行sql语句,把sql语句发送给mysql服务器
		int count = ps.executeUpdate();
		if (count > 0) {
			System.out.println("添加成功");
		}else {
			System.out.println("添加失败!");
		}
		// 释放资源
		ps.close();
		conn.close();// 归还给连接池
	}
    
	
}

JDBC Template模板

// 按照JavaBean标准类    建议使用包装类
public class Account{

	private Integer id;
	private String username;
	private Double balance;// null
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Double getBalance() {
		return balance;
	}
	public void setBalance(Double balance) {
		this.balance = balance;
	}
	public Account() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Account(Integer id, String username, Double balance) {
		super();
		this.id = id;
		this.username = username;
		this.balance = balance;
	}
	@Override
	public String toString() {
		return "Account [id=" + id + ", username=" + username + ", balance=" + balance + "]";
	}

	
}
// 使用德鲁伊连接池配置工具类
public class DruidUtil {

	private static DataSource pool;
	// 把加载德鲁伊的一套放进静态代码块中
	static{
		//手动加载配置文件信息: Properties集合
		Properties properties = new Properties();
		// 使用当前类的字节码对象获取该字节码对象的类加载器  去读取配置文件信息
		InputStream is = DruidDemo02.class.getClassLoader().getResourceAsStream("druid.properties");
		try {
			// 把输入流中的信息读取properties集合当中
			properties.load(is);
			// 获取DataSource对象 :通过工厂方式来实现的,DruidDataSourceFactory
			pool = DruidDataSourceFactory.createDataSource(properties);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	// 对外提供获取连接的对象
	public static Connection getConnection() throws SQLException {
		return pool.getConnection();
	}
	
	// 提供获取连接池的方法
	public static DataSource getDataSource() {
		return pool;
	}
	
	// 释放资源的方法
	public static void closeAll(ResultSet set,PreparedStatement ps,Connection conn) {
		if (set != null) {
			try {
				set.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (ps != null) {
			try {
				ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}
public class JDBCTemplateDemo01 {
	// 创建JDBCTemplate对象  依赖于DataSource数据源
	static JdbcTemplate jdbcTemplate = new JdbcTemplate(DruidUtil.getDataSource());
	
	public static void main(String[] args) {
		
		
		//增加
		//insertDate();
		//查询
		//test();
		//删除
		//deleteData();
		//修改
		modifyData();
		
	}
	
	// 修改数据
	public static void modifyData() {
		
		int count = jdbcTemplate.update("update account set name = ? where name = ?", "杨柳","赵柳");
		System.out.println(count);
	}
	
	// 删除数据
	public static void deleteData() {
		int count = jdbcTemplate.update("delete from account where name = ?", "老王");
		System.out.println(count);
	}
	
	// 增删改动作
	public static void insertDate() {
		// 插入一条数据
		int count = jdbcTemplate.update("insert into account values(null,?,?)", "王五",5000);
		System.out.println(count);
	}
	
	//查询
	public static void test() {
		// 查询张三的这条信息 封装到账户对象中
		String name = "老王";
		String sql = "select * from account where name = ?";	
		Map<String, Object> map = jdbcTemplate.queryForMap(sql,name);
		System.out.println(map);// {id=1, username=张三, balance=20000.0}
	}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值