java JDBC DAO ORM Domain

一、认识JDBC

JDBC是用于在Java语言编程中与数据库连接的API.JDBC是一个规范,它提供了一整套接口,允许以一种可移植的访问底层数据库API。使用JDBC驱动程序来访问数据库,并用于存储数据到数据库中.

java JDBC DAO ORM Domainjava JDBC DAO ORM Domainjava JDBC DAO ORM Domain

解释上面两幅图:

java应用程序通过JDBC API首先连接到JDBC Driver,这些JDBC驱动器都是由各大数据库厂家针对JDBC提供的,我们可以在网上下载jar包来使用,然后通过JDBC驱动器就能连接到我们的数据库了。

第一步 添加驱动

1.在项目当中创建一个文件夹为lib
2.把Mysql驱动包复制到该文件夹下
3.builder path 编译路径
复制代码

第二步 连接到数据库

package con.meils.jdbc.conn;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class ConnectionClass {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
	// TODO Auto-generated method stub
	
	
	// 1、加载驱动
	// 把com.mysql.jdbc.Driver这份字节码加载进JVM
	// 当一份字节码加载进JVM的时候,就会执行字节码文件中的静态代码块
	// 这里加载该字节码之后会实例化一个驱动器
	Class.forName(<span class="hljs-string">"com.mysql.jdbc.Driver"</span>);
	
	// 2、连接
	String url = <span class="hljs-string">"jdbc:mysql://localhost:3306/mytest"</span>;
	String username = <span class="hljs-string">"root"</span>;
	String password = <span class="hljs-string">"zjj19970517"</span>;
	Connection connection = DriverManager.getConnection(url, username, password);
	
	// 3、验证连接
	System.out.println(connection); // 如果有输出,表明连接成功
}

}

复制代码

第三步 操作数据库创建表

package con.meils.jdbc.ddl;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class CreateTable {

	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub
		// 1\加载驱动
		// 把com.mysql.jdbc.Driver这份字节码加载进JVM
		// 当一份字节码加载进JVM的时候,就会执行字节码文件中的静态代码块
		// 这里加载该字节码之后会实例化一个驱动器
		Class.forName("com.mysql.jdbc.Driver");

		String url = "jdbc:mysql://localhost:3306/jdbc_db";
		String username = "root";
		String password = "zjj19970517";
		// 2\ 连接数据库
		Connection connection = DriverManager.getConnection(url, username, password);
		
		
		// 3\创建sql语句
		String sql = "create table stu (id int , name varchar(20), age int)";
		
		// 4\执行sql语句
		Statement st = connection.createStatement();
		int row = st.executeUpdate(sql);
		
		// 5\释放
		st.close();
		connection.close();
		
		
		
	}

}

复制代码
java JDBC DAO ORM Domain

为什么要释放资源呢?

java JDBC DAO ORM Domain

第四步 插入数据

