Java Database Connectivity
(Java数据库连接)
JDBC是Java定义的访问数据库的规范(也就是一套接口),各大数据库厂商实现这套接口(写成一套自己厂子的jar
包·),应用程序员通过引用各大厂商的规范(也就是他们定义的jar
包),来完成各大数据库的访问。在访问这些各大厂商的数据库时,我们使用jdbc
的定义的这一套接口来编程,相对而言就减少了学习成本,不用学习各个数据库厂商的规范,只需要学习jdbc
规范即可
有关jdbc
,最重要的莫过于它的一套操作流程啦。
- 加载驱动
- 创建连接
- 定义sql语句,创建Statement
- 执行操作,获取结果集
- 关闭连接和资源
关于上面这套流程,使用Oracle
的连接规范举例:
public static void main(String[] args) throws SQLException {
Connection conn = null;
Statement stmt = null;
//1. 加载驱动
try {
Class.forName("oracle.jdbc.OracleDriver");
//2. 建立连接
conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:ORCL", "SCOTT", "tiger");
//3. 获取Statement对象
stmt = conn.createStatement();
//4. 执行sql语句
int num = stmt.executeUpdate("insert into stu(id,name,pwd)values(1,'zhangsan','123')");
//5. 操作结果
if(num>0){//
System.out.println("插入成功");
}
// 6. 关闭jdbc的对象
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally {
if(stmt!=null){
stmt.close();
}
if(conn!=null){
conn.close();
}
}
}
对于日常开发而言,基本上都是使用框架的各种操作,一般不接触这一套,不过,对于上面
的规范实现而言,我们需要了解其原理,对于这套操作,我们可以把它封装成工具类 :
public class JDBCUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try {
FileInputStream fileInputStream = new FileInputStream("src\\com\\llm\\test\\demo\\db.properties");
Properties prop = new Properties();
prop.load(fileInputStream);
driver = prop.getProperty("driver");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void updateByString(String sql,Object[] objs){
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = getConnection();
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < objs.length; i++) {
preparedStatement.setObject(i+1,objs[i]);
}
int i = preparedStatement.executeUpdate();
if (i > 0){
System.out.println("更新成功");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
close(connection,preparedStatement,null);
}
}
public static Connection getConnection(){
Connection conn=null;
try {
Class.forName(driver);//加载数据驱动
conn = DriverManager.getConnection(url, username, password);// 连接数据库
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("加载数据库驱动失败");
}catch(Exception e){
e.printStackTrace();
System.out.println("连接数据库失败");
}
return conn;
}
public static void close(Connection conn, PreparedStatement ps, ResultSet rs){
try {
if(rs!=null){
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(ps!=null){
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
工具类加载的配置文件使用详解:
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
username=scott
password=tigger
有了这个工具类,就可以不用再重复的获取连接,以及可以把关闭连接的代码略去,可以把
更多的心思放在sql的编写上
下面就是使用这个工具类完成的一个小练习,完成基本的增删改查工作:
数据库建表如下:
create table user2(
username varchar(20) default '',
password varchar(20) default ''
)
select * from user2;
下面是代码:
public class UserTest {
static List<User> users = new LinkedList<>();
public static void main(String[] args)throws Exception {
findAll();
}
// [1] 查找所有数据
public static void findAll() throws Exception{
Connection conn = JDBCUtils.getConnection();
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select * from user2");
while (rs.next()){
users.add(new User(rs.getString(1),rs.getString(2)));
}
//遍历数据结果集
users.stream().forEach(System.out::println);
}
// [2] 添加一条数据
public static void insert() throws Exception{
Connection conn = JDBCUtils.getConnection();
String sql = "insert into user2(username,password) values(?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,"周三");
ps.setString(2,"abcdeee");
int i = ps.executeUpdate();
if (i > 0){
//遍历数据结果集
users.stream().forEach(System.out::println);
}
}
// [3] 更新一条数据
public static void update() throws Exception{
Connection conn = JDBCUtils.getConnection();
String sql = "update user2 set password = ? where username = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,"周三");
ps.setString(2,"hahaha");
int i = ps.executeUpdate();
if (i > 0){
//遍历数据结果集
users.stream().forEach(System.out::println);
}
}
// [4] 删除一条数据
public static void delete() throws Exception{
Connection conn = JDBCUtils.getConnection();
String sql = "delete from user2 where username = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,"周三");
int i = ps.executeUpdate();
if (i > 0){
//遍历数据结果集
users.stream().forEach(System.out::println);
}
}
上面的代码都是使用代码真刀真枪的和数据库之间进行连接操作,技术在发展,现在常用的
框架,比如Spring Data JPA
,明显不是简单的直接的连接数据库,而是使用到了 Dao
模式 +
数据库连接池,目前大部分数据访问层框架都是这种套路,所以我们还是有必要了解了解这
个 Dao
和数据库连接池
滴。
DAO模式
DAO (DataAccessobjects 数据存取对象)是指位于业务逻辑和持久化数据之间实现对持久化数据的访问。通俗来讲,就是将数据库操作都封装起来。
DAO模式的操作套路就是把关系型数据库的每一行数据都映射成一个对象,然后通过这些
对象,来对数据库里面的数据进行访问,在使用对象的时候,使用接口和工具类完成文件的
解耦和连接的生成。
DAO模式的文件目录结构如下:
对于下面这个定义的User
实体类而言
public class User {
private String userName;
private String password;
}
使用UserDao
接口来访问user
表
public interface UserDao {
//通过名字修改密码
int updatePassByName(User user);
//查找到所有的User
List<User> findAll();
}
UserDaoImpl
里面保存所有的具体处理逻辑,当然数据的操作封装到了User
对象里面
public class UserDaoImpl implements UserDao {
@Override
public int updatePassByName(User user){
Connection conn = JDBCUtils.getConnection();
PreparedStatement ps = null;
String sql = "update user2 set password = ? where username = ?";
int i = 0;
try {
ps = conn.prepareStatement(sql);
ps.setString(1,user.getUserName());
ps.setString(2,user.getPassword());
i = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(conn,ps,null);
}
return i;
}
@Override
public List<User> findAll() {
List<User> users = new LinkedList<>();
Connection conn = JDBCUtils.getConnection();
Statement stat = null;
ResultSet rs = null;
try {
stat = conn.createStatement();
rs = stat.executeQuery("select * from user2");
while (rs.next()){
users.add(new User(rs.getString(1),rs.getString(2)));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCUtils.close(conn,null,rs);
}
return users;
}
}
除了DAO模式,还的看看连接池
JDBC连接池
Connection Pool (连接池)
连接池就是存储连接的一个池子,和线程池等池子一样,连接池相当于是一个容器,使用这个容器可以更好的管理连接,并且需要使用的话直接拿过去用,减少了即时创建的性能损失
JDBC连接池有很多实现,主要有 dbcp,c3p0,druid
三种实现
在分析他们的实现之前,我们可以尝试自己定义一个简单的连接池:
public class ConnectionPool {
//默认为十个连接
private static List<Connection> conns = Collections.synchronizedList(new ArrayList<>(10));
static {
for (int i = 0; i < 10; i++) {
conns.add(JDBCUtils.getConnection());
}
}
//获取连接
public static Connection getConnection(){
Connection remove = null;
if (conns.size() > 0){
remove = conns.remove(0);
}
return remove;
}
//归还连接
public static void returnConnection(Connection conn){
conns.add(conn);
System.out.println("归还连接成功");
}
}
这个简单的连接池使用上面定义的JDBCUtils
类创建连接,然后使用静态的List
来充当容器
的角色,然后使用List的remove和add方法,来完成连接的获取和归还工作,原理非常简
单,关于各大连接池技术的实现,思路都是相似的
关于连接池技术的原理大概就是上面的套路,下面可以使用常见的dbcp
技术做一个例子,
采用三步走战略:
第一步:导入下面的包:
编写如下配置文件:
driverClassName=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
username=scott
password=tigger
第二步:编写获取连接工具类:
public class DBUtils2 {
private static DataSource dataSource = null;
static{
try {
Properties properties = new Properties();
properties.load(new FileInputStream("D:\\BaiduNetdiskDownload\\dailyLearning\\src\\com\\llm\\test\\demo\\db.properties"));
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
第三步:编写测试类进行测试
public static void findAll() throws Exception{
Connection conn = DBUtils2.getConnection();
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("select * from user2");
while (rs.next()){
users.add(new User(rs.getString(1),rs.getString(2)));
}
//遍历数据结果集
users.stream().forEach(System.out::println);
}
打印如下内容:
可见,连接池的操作也是极为简单的
通过 DAO模式 + 连接池
技术的综合使用,都是为了让程序得到更好的性能并且让编程更加容
易,目标就是让编码更简单,程序运行效率更高,这篇文章有很多不足之处,有缘人看到请
多批评指正。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/202483.html