1.)连接池原理
说明:以前使用的jdbc的缺点:
1、操作数据库都需要创建连接,操作完成还需要关闭连接
2、创建连接和关闭连接需要可能比执行sql需要的时间都长
3、一个网站需要高频繁的访问数据库,如果短时间频繁的访问数据库服务器,
就容易造成服务器的宕机,即死机。
数据库连接池结构:
首先创建一定数量的连接,然后放到指定的地方。当我们需要获取连接的时候,直接从指定的地方获取。
用完了,我们再将连接放回去。这样就能将我们连接的回收利用。并且不用花费大量时间在创建和销毁连接上。
自定义连接池代码范例:
范例 表格:名称:emp
id | name | city |
---|---|---|
1 | 刘备 | 北京 |
2 | 关羽 | 上海 |
3 | 张飞 | 广州 |
需求:查询emp表的所有用户。
public class MyDatasourceTest {
//使用连接池实现
@Test
public void demo1() {
//1.从连接池获取连接
//2.将用完的连接放回到连接池中
//创建自定义连接池对象,初始化连接池
MyDatasource ds = new MyDatasource();
// 初始化值
Connection conn = null;
ResultSet rs = null;
PreparedStatement pst = null;
try {
// 获取连接// conn = JDBCUtils.getConnection();
conn=ds.getConnection();
String sql = "select * from emp";
// 获取发送sql的对象
pst = conn.prepareStatement(sql);
// 执行sql
rs = pst.executeQuery();
//处理结果
while(rs.next())
{
//取出数据
int id = rs.getInt("id");
String name = rs.getString("name");
String city = rs.getString("city");
//输出
System.out.println(id+"==="+name+"----"+city);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}finally{
JDBCUtils.release(null, pst, rs);
//2.将用完的连接放回到连接池中
ds.backPool(conn);
}
}
}
2.) 数据库连接池的实现步骤:
1、创建自定义连接池类 实现 javax.sql.DataSource接口;这是sun公司规定。
2、创建保存数据库连接的集合类使用LinkedList。 当做连接池。
3、在自定义连接池类的构造函数中始化数据库连接池,批量创建与数据库的连接(Connection),把连接保存到集合中。
4、实现DataSource这个接口中的getConnection()方法,每次调用getConnection方法时,从集合对象中取一个connection对象给用户。
注意:这个方法是从我们数据库连接池中获取连接,从连接池中获取之后需要将池子中的连接对象给删掉。这样就可以保证每次从连接池中获取的连接都是唯一的,不会重复的。
5、使用完connection 连接,调用自定义的backPool方法,将connection连接放回集合中,不要交给数据库。
注意:这里只是将连接放回到连接池中,而不是关闭连接。
DRUID(阿里巴巴-德鲁伊)连接池:
在工具类增加代码使用德鲁伊获取连接
具体代码如下:
3.) public static Connection getDruidConnection()
{
try {
//创建Properties集合对象
Properties p = new Properties();
//调用方法加载配置文件中的数据
p.load(new FileInputStream("druid.properties"));
//使用德鲁伊核心类调用静态方法获取配置文件中的数据
DataSource ds = DruidDataSourceFactory.createDataSource(p);
//从德鲁伊数据库连接池中获取连接
Connection conn = ds.getConnection();
//返回连接
return conn;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
3.)JdbcTemplate概念
JDBC已经能够满足大部分用户最基本的需求,但是在使用JDBC时,必须自己来管理数据库资源。
JdbcTemplate就是Spring对JDBC的封装,目的是使JDBC更加易于使用。JdbcTemplate是Spring的一部分。
JdbcTemplate处理了资源的建立和释放。他帮助我们避免一些常见的错误,比如忘了总要关闭连接。
他运行核心的JDBC工作流,如PreparedStatement的建立和执行,而我们只需要提供SQL语句和提取结果。
JdbcTemplate中的方法
功能说明
execute() | 用于执行DDL语句,如:建表 了解 |
---|---|
update() | 用于执行DML语句,实现对数据库表的增删改操作 掌握 |
queryXxx() | 用于执行DQL语句,实现对数据库表的各种查询的操作 一定掌握 |
JdbcTemplate类的构造方法:
JdbcTemplate(DataSource dataSource) | Construct a new JdbcTemplate, given a DataSource to obtain connections from. |
---|---|
JdbcTemplate类的方法:
JdbcTemplate类中创建表的方法:DDL(建表)语句 | public void execute(String sql) | 执行建表语句,没有返回值。参数是SQL语句,属于String类型。 |
JdbcTemplate类中修改表的方法:DML(修改表)语句 | public int update(String sql, Object…args) | 执行DML语句,对数据库表中的数据进行增删改操作返回:影响的行数参数:1) sql语句2) args是用来替换占位符的真实值,可变的参数 |
JdbcTemplate类中查询表的方法:执行DQL(查表)语句 | query() | 通用的查询方法,有多个同名方法的重载,可以自定义查询结果集封装成什么样的对象。 |
public <T> List<T> query(String sql, RowMapper<T> rowMapper) 执行查询语句,返回一个List集合,List中存放的是RowMapper指定类型的数据。
说明:
1)query() 必须要指定查询的结果集与JavaBean属性之间的对应关系,而结果集与JavaBean属性之间的对应关系需要传递一个接口作为query方法参数来确定。这个接口就是:RowMapper。
而RowMapper属于接口,不能创建对象,我们使用其实现类BeanPropertyRowMapper来创建对象。
BeanPropertyRowMapper类如下所示:
public class BeanPropertyRowMapper implements RowMapper
我们发现:BeanPropertyRowMapper类实现了RowMapper接口。所以我们只需要创建BeanPropertyRowMapper类的对象,然后将创建好的对象作为query方法的第二个参数传递即可。
2)BeanPropertyRowMapper类的构造方法说明:BeanPropertyRowMapper(Class mappedClass)
补充:mappedClass表示某个类的Class对象,这里我们在使用的时候只需要在构造方法中给某个类的.class即可。
例如:Student.class。
只要我们给某个类的.class对象,在底层那么就会将数据库表中对应的字段值给这个类的成员变量赋值,
所以在创建JavaBean的时候,要求成员变量名一定要和数据库表中的字段名一致,这样才可以完成封装。
使用举例:
List<Student> students = jdbcTemplate.query("select * from student", new BeanPropertyRowMapper<>(Student.class));
queryForList() 返回多条记录的查询结果,封装成一个List集合 默认List集合中的每个元素是Map对象,即List<Map<String,Object>>
如果要封装成List对象,使用query()方法。
public List<Map<String, Object>> queryForList(String sql, Object... args) 传入参数,执行查询语句,返回一个List集合,List中存放的是Map类型的数据。
说明:
1)使用举例:
List<Map<String, Object>> mapList = jdbcTemplate.queryForList(“select * from student”);
2)多行多列。
queryForObject() 返回查询只有单一对象的结果,这个单一结果应该是简单的数据类型,如:Integer.class、Long.class、String.class,
不能直接封装成JavaBean对象。可以用于聚合函数的查询结果。
public <T> T queryForObject(String sql, Class<T> requiredType, Object... args):传入参数, 执行查询语句,返回一个指定类型的数据。
说明:
1)返回查询只有单一对象的结果,这个单一结果应该是简单的数据类型,如:int.class、long.class、 String.class。也可以用于聚合函数的查询结果。
2)参数:
sql:表示要执行的sql语句.
requiredType:表示必须给的类型,最后需要返回的Class类的对象.
args:属于可变参数,传入的真实参数,例如给sql语句的占位符赋值的真实值.
使用举例:
String name= jdbcTemplate.queryForObject(“select name from student where id=?”,String.class,2);
第一个参数表示一条sql语句
String.class表示查询出来name列的类型的Class对象
2 表示id是2的数据
3)查询的是单行单列。
queryForMap() 返回Map<String,Object>的查询结果,其中键是列名,值是表中对应的记录。
用于查询结果只有1条记录的情况。如果结果集返回多条记录会出现异常。
public Map<String, Object> queryForMap(String sql, Object... args) 传入参数,执行查询语句,将一条记录放到一个Map中。
说明:
1)参数:
sql 表示查询的sql语句
args 表示给第一个参数的sql语句的占位符,设置值的
使用举例:
Map<String, Object> map = jdbcTemplate.queryForMap(“select * from student where id=?”, 2);
第一个参数表示一条sql语句
2 表示id是2的数据
2)查询单行多列