package con.meils.jdbc.dml;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class InsertClass {
public static void main(String[] args) {
	// TODO Auto-generated method stub
	
	
	// ================ 插入数据 ================
	
	Connection conn = null;
	
	Statement st = null;
	
	
	try {
		// 1、加载驱动
		Class.forName(<span class="hljs-string">"com.mysql.jdbc.Driver"</span>);
		
		// 2、创建连接
		String url = <span class="hljs-string">"jdbc:mysql://localhost:3306/mytest"</span>;
		String user = <span class="hljs-string">"root"</span>;
		String password = <span class="hljs-string">"zjj19970517"</span>;
		conn = DriverManager.getConnection(url, user, password);
		
		// 3、创建sql语句
		String sql = <span class="hljs-string">"insert into stu values(1, ‘zjj‘, 20)"</span>;
		st = conn.createStatement();
		
		// 4、执行语句
		int row = st.executeUpdate(sql);
		System.out.println(row);
	}catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 5、释放
		<span class="hljs-keyword">if</span>(st!=null) {
			try {
				st.close();
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
		<span class="hljs-keyword">if</span>(conn!=null) {
			try {
				conn.close();
			}catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		
	}
	
}

}

复制代码

第五步 查询操作

java JDBC DAO ORM Domain
package con.meils.jdbc.dql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class QueryClass {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
	// TODO Auto-generated method stub

	// ================ 查询数据 ================
	
	// 1\加载驱动
			// 把com.mysql.jdbc.Driver这份字节码加载进JVM
			// 当一份字节码加载进JVM的时候,就会执行字节码文件中的静态代码块
			// 这里加载该字节码之后会实例化一个驱动器
			Class.forName(<span class="hljs-string">"com.mysql.jdbc.Driver"</span>);

			String url = <span class="hljs-string">"jdbc:mysql://localhost:3306/mytest"</span>;
			String username = <span class="hljs-string">"root"</span>;
			String password = <span class="hljs-string">"zjj19970517"</span>;
			// 2\ 连接数据库
			Connection connection = DriverManager.getConnection(url, username, password);
			
			
			// 3\创建sql语句 
			String sql = <span class="hljs-string">"select count(*) as total from stu"</span>; // 查询一共有几行数据
			
			// 4\执行sql语句
			Statement st = connection.createStatement();
			ResultSet rs = st.executeQuery(sql);
			
			<span class="hljs-keyword">if</span>(rs.next()) {
				int count = rs.getInt(<span class="hljs-string">"total"</span>);
				System.out.println(count); // 1
			}
			
			// 5\释放
			st.close();
			connection.close();
}

}

复制代码

java JDBC DAO ORM Domainjava JDBC DAO ORM Domainjava JDBC DAO ORM Domain

数据类型对照表:

java JDBC DAO ORM Domain

上面我们基本学会了如何与数据库打交道,但是这样使用存在许多的弊端,比如:每一步操作都进行一次数据库连接,造成浪费,所以我们在实际中要使用DAO思想来处理。

二、DAO设计

1、什么是DAO

java JDBC DAO ORM Domain

DAO(Data Access Object)数据存储对象,介于业务逻辑层和持久层之间,实现持久化数据访问。

不使用DAO的时候:

java JDBC DAO ORM Domain

使用DAO的情况:

java JDBC DAO ORM Domain

三、ORM映射关系

java JDBC DAO ORM Domain

四、Domain

1、认识domain

java JDBC DAO ORM Domain

2、domain类

java JDBC DAO ORM Domain

3、保存数据

java JDBC DAO ORM Domain

4、获取数据

java JDBC DAO ORM Domain

五、DAO设计规范

java JDBC DAO ORM Domain

案例

我们可以编写一个DAO接口,定义了常用的数据库操作方法,这时候我们同时会连接多个数据库,比如是mysql 和 oracle ,我们可以分别实现oracleDao和mysqlDao两个类,不同类里面定义不同的操作数据库的代码,实现的功能确实相同的。

java JDBC DAO ORM Domain

所以面向接口编程是很重要的,也是一个很好的方式。

1、包命名规范

java JDBC DAO ORM Domain

2、类命名规范

java JDBC DAO ORM Domain

3、开发步骤

java JDBC DAO ORM Domain

目录如下

java JDBC DAO ORM Domain

内容实现:

java JDBC DAO ORM Domain

接口实现类的具体内容:

package com.meils.jdbc.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.meils.jdbc.dao.IStudentDao;
import com.meils.jdbc.domain.Student;
import com.meils.jdbc.utils.JdbcUtil;
/**

实现DAO接口的类
@author apple



*/
public class StudentDaoImpl implements IStudentDao{
@Override
/**
 * 存储学生
 * @param stu
 */
public void save(Student stu) {
	// TODO Auto-generated method stub
	Connection conn = null;
	PreparedStatement ps = null;
	
	try {
		// 连接数据库
		conn = JdbcUtil.getConnection();
		
		String sql = <span class="hljs-string">"insert into student (name, age) values (? , ?)"</span>;
		
		// 创建预编译
		ps = conn.prepareStatement(sql);
		ps.setString(1, stu.getName());
		ps.setInt(2, stu.getAge());
		
		// 执行更新
		ps.executeUpdate();
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		JdbcUtil.close(conn, ps, null);
	}
}

@Override
public void delete(int id) {
	Connection conn = null;
	PreparedStatement ps = null;
	try {
		// 连接数据库
		conn = JdbcUtil.getConnection();
		
		String sql = <span class="hljs-string">"delete from student where id = ?"</span>;
		
		// 创建预编译
		ps = conn.prepareStatement(sql);
		ps.setInt(1, id);
		// 执行更新
		ps.executeUpdate();
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		JdbcUtil.close(conn, ps, null);
	}
}

@Override
public void update(int id, Student stu) {
	
	Connection conn = null;
	PreparedStatement ps = null;
	try {

		conn = JdbcUtil.getConnection();
		
		String sql = <span class="hljs-string">"update student set name=?, age=? where id = ? "</span>;
		ps = conn.prepareStatement(sql);
		
		ps.setString(1, stu.getName());
		ps.setInt(2, stu.getAge());
		ps.setInt(3, id);
		// 执行
		ps.executeUpdate();
		
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		JdbcUtil.close(conn, ps, null);
	}
	

}

@Override
public Student findOne(int id) {
	Connection conn = null;
	PreparedStatement ps = null;
	ResultSet rs = null;
	try {
		
		conn = JdbcUtil.getConnection();
		// sql语句
		String sql = <span class="hljs-string">"select * from student where id = ?"</span>;
		ps = conn.prepareStatement(sql);
		ps.setInt(1, id);
		// 执行
		rs = ps.executeQuery();
		
		<span class="hljs-keyword">if</span> (rs.next()) {
			// 保存数据
			Student stu = new Student();
			stu.setName(rs.getString(<span class="hljs-string">"name"</span>));
			stu.setAge(rs.getInt(<span class="hljs-string">"age"</span>));
			stu.setId(rs.getInt(<span class="hljs-string">"id"</span>));
			<span class="hljs-built_in">return</span> stu;
		}

	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		// 销毁
		JdbcUtil.close(conn, ps, rs);

	}
	
	<span class="hljs-built_in">return</span> null;
}

@Override
public List&lt;Student&gt; <span class="hljs-function"><span class="hljs-title">findAll</span></span>() {
	
	Connection conn = null;
	Statement st = null;
	ResultSet rs = null;
	try {
		
		
		conn = JdbcUtil.getConnection();
		
		
		st = conn.createStatement();
		String sql = <span class="hljs-string">"select * from student "</span>;
		
		rs = st.executeQuery(sql);
		
		List&lt;Student&gt; list = new ArrayList&lt;Student&gt;();
		<span class="hljs-keyword">while</span> (rs.next()) {
			Student stu = new Student();
			stu.setName(rs.getString(<span class="hljs-string">"name"</span>));
			stu.setAge(rs.getInt(<span class="hljs-string">"age"</span>));
			stu.setId(rs.getInt(<span class="hljs-string">"id"</span>));
			list.add(stu);
		}
		<span class="hljs-built_in">return</span> list;

	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		JdbcUtil.close(conn, st, rs);
	}
	<span class="hljs-built_in">return</span> null;
}

}

复制代码

编写测试类:

package com.meils.jdbc.dao.test;

import java.util.List;

import org.junit.Test;

import com.meils.jdbc.dao.IStudentDao;
import com.meils.jdbc.dao.impl.StudentDaoImpl;
import com.meils.jdbc.domain.Student;

/**
 * StudentDao测试类
 * @author apple
 */
public class StudentDaoTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
	}
	
	@Test
	public void save() {
		Student stu = new Student();
		stu.setName("张伟");
		stu.setAge(21);
		
		IStudentDao dao = new StudentDaoImpl();
		dao.save(stu);
	}
	
	@Test
	public void delete() {
		IStudentDao dao = new StudentDaoImpl();
		dao.delete(4);
	}

	@Test
	public void update () {
		Student stu = new Student();
		stu.setName("mmmmm");
		stu.setAge(16);
		
		IStudentDao dao = new StudentDaoImpl();
		dao.update(5, stu);
	}
	
	@Test
	public void findOne() {
		IStudentDao dao = new StudentDaoImpl();
		Student stu = dao.findOne(5);
		System.out.println(stu);
	}
	
	
	@Test
	public void findAll() {
		IStudentDao dao = new StudentDaoImpl();
		List<Student> allStu = dao.findAll();
		System.out.println(allStu);
	}
	
	
	
	
}

