1.ORM简介
对象关系映射(Object Relationship Mapping),在我理解看来就是把数据库内的关系数据转变为便于程序操作的类的对象的一种机制。它将从数据库中取出的离散的数据通过类的方式重新组织在一起维持了其原有的关系。
2.ORM实例
抽象的东西多说无益,直接上例子:假设在数据库中有一张student表,表中有三个属性sno、sname、sage分别对应学生的学号、姓名、年龄,在数据库中对应的信息是以数据项的形式存在,三条对应的数据项构成一条学生记录,所有的学生记录构成一张student表,而在程序中信息是以对象及其内部的数据成员的方式存在。在这里其映射关系是:一张表对应一个类,其中的一条记录对应一个实例对象,每一条记录中的数据项对应各个对象中的数据成员。
关系表 → 类 |
记录 → 对象 |
数据项 → 数据成员 |
这样的对应关系就是具体的映象方式,而我们要做的就是实现这个映象。
首先我们在数据库中建立student表,并存入相应数据:
create table student(sno char(10),sname char(10),sage int);
insert into student values('001','子鼠',18);
insert into student values('002','丑牛',19);
insert into student values('003','寅虎',17);
insert into student values('004','卯兔',18);
insert into student values('005','辰龙',20);
首先,我们可以建立一个SQLOperator类,将所有的数据库操作封装为类的方法,屏蔽数据库操作以及SQL语句,以便将用户从数据库操作中解放出来,专注业务逻辑处理。SQLOperator包含两个数据成员,Connection用于获取数据库连接,以及PreparedStatement用于存放sql语句(也可以使用Statement,区别为前者为预编译语句,在数据库编译运行时效率较高)。
SQLOperator类框架
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class SQLOperator {
Connection connection;
PreparedStatement statement;
//获取数据库连接
public SQLOperator(Connection c) {
this.connection = c;
try {
//关闭自动提交,手动提交以确保事务的完整性
c.setAutoCommit(false);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
编写Student类用于存放从数据库中读出的记录
class Student{
public String num;
public String name;
public int age;
public Student(String num,String name,int age) {
this.num = num;
this.name = name;
this.age = age;
}
}
1、完成SQLOperator的构造方法,连接数据库,数据库连接可参考https://blog.youkuaiyun.com/qq_42332204/article/details/95235339
//获取数据库连接
public SQLOperator(Connection c) {
this.connection = c;
try {
//关闭自动提交,手动提交以确保事务的完整性
c.setAutoCommit(false);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
2、get()方法,传入学生学号作为参数,用于获取数据库中学生记录。将sql语句传入数据库后返回一个查询结果集,存放在ResultSet中,依次遍历结果集内的数据将对应的数据内容返回给Student对象的各个成员,完成关系映射。由于sql语句封装在get()方法内部,对用户不可见,因此用户无需关注数据库操作,仅获取到Student对象即可。
//获取学生,依照学生的学号获取学生对象
public Student get(String num) {
int age = 0;
Student s = null;
String name = null;
String sql = "select * from student where sno=?";
//try-with-resource可自动关闭statement
try (PreparedStatement statement = connection.prepareStatement(sql);) {
statement.setString(1, num);
ResultSet rs = statement.executeQuery();
//当找到学生时返回学生,否则返回null
if(rs.next()) {
name = rs.getString("sname");
age = rs.getInt("sage");
s = new Student(num,name,age);
}else {
System.err.println("NotFoundStudent");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return s;
}
3、对数据库的增加,删除,修改操作。这几个操作较为类似,通过执行传入的sql语句,实现对数据库的操作。其中Statement语句中的“?”代表一个可变的参数,通过调用setString()等方法可以修改对应的"?"代表的值,方法中第一个参数代表语句中第n个“?”表示的参数,第二个参数为其值;传参后调用execute()方法执行语句,最后commit()提交事务。
//插入,传入一个student对象,将对象转换为一条记录插入到数据库中
public void add(Student s) {
String sql = "insert into student values(?,?,?)";
try (PreparedStatement statement = connection.prepareStatement(sql);) {
statement.setString(1, s.num);
statement.setString(2, s.name);
statement.setInt(3, s.age);
statement.execute();
connection.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//修改,依照student的学号作为key,找到并修改该学生的其他属性
public void update(Student s) {
String sql = "update student set sname=? , sage=? where sno =?";
try (PreparedStatement statement = connection.prepareStatement(sql);) {
statement.setString(1, s.name);
statement.setInt(2, s.age);
statement.setString(3, s.num);
statement.execute();
connection.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//删除,依照学生学号删除数据库内对应记录
public void delete(Student s) {
String sql = "delete from student where sno=?";
try (PreparedStatement statement = connection.prepareStatement(sql);) {
statement.setString(1, s.num);
statement.execute();
connection.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
4、归还或关闭数据库连接。由于同一时刻与数据库建立的连接是有限的,因此数据库连接是一个有限资源,当完成数据库操作以后需要归还或关闭数据库连接以便其余用户对数据库进行连接操作。
//数据库操作完成后返回数据库连接
public Connection returnConnection() {
return connection;
}
//关闭数据库连接
public void closeConnection() {
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
以上是一些常用的数据库操作,通过类似的方式可以将对数据库的操作封装起来,方便用户使用。最后总结一下,ORM实质是一种将数据库记录转化为类的方式,通过实现由数据库的表到类的关系映射,便于对数据进行高效的处理,并且使数据库便于开发者使用。此处的代码仅作参考,一些细节和健壮性问题尚未考虑的特别周全,读者可以自行进行完善和加强。