- 当服务器意外终止时,数据会丢失。
- 大量读写Yaml文件,效率低下
- 不利于批量读入,数据载入到内存中又会浪费过多内存资源。
下面请跟随源码认识和使用Ebean数据库。
Bukkit为我们准备了一个例子,我将围绕这个例子进行讲解。
这是一个“多个家”的插件,使用Ebean作为数据库。
例子源码:https://github.com/Bukkit/HomeBukkit
1.数据实体类
- @Entity()
- @Table(name="hb_home")
- public class Home {
- @Id
- private int id;
- @NotNull
- private String playerName;
- @Length(max=30)
- @NotEmpty
- private String name;
- @NotNull
- private double x;
- @NotNull
- private double y;
- @NotNull
- private double z;
- @NotNull
- private float pitch;
- @NotNull
- private float yaw;
- @NotEmpty
- private String worldName;
每个数据实体类的结构都是一张库表。
每个数据实体类的成员属性就是这张库表的字段。
你要注意的是,这里只允许使用Java的基础属性。
简单介绍一下这个类中的各个注解。
@Entity,注解在数据实体类上。代表这是一个数据实体。
@Table,注解在数据实体类上,参数name确定数据表名。
@Id,数据ID的注解
@Length,标记数据的长度
@NotEmpty,不允许为空
@NotNull,不允许为Null
(更多注解请翻阅Ebean的API,这里只做简单介绍)
同时,你要为你的数据实体类写好所有Getter/Setter。(可以用IDE的快捷输入)
2.注册数据类
在JavaPlugin中向Ebean注册你的数据实体类,以期让其工作。
- @Override
- public List<Class<?>> getDatabaseClasses() {
- List<Class<?>> list = new ArrayList<Class<?>>();
- list.add(Home.class);
- return list;
3.创建数据库
当你的插件第一次运行的时候,数据库/表都是不存在的,那么你需要创建。
需要手动创建吗?不,JavaPlugin封装好了,你只需要检查一下是否需要创建。
- private void setupDatabase() {
- try {
- getDatabase().find(Home.class).findRowCount();
- } catch (PersistenceException ex) {
- System.out.println("Installing database for " + getDescription().getName() + " due to first time usage");
- installDDL();
- }
- }
这个方法将会尝试读取某个数据实体类的所有数量,当出现PersistenceException异常的时候,创建这个数据表。
而创建方法,就是调用已经封装好的installDDL();
4.操作数据库
对数据库的基础操作分为:增、删、查、改。
4.1 增
其中,增加一条数据记录,就是实例化一个数据实体类,然后将其save在数据库内。
- home = new Home();
- home.setPlayer(player);
- home.setName(name);
- home.setLocation(((Player)sender).getLocation());
- <span style="line-height: 19.0909px;">plugin.getDatabase().save(home);</span>
4.2 删
删除之前先获取这条数据的实体类。
- // 获取数据实体类
查询,读取,这一步比较复杂。
查询单个记录:
- Home home = plugin.getDatabase().find(Home.class).where().ieq("name", name).ieq("playerName", player.getName()).findUnique();
where(),判断
ieq("name", name),是否相等,判断name这个字段中哪条记录和变量name相等。
ieq("playerName",player.getName()),是否相等,判断playerName这个字段中哪条记录和玩家的名字相等。
findUnique(); 返回一个独一无二的记录。
查询一组记录:
- List<Home> homes = plugin.getDatabase().find(Home.class).where().ieq("playerName", player.getName()).findList();
这里只有一个 ieq("playerName",player.getName()) ,意思是取所有玩家名相对应的记录。
最关键的是findList(),他返回一组记录,所有符合要求的记录都会被实例化为数据实体类,然后返回。
返回值是List<?>
更多的查询需要你自己前往Ebean的API中查询,诸如更复杂的查询条件,排序查询等等。
4.4 改
所谓改,就是对数据的一种刷新。
- // 获取数据实体类
- Home home;
5.配置
最后一步,不要忘记在你的插件配置文件中打开database这个选项,以激活Ebean数据库!
- # Plugin.yml 插件文件
6.瑕疵
目前还没发现怎么让Ebean支持MySQL(只支持Sqlite),如果各位大佬有研究成果,欢迎分享。
让Ebean支持MySQL,请参考我的第二篇文章:[教程]认识Ebean数据库(二)
http://www.mcbbs.net/forum.php?mod=viewthread&tid=636860
(出处: http://www.mcbbs.net/)
使用了Ebean之后,如果你在测试服务器中测试Ebean插件,并修改代码后覆盖正在运行的Ebean插件,然后使用Reload指令重载服务器端,会造成这个Ebean插件无法工作
(至于原因,应该是反射机制的问题。你只能重启服务器端来解决这个问题)
7.结语
使用Ebean可以大大加快你的插件开发进度,完善你的插件数据库。
ORM框架除了给你提供强大快捷的对象映射之外,还自带反SQL注入,确保了数据安全。
对于新手插件开发者、甚至熟练插件开发者,Ebean作为Bukkit原生支持的ORM框架,都是值得使用的。
希望这篇文章能帮助为各位插件开发者了解和学习Ebena。
祝愿各位国内的插件开发者能开发出更强大、更完善的插件。
来自:神坑插件开发小组