复制代码

JDBC工具类:

package com.meils.jdbc.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

/**
 * JDBC  工具类
 * @author apple
 *
 */
public class JdbcUtil {
	// 配置信息
	public static String driverName = "com.mysql.jdbc.Driver";
	public static String url = "jdbc:mysql://localhost:3306/mytest";
	public static String userName = "root";
	public static String password = "zjj19970517";
	
	static {
		try {
			// 加载驱动,因为是在static块中,所以只会加载一次
			Class.forName(JdbcUtil.driverName);
		}catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 连接数据库
	 * @return 返回连接对象
	 */
	public static Connection getConnection() {
		try {
			return DriverManager.getConnection(JdbcUtil.url, JdbcUtil.userName, JdbcUtil.password);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 关闭连接,并释放资源
	 * @param conn
	 * @param st
	 * @param rs
	 */
	public static void close(Connection conn, Statement st, ResultSet rs) {
		if(conn!=null) {
			try {
				conn.close();
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		
		if(st!=null) {
			try {
				st.close();
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		
		if(rs!=null) {
			try {
				rs.close();
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
	}
}

复制代码

3、DAO代码重构

java JDBC DAO ORM Domain

4、Statement接口

java JDBC DAO ORM Domainjava JDBC DAO ORM Domain
Statement 是父接口,PreparedStatement 和 CallableStatement 是子接口。
Statement 用于java应用程序与数据库之间的传送数据,比如传送sql语句过去,到数据库执行操作。
Statement 用于通用的访问,使用静态sql,其实并不好,容易SQL注入
PreparedStatement 用于预编译模版SQL语句,可以在运行的时候传入参数
CallableStatement 访问存储过程的时候使用复制代码

5、预编译语句

java JDBC DAO ORM Domain

防止SQL注入:

java JDBC DAO ORM Domain

java JDBC DAO封装教程

6、通过DB类来操作数据库

JDBC的另一种封装方法:

package com.meils.jdbc.db;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class MysqlDB {
Connection conn = null; // 创建连接对象
Statement st = null; // 创建编译语句对象
PreparedStatement ps = null; // 创建预编译语句对象
ResultSet rs1 = null;  // 结果集
// 配置信息
// 驱动名称
private static final String driverName = <span class="hljs-string">"com.mysql.jdbc.Driver"</span>;
// 数据库的地址
private static final String URL = <span class="hljs-string">"jdbc:mysql://localhost:3306/mytest"</span>;
// 数据库登录用户名
private static final String userName = <span class="hljs-string">"root"</span>;
// 数据库登录密码
private static final String <span class="hljs-built_in">pwd</span> = <span class="hljs-string">"zjj19970517"</span>;

/**
 * 连接数据库
 * @<span class="hljs-built_in">return</span>
 */
public Connection <span class="hljs-function"><span class="hljs-title">getConnection</span></span>() {
	try {
		Class.forName(driverName);
		
		this.conn = DriverManager.getConnection(URL, userName, <span class="hljs-built_in">pwd</span>);
		System.out.println(<span class="hljs-string">"连接成功"</span>);
		
		<span class="hljs-built_in">return</span> conn;
	} catch (Exception e) {
		e.printStackTrace();
	}
	<span class="hljs-built_in">return</span> null;
}

// 构造函数
public <span class="hljs-function"><span class="hljs-title">MysqlDB</span></span>() {
	this.getConnection();
}

/**
 * 查询
 * @param sql sql语句,完整的语句,查询一般比较安全
 * @<span class="hljs-built_in">return</span>
 */
public ResultSet query(String sql) {
	try {
		this.st = this.conn.createStatement();
		this.rs1 = this.st.executeQuery(sql);
		<span class="hljs-built_in">return</span> rs1;
	} catch (SQLException e) {
		e.printStackTrace();
	} 
	
	<span class="hljs-built_in">return</span> null;
}

/**
 * 更新
 * @param sql  // 预编译sql语句
 * @param args // 参数数组
 */
public void update(String sql, String [] args) {
	try {
		this.ps = this.conn.prepareStatement(sql);
		<span class="hljs-keyword">for</span> (int i = 0 ; i &lt; args.length ; i++) {
			this.ps.setString(i+1, args[i]);
		}
		
		this.ps.executeUpdate();
	} catch (SQLException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	} finally {
		this.close();
	}
	
}

/**
 * 删除
 * @param sql
 * @<span class="hljs-built_in">return</span>
 */
public int delete(String sql){
    try {
        this.st = this.conn.createStatement();
        int num = this.st.executeUpdate(sql);
        <span class="hljs-built_in">return</span> num;
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }  finally {
		this.close();
	}
    <span class="hljs-built_in">return</span> 0;
}

/**
 * 释放资源
 */
public void <span class="hljs-function"><span class="hljs-title">close</span></span> () {
	try {
        <span class="hljs-keyword">if</span>(rs1!=null) {
            rs1.close();
        }
        <span class="hljs-keyword">if</span>(st!=null) {
            st.close();
        }
        <span class="hljs-keyword">if</span>(ps!=null) {
            ps.close();
        }
        <span class="hljs-keyword">if</span>(conn!=null) {
            conn.close();
        }

    } catch (SQLException e) {
        // TODO: handle exception
    	e.printStackTrace();
    }
}

}

复制代码

测试以下:

package com.meils.jdbc.db;

import java.sql.ResultSet;
import java.sql.SQLException;

public class Test {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
//		Conn();
		delete();
	}

	// 测试连接
	public static void Conn() {
		MysqlDB m = new MysqlDB();
	}

	// 测试查询
	public static void queryTest() {
		MysqlDB m = new MysqlDB();
		String sql = "select * from student";
		ResultSet result = m.query(sql);
		System.out.println(result);
		try {
			while (result.next()) {
				System.out.println(result.getString("name"));
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			m.close();
		}
	}
	// 更新
	public static void update() {
		MysqlDB m = new MysqlDB();
		String sql = "update student set name = ? where id = ?";
		String [] args = {"梅子111", "7"};
		
		m.update(sql, args);
	}
	
	// 删除
	public static void delete() {
		MysqlDB m = new MysqlDB();
		String sql = "delete from student  where id = 8";
		System.out.println(m.delete(sql));
	}
	
	
	

}

复制代码

7、调用存储过程

首先我们熟悉一下存储过程

java JDBC DAO ORM Domain
// 新建存储过程
DELIMITER //
create PROCEDURE getStudent1(in n varchar(20))
BEGIN
select * from student <span class="hljs-built_in">where</span> name = n;

END //
DELIMITER ;

// 执行
call getStudent1(‘张锦杰‘);
复制代码

java JDBC DAO ORM Domain
测试一下: (非常尴尬好像并没有结果,也没有报错,不知道是什么原因~~)
package com.meils.jdbc.dao.test;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import com.meils.jdbc.domain.Student;
import com.meils.jdbc.utils.JdbcUtil;

public class ProductTest {

	public static void main(String[] args) {
		CallableStatement cstmt = null;
		try {
			//1.连接
			Connection conn = JdbcUtil.getConnection();
			//2.
			CallableStatement cs = conn.prepareCall("{ call getStu(?)}");
			//3.设置参数
			cs.setString(1, "张锦杰");
			//4.执行
			ResultSet rs = cs.executeQuery();
			if(rs.next()) {
				Student stu = new Student();
				stu.setId(rs.getInt("id"));
				stu.setName(rs.getString("name"));
				stu.setAge(rs.getInt("age"));
				System.out.println(stu);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		

	}

}

复制代码

带有参数和输出的存储过程

// 带有参数和输出的存储过程

DELIMITER //
CREATE PROCEDURE getName ( IN i INT, OUT n VARCHAR ( 50 ) ) BEGIN
	SELECT NAME INTO
		n 
	FROM
		student 
	WHERE
		id = i;

END // DELIMITER;

call getName(1, @name);
select @name;
复制代码
java JDBC DAO ORM Domain

测试一下:

package com.meils.jdbc.dao.test;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import com.meils.jdbc.domain.Student;
import com.meils.jdbc.utils.JdbcUtil;

public class ProductTest {

	public static void main(String[] args) {
		CallableStatement cstmt = null;
		try {
			//1.创建连接
			Connection conn = JdbcUtil.getConnection();
			//2.创建预编译语句
			CallableStatement cs = conn.prepareCall("{ call getName(?,?)}");
			//3.设置参数
			cs.setInt(1, 1);
			//4.设置输出参数
			cs.registerOutParameter(2, Types.VARCHAR);
			//5.执行
			cs.execute();
			
			//6.获取到输出的参数
			String name = cs.getString(2);
			System.out.println(name); // 张锦杰
		} catch (Exception e) {
			e.printStackTrace();
		}
		

	}

}

复制代码

8、事物

java JDBC DAO ORM Domain实例:java JDBC DAO ORM Domain

首先在减少钱之前关闭自动提交事务,期间可以进行多个操作,此时的事务提交必须手动了,需要使用conn.commit();。如果在中间发生了异常,那么就进行回滚,释放资源。

9、批处理

java JDBC DAO ORM Domainjava JDBC DAO ORM Domainjava JDBC DAO ORM Domain

通常情况下如果我们想要一次性执行许多条sql语句,我们都是一条执行完毕再执行下一条,当我们使用了批处理之后,我们就可以一次性执行多条语句,话费的事件将大大缩短。

10、将文件存入数据库

java JDBC DAO ORM Domain

通常我们不会这么做的,因为数据库的空间是非常宝贵的,文件较大,占用的空间也较大,成本也就高了,假如我们需要存文件,那么就要选择blob类型了,它是以二进制的形式来存取的,可以存视频、图片、等多媒体信息。

首先需要设置数据库中的字段类型为blob。
复制代码

存储文件到数据库:

java JDBC DAO ORM Domain

将数据库中的文件取出来:

java JDBC DAO ORM Domain

11、获取自动生成的主键id

需求分析:

我们可能回遇到这样的情景,我们首先注册信息,填入用户明和密码后,注册成功,此时的数据库中的id是自动添加进去的,接下来回让自己去完善自己的信息,这就要需要我们刚才创建的id了,那么如何返回id给我们下次使用呢?

两种方式获取:

1:

java JDBC DAO ORM Domain

2:

java JDBC DAO ORM Domain

相关推荐