One method I've used when rotations get confusing is to make a unit cube and place it at the axis of rotation I'd like. Then link whatever you're working on to this unit cube such that the cube is the root prim. Now if the center of rotation of this cube is the same as your object, great, you can rotate it directly in the editor, starting from 0,0,0 angles from all sides since the unit cube is your "rotation control" now. When you're done you can unlink it and delete the cube.
However, often you want to rotate an object around an arbitrary point, or rotate multiple objects together around an arbitrary point, and this is where a little scripting comes in because it doesn't seem like you can rotate around a root prim in the editor. (The rotation instead takes place around the center of the linkset bounding box)
Link your object(s) to the unit cube, and then stick this script in the cube, which should again be the root prim:
default
{
state_entry()
{
llSetRot(llEuler2Rot(<45.0,0.0,0.0>*DEG_TO_RAD));
}
}
You don't have to know scripting to use this; just substitute your desired rotational values between the brackets. <X,Y,Z>. This well set *absolute* rotation, like you entered the values into the editor. If you want relative rotation,
default
{
state_entry()
{
llSetRot(llEuler2Rot(<45.0,0.0,0.0>*DEG_TO_RAD) * llGetRot());
}
}
Of course if you just have one object and want to do a relative rotation on it, you can just drop this script in that object by itself. Hope some of this makes sense

Now every time you reset the script, it will rotate 45 degrees on the X axis. To keep from getting a headache, try to rotate on one axis at a time.