- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章java 使用JDBC构建简单的数据访问层实例详解由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本教程的目的是使用Java编写的分离的层去访问数据库中的表,这一层通常称为数据访问层(DAL) 。
使用DAL的最大好处是通过直接使用一些类似insert()和find()的方法简化了数据库的访问操作,而不是总是先做链接,再执行一些查询.
该层在其内部处理所有与数据库相关的调用和查询.
创建数据库 。
我们希望为用户创造一个简单的表,我们可以使用这些字段来创建 。
id int name varchar(200) password varchar(200) age int 。
数据传输对象 。
这一层应该包含一个简单的类叫做数据传输对象(DTO)。这个类仅仅是一个与数据库中的表相对应的简单映射,表中的每一列对应类的一个成员变量.
我们的目的是使用简单的Java对象,而不是处理SQL语句和其他与数据库相关的命令来进行数据库的增删改查.
我们想要把表映射成java代码,只需要创建包含相同字段的类(bean)即可 。
为了更好地封装,除了构造函数我们应该声明所有字段变量为私有,创造访问器(getter和setter),其中有一个是默认的构造函数.
1
2
3
4
5
6
|
public
class
User {
private
Integer id;
private
String name;
private
String pass;
private
Integer age;
}
|
为了正确地映射字段,我们应该考虑数据库中的NULL值。对于Java的原始的默认值,例如int类型,其默认值是0,所以我们应该提供可容纳空值的新的数据类型。我们可以通过使用特殊的类型——封装类,如Integer来代替 INT.
最后我们的类应该像这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
public
class
User {
private
Integer id;
private
String name;
private
String pass;
private
Integer age;
public
User() {
}
public
User(String name, String pass, Integer age) {
this
.name = name;
this
.pass = pass;
this
.age = age;
}
public
User(Integer id, String name, String pass, Integer age) {
this
.id = id;
this
.name = name;
this
.pass = pass;
this
.age = age;
}
public
Integer getAge() {
return
age;
}
public
void
setAge(Integer age) {
this
.age = age;
}
public
Integer getId() {
return
id;
}
public
void
setId(Integer id) {
this
.id = id;
}
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
public
String getPass() {
return
pass;
}
public
void
setPass(String pass) {
this
.pass = pass;
}
}
|
一个好的做法是,提供默认的空构造函数,一个完整的构造函数和一个没有id参数的完整构造函数.
连接数据库 。
我们可以使用一个中间类来方便连接到数据库,在这个类中,我们将提供数据库的连接参数如数据库JDBC, URL,用户名和密码,并将这些变量定义成final的(从properties 或者 xml配置文件中获取这些数据将会更好) 。
提供一个方法返回一个Connection对象或者当连接失败时返回一个null又或者抛出一个运行时异常.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
public
static
final
String URL =
"jdbc:mysql://localhost:3306/testdb"
;
public
static
final
String USER =
"testuser"
;
public
static
final
String PASS =
"testpass"
;
/**
* 获取connection对象
* @return Connection 对象
*/
public
static
Connection getConnection() {
try
{
DriverManager.registerDriver(
new
Driver());
return
DriverManager.getConnection(URL, USER, PASS);
}
catch
(SQLException ex) {
throw
new
RuntimeException(
"Error connecting to the database"
, ex);
}
}
|
我们也可以在类中包含一个主方法来测试连接。完整的类像这样:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
import
com.mysql.jdbc.Driver;
import
java.sql.Connection;
import
java.sql.DriverManager;
import
java.sql.SQLException;
/**
* Connect to Database
* @author hany.said
*/
public
class
ConnectionFactory {
public
static
final
String URL =
"jdbc:mysql://localhost:3306/testdb"
;
public
static
final
String USER =
"testuser"
;
public
static
final
String PASS =
"testpass"
;
/**
* Get a connection to database
* @return Connection object
*/
public
static
Connection getConnection()
{
try
{
DriverManager.registerDriver(
new
Driver());
return
DriverManager.getConnection(URL, USER, PASS);
}
catch
(SQLException ex) {
throw
new
RuntimeException(
"Error connecting to the database"
, ex);
}
}
/**
* Test Connection
*/
public
static
void
main(String[] args) {
Connection connection = connectionFactory.getConnection();
}
}
|
数据访问对象 。
DAO层可以做CRUD操作。它可以对我们的表进行增删改查.
我们的DAO层接口应该像这样:
1
2
3
4
5
6
7
8
|
public
interface UserDao {
User getUser();
Set<User> getAllUsers();
User getUserByUserNameAndPassword();
boolean insertUser();
boolean updateUser();
boolean deleteUser();
}
|
查找用户 。
用户可以通过像ID,姓名或邮箱等任何唯一字段来查询。在这个例子中,我们使用ID来查找用户。第一步是通过连接器类来创建一个connection,然后执行SELECT语句以获得其ID为7的用户,我们可以使用这条语句查询用户:
SELECT * FROM user WHERE id=7 。
就在这里,我们做了一个动态的语句来从参数中获取ID.
通过执行这个查询,得到一个结果集,其中保存有用户或null。我们可以通过Resultset的next()方法来检测是否有值。如果返回true,我们将继续利用data getters从ResultSet中获取用户数据。当我们将所有的数据封装到user中后,我们返回它。如果不存在此ID的用户或其他任何异常发生(如无效的SQL语句)这个方法会返回null.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
User getUser(
int
id) {
Connection connection = connectionFactory.getConnection();
try
{
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT * FROM user WHERE id="
+ id);
if
(rs.next())
{
User user =
new
User();
user.setId( rs.getInt(
"id"
) );
user.setName( rs.getString(
"name"
) );
user.setPass( rs.getString(
"pass"
) );
user.setAge( rs.getInt(
"age"
) );
return
user;
}
}
catch
(SQLException ex) {
ex.printStackTrace();
}
return
null
;
}
|
使用单独的方法来从结果集中提取数据将会更方便,因为在很多方法中我们将会调用它.
这个新方法将抛出SQLException并且为了限制只能在类内部使用,其应该是私有的:
1
2
3
4
5
6
7
8
|
private
User extractUserFromResultSet(ResultSet rs)
throws
SQLException {
User user =
new
User();
user.setId( rs.getInt(
"id"
) );
user.setName( rs.getString(
"name"
) );
user.setPass( rs.getString(
"pass"
) );
user.setAge( rs.getInt(
"age"
) );
return
user;
}
|
我们上面的方法应该修改成新的方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public
User getUser(
int
id) {
Connection connection = connectionFactory.getConnection();
try
{
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT * FROM user WHERE id="
+ id);
if
(rs.next())
{
return
extractUserFromResultSet(rs);
}
}
catch
(SQLException ex) {
ex.printStackTrace();
}
return
null
;
}
|
登陆方法 。
登陆操作类似。我们希望提供用户和密码替代ID,这将不会影响参数列表和查询语句。如果用户名和密码是正确的,这个方法会返回一个有效的用户,否则为null。因为有很多的参数,使用PreparedStatement将更有用.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
public
User getUserByUserNameAndPassword(String user, String pass) {
Connector connector =
new
Connector();
Connection connection = connector.getConnection();
try
{
PreparedStatement ps = connection.prepareStatement(
"SELECT * FROM user WHERE user=? AND pass=?"
);
ps.setString(
1
, user);
ps.setString(
2
, pass);
ResultSet rs = ps.executeQuery();
if
(rs.next())
{
return
extractUserFromResultSet(rs);
}
}
catch
(SQLException ex) {
ex.printStackTrace();
}
return
null
;
}
|
查询所有用户的方法 。
这个方法将会返回所有的用户,所以我们应该将它们存在一个类似数组的容器中返回来。但是,因为我们不知道有多少条记录。 使用例如Set或者List的集合将会更好:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
Set getAllUsers() {
Connector connector =
new
Connector();
Connection connection = connector.getConnection();
try
{
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(
"SELECT * FROM user"
);
Set users =
new
HashSet();
while
(rs.next())
{
User user = extractUserFromResultSet(rs);
users.add(user);
}
return
users;
}
catch
(SQLException ex) {
ex.printStackTrace();
}
return
null
;
}
|
插入方法 。
Insert方法将采取用户作为参数,并使用PreparedStatement对象来执行SQL update语句。executeUpdate 方法返回受影响的行数。如果我们添加单行,意味着该方法应该返回1,如果是这样,我们返回true,否则,我们返回false 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public
boolean
insertUser(User user) {
Connector connector =
new
Connector();
Connection connection = connector.getConnection();
try
{
PreparedStatement ps = connection.prepareStatement(
"INSERT INTO user VALUES (NULL, ?, ?, ?)"
);
ps.setString(
1
, user.getName());
ps.setString(
2
, user.getPass());
ps.setInt(
3
, user.getAge());
int
i = ps.executeUpdate();
if
(i ==
1
) {
return
true
;
}
}
catch
(SQLException ex) {
ex.printStackTrace();
}
return
false
;
}
|
更新方法 。
更新方法和插入方法类似。唯一变化的是SQL语句 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
boolean
updateUser(User user) {
Connector connector =
new
Connector();
Connection connection = connector.getConnection();
try
{
PreparedStatement ps = connection.prepareStatement(
"UPDATE user SET name=?, pass=?, age=? WHERE id=?"
);
ps.setString(
1
, user.getName());
ps.setString(
2
, user.getPass());
ps.setInt(
3
, user.getAge());
ps.setInt(
4
, user.getId());
int
i = ps.executeUpdate();
if
(i ==
1
) {
return
true
;
}
}
catch
(SQLException ex) {
ex.printStackTrace();
}
return
false
;
}
|
删除方法 。
删除的方法是使用一个简单的查询像 。
DELETE FROM user WHERE ID = 7 。
带上id参数发送该查询将删除此记录。如果成功删除将返回1 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
public
boolean
deleteUser(
int
id) {
Connector connector =
new
Connector();
Connection connection = connector.getConnection();
try
{
Statement stmt = connection.createStatement();
int
i = stmt.executeUpdate(
"DELETE FROM user WHERE id="
+ id);
if
(i ==
1
) {
return
true
;
}
}
catch
(SQLException ex) {
ex.printStackTrace();
}
return
false
;
}
|
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持! 。
最后此篇关于java 使用JDBC构建简单的数据访问层实例详解的文章就讲到这里了,如果你想了解更多关于java 使用JDBC构建简单的数据访问层实例详解的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在努力实现以下目标, 假设我有字符串: ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ( z ) ( A ) ) ) ) ) 我想编写一个正则
给定: 1 2 3 4 5 6
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
大家好,我卡颂。 Svelte问世很久了,一直想写一篇好懂的原理分析文章,拖了这么久终于写了。 本文会围绕一张流程图和两个Demo讲解,正确的食用方式是用电脑打开本文,跟着流程图、Demo一
身份证为15位或者18位,15位的全为数字,18位的前17位为数字,最后一位为数字或者大写字母”X“。 与之匹配的正则表达式: ?
我们先来最简单的,网页的登录窗口; 不过开始之前,大家先下载jquery的插件 本人习惯用了vs2008来做网页了,先添加一个空白页 这是最简单的的做法。。。先在body里面插入 <
1、MySQL自带的压力测试工具 Mysqlslap mysqlslap是mysql自带的基准测试工具,该工具查询数据,语法简单,灵活容易使用.该工具可以模拟多个客户端同时并发的向服务器发出
前言 今天大姚给大家分享一款.NET开源(MIT License)、免费、简单、实用的数据库文档(字典)生成工具,该工具支持CHM、Word、Excel、PDF、Html、XML、Markdown等
Go语言语法类似于C语言,因此熟悉C语言及其派生语言( C++、 C#、Objective-C 等)的人都会迅速熟悉这门语言。 C语言的有些语法会让代码可读性降低甚至发生歧义。Go语言在C语言的
我正在使用快速将 mkv 转换为 mp4 ffmpeg 命令 ffmpeg -i test.mkv -vcodec copy -acodec copy new.mp4 但不适用于任何 mkv 文件,当
我想计算我的工作簿中的工作表数量,然后从总数中减去特定的工作表。我错过了什么?这给了我一个对象错误: wsCount = ThisWorkbook.Sheets.Count - ThisWorkboo
我有一个 perl 文件,用于查看文件夹中是否存在 ini。如果是,它会从中读取,如果不是,它会根据我为它制作的模板创建一个。 我在 ini 部分使用 Config::Simple。 我的问题是,如果
尝试让一个 ViewController 通过标准 Cocoa 通知与另一个 ViewController 进行通信。 编写了一个简单的测试用例。在我最初的 VC 中,我将以下内容添加到 viewDi
我正在绘制高程剖面图,显示沿路径的高程增益/损失,类似于下面的: Sample Elevation Profile with hand-placed labels http://img38.image
嗨,所以我需要做的是最终让 regStart 和 regPage 根据点击事件交替可见性,我不太担心编写 JavaScript 函数,但我根本无法让我的 regPage 首先隐藏。这是我的代码。请简单
我有一个非常简单的程序来测量一个函数花费了多少时间。 #include #include #include struct Foo { void addSample(uint64_t s)
我需要为 JavaScript 制作简单的 C# BitConverter。我做了一个简单的BitConverter class BitConverter{ constructor(){} GetBy
已关闭。这个问题是 not reproducible or was caused by typos 。目前不接受答案。 这个问题是由拼写错误或无法再重现的问题引起的。虽然类似的问题可能是 on-top
我是 Simple.Data 的新手。但我很难找到如何进行“分组依据”。 我想要的是非常基本的。 表格看起来像: +________+ | cards | +________+ | id |
我现在正在开发一个 JS UDF,它看起来遵循编码。 通常情况下,由于循环计数为 2,Alert Msg 会出现两次。我想要的是即使循环计数为 3,Alert Msg 也只会出现一次。任何想法都
我是一名优秀的程序员,十分优秀!