Persistence & DataBases - bukkit tutorial

Discussion in 'Resources' started by Sammy, Apr 10, 2011.

Thread Status:
Not open for further replies.
  1. Offline

    Sammy

    Please help me maintain my test server:​
    [cake] [​IMG] [cake]

    With the help of Mixcoalt I manage to understand how the new persistence class works..
    I was going to make a writen tutorial but persistence has some little things that are easier understood with a video :)

    I'm not a great English speaker so forgive all my verbal errors ^^

    Video:





    PasteBin Src:
    plugin.yml
    Main file
    Persistence class
    Commands

    Fell free to bash and troll me ^^
    Questions and welcome too !!!

    EDIT:
    If you want to know more about datatypes on Ebean this is the best place to have a look:
    Ebean manydatatypes
     
  2. Offline

    MrChick

    Thanks for the tutorial. But is it just me or is the volume really really really low? Got everything on max volume and still almost can't hear you.
     
  3. Offline

    Sammy

    @MrChick you are right I'm going to re-upload the video tks ! DONE
     
  4. Offline

    phondeux

    Your demo is terrific, but how do you connect to a MySQL database? I assume everything after that such as table setup, etc,, is just the same?
    Could you post the contents of your bukkit.yml from the example?

    Also, how do you make an auto-incrementing not null index for a table?

    Rather than edit my last post ... the bukkit.yml for using MySQL would look like this, right?
    Code:
    database:
       username: bukkit
       isolation: SERIALIZABLE
       driver: com.mysql.jdbc.Driver
       password: walrus
       url: jdbc:mysql://localhost/minecraft
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 13, 2016
  5. Offline

    Sammy

    Well, it depends, somethings aren't that well implemented on Ebean... for example hashmaps are horrible to configure, I'm going to add to my post the info about that, I forgot =X
     
  6. Offline

    phondeux

    I did some research and the answer seems to be, "You don't use ebean for it, you use the database specific tools." So, run the plugin once to setup the tables and then run an sql statement or two to set it up. Someone correct me if I'm wrong please. :)
     
  7. Offline

    Sammy

    Yes, and no ^^
    You use javax persistence annotations to create tables and columns on a database, I'm learning more about that, I might make another tutorial next week.
     
  8. Offline

    matejdro

    I'm checking out this now and i will probably have a lot of questions, so excuse me please.

    1. How can i update database structure? So what do i do, when i add new variable to the class?
     
  9. Offline

    Sammy

    Well when do make a new variable you just need to put the setter and getter and at least delete the database table so it'll great a new one...
    NetBeans and Eclipse have a database handling part, you just need to connect to your db and delete the table
    Setters and getters can be automatically add if you use the "insert getters and setters" command on NetBeans/Eclipse
     
  10. Offline

    matejdro

    Yes but what if i want to keep the existing data? Let's say I'm adding new feature to the plugin, but i want users to keep their existing stuff.
     
  11. Offline

    Kevin Forte

    I watched this video, but I am still very lost as to how to tie this into my already existing plugin.
     
    ShadowDrakken likes this.
  12. Offline

    Sammy

    @Kevin Forte
    Well I explained the best I could, and you are the 1st on still lost after, try watching it again, if you still have questions just ask here :)

    @matejdro

    Well I'm trying to add a column, I know how to do it in sql it's:
    Code:
    ALTER TABLE MyTable ADD COLUMN NewColumn
    The problem is that I don't know how to call this query on Ebean I already tried using this "onEnable":
    Code:
            String dml = "ALTER TABLE MyTable ADD COLUMN NewColumn";
            SqlUpdate update = getDatabase().createSqlUpdate(dml);
            int rows = update.execute();
    The problem is that "ALTER TABLE" is not a SqlUpdate query... i tried using other ebean query's but none worked
     
  13. Offline

    Kevin Forte

    I've watched it three times xD I'm positive it's my fault and not yours, but if I post my source file(s) and a general idea of what I'm trying to do here, do you think you can shed some light on stuff?
     
  14. Offline

    matejdro

    @Sammy I hope that we can find a solution. I'm looking for dynamic perisistence framework that would not have troubles with updating structure of the database, so i can easily make updates.

    Well still, i can add automated backup, deletion of the DB and then restore the backup.
     
  15. Offline

    Sammy

    Of course, but use pastebin please =)

    @matejdro Well there's almost no documentation about Ebean so it's a bit hard... if you find it first please shout ^^
     
  16. Offline

    Kevin Forte

    http://www.pastie.org/1798546 - The only class
    http://www.pastie.org/1798540 - plugin.yml

    In the class file, on lines 119 - 137, I have a blank space where I was stumped. I want a user to be able to type /skill [arg] [arg], where the first arg is the name of the skill and the second is its modifier. Then, I want the user to be able to type /rollskill [arg] where the arg is the name of the skill. I want the plugin to be able to then roll for that skill's modifier, as defined with /skill. A lot of users would have the same skills though name-wise, such as Search or Spot.
     
  17. Offline

    Wolfwood

    I don't see what this has to do with persistence & database topic of this thread and have no clue how the video could help you with your problem.

    In your plugin.yml you need /<command> after the usage for onCommand to be able to register it with CB.
    Code:
    commands:
      roll:
        description: Returns a random integer from 1 to the integer defined in the argument.
        usage: /<command>
    other than that 119-137 are block commented out in the pastbin you posted so the code wouldn't be compiled.
     
  18. Offline

    Sammy

    @Kevin Forte I don't understand your question, you want do implement a database to what ?
     
  19. Offline

    Kevin Forte

    I know it's commented out, I did that because that portion of the plugin isn't done yet and I don't want it conflicting with the rest.

    I want a user to be able to type like '/skill spot 5', that way the skill 'spot' now has a modifier of 5. Now, whenever they type '/rollskill spot', that 5 will be added onto whatever they roll. I want the modifiers they set to be persistent, and I want each player to be able to have their own set of skills, so playerA might have their 'spot' skill set to 5 and playerB might have theirs set to 7. When playerA uses '/rollskill spot', 5 will be added to the result of the roll. When playerB uses '/rollskill spot', 7 will be added. I'd also need multiple skills, so a player could have values set for 'spot', 'search', 'openlock', etc. Does that make any more sense? I'm trying to explain best I can )x Basically, if any of you have played D&D, I want people to be able to punch their skills in and just roll for that skill as opposed to having to find the modifier and add it manually every single time.
     
  20. Offline

    Sammy

    Well that's not really a question, it's making you all the code...
    The idea is, you make a new class, and there you place all the variables you want to persist (save to the data base)
     
  21. Offline

    Kevin Forte

    Well I did figure it out via help on bukkitdev, and I guess the question was a request for help in doing so, I didn't really want you to write all of the code xP
     
  22. Offline

    phondeux

    Please correct me if I'm wrong; so the way you use persistance is you create a class which is basically a representation of a table. In the class you create get and set methods to update table column data.

    Or does the class represent just a row in a table? I don't quite get it. :(
     
  23. Offline

    Sammy

    That's exactly it
    Your @id is the id of each row, the playername is the search variable for each row
     
  24. Offline

    oliverw92

    I don't think you need the ebean property file anymore. For my persistent plugin all i needed was the bukkit.yml configured correctly. Also in the tutorial it sounded like you meant that you HAVE to have a name and playerName property for the table, which is not the case. Wasn't quite sure what you meant until i started playing.

    Thanks for the tutorial - it solved all my issues :D Didn't realise you had to have database: true in plugin.yml!
     
  25. Offline

    Daniel Heppner

    I need help creating the persistence class, the rest seems easy enough.
    Specifically the annotations.

    Can you persist things like Location and Player or does it have to be numbers and strings?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 13, 2016
  26. Offline

    Mixcoatl

    It's actually pretty easy. If you post the class in a "code" block I can help you annotate it.
    You cannot directly persist Bukkit classes, perhaps with a few exceptions. You need to create classes that represent the data you want to persist. Your persistent entity classes may contain primitive types (int, double, boolean), wrapper types (Integer, Double, Boolean), strings, and references to other persistent entity classes.
     
  27. Offline

    Sammy

    Well you don't need to use them both, but if you want multiple records of the same name you need to use two entries or you won't find a single row.
    For example, more than one spawnpoint per player
     
  28. Offline

    oliverw92

    Fair point :)
     
  29. Offline

    oliverw92

    Have you had to chance to test Persistence on the newer bukkit builds? I'm having a problem with my multiple-home plugin, particularly the setting part. If a user has not had a home set yet in the world they are in, they can set their home with /home set fine, and then go to it using /home. However if the user alread has a home set in that world, then tries to /home set, it says it has set it and gives no errors, yet it does not update the location. Here is the section of my code that does the setting part:

    Code:
    //Setting home
                    if (command.equalsIgnoreCase("set")) {
                        Home home = getDatabase().find(Home.class).where().ieq("world", world.getName()).ieq("player", player.getName()).findUnique();
    
                        if (home == null) {
                            home = new Home();
                            home.setPlayer(player.getName());
                        }
    
                        home.setLocation(player.getLocation());
                        getDatabase().save(home);
                        sendMessage(player, "`aYour home has been set in world `f" + world.getName());
                    }
    And here is my Home persisted class:

    Home.class (open)

    Code:
    package uk.co.oliwali.MultiHome;
    
    import com.avaje.ebean.validation.NotNull;
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Location;
    import org.bukkit.World;
    
    @Entity()
    @Table(name="multihome")
    public class Home {
    
        @Id
        private int id;
        @NotNull
        private String player;
        @NotNull
        private String world;
        @NotNull
        private double x;
        @NotNull
        private double y;
        @NotNull
        private double z;
        @NotNull
        private float pitch;
        @NotNull
        private float yaw;
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getPlayer() {
            return player;
        }
    
        public void setPlayer(String player) {
            this.player = player;
        }
    
        public String getWorld() {
            return world;
        }
    
        public void setWorld(String world) {
            this.world = world;
        }
    
        public double getX() {
            return x;
        }
    
        public void setX(double x) {
            this.x = x;
        }
    
        public double getY() {
            return y;
        }
    
        public void setY(double y) {
            this.y = y;
        }
    
        public double getZ() {
            return z;
        }
    
        public void setZ(double z) {
            this.z = z;
        }
    
        public float getYaw() {
            return yaw;
        }
    
        public void setYaw(float yaw) {
            this.yaw = yaw;
        }
    
        public float getPitch() {
            return pitch;
        }
    
        public void setPitch(float pitch) {
            this.pitch = pitch;
        }
    
        public void setLocation(Location location) {
            this.world = location.getWorld().getName();
            this.x = location.getX();
            this.y = location.getY();
            this.z = location.getZ();
            this.pitch = location.getPitch();
            this.yaw = location.getYaw();
        }
    
        public Location getLocation() {
            World world = Bukkit.getServer().getWorld(this.world);
            return new Location(world, x, y, z, yaw, pitch);
        }
    
    }
     
  30. Offline

    Mixcoatl

    Looks like you're not setting the world in your home == null block.
     
Thread Status:
Not open for further replies.

Share This Page