I think you are confusing two different resources here; you may indeed want an open thread (effectively a process) for each player logged on, but this doesn't mean you should have a connection to the database open for each player constantly, as things like database connections, file handles etc are not managed resources and should be freed up as soon as you are finished with them.
There's a good introduction and explanation of C# threading here.
You should only open a connection to the database when you need it. This means your data access classes could be instantiated many times (this is the simplest design) each with their own connection. If you use connection pooling, which I feel you actually might have been asking about, then you'll benefit further. Moving towards a static database connection design (where many people share the same dao classes) can be much more problematic as you may have to synchronize certain resources, ensure certain variables can only be accessed in sequence via locking or similar, and more.
You can read more about this here for example. Microsoft also talk about the benefits of connection pooling here.
The code you have above is a good starting point for connecting to the database, by including the using statement you are closing and disposing of the connection as soon as you are finished with it; you might also consider the following improvements:
using(var conn = new MySqlConnection(DatabaseHelper.getConnectionString()))
{
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandType = CommandType.Text;
//Parameterize your queries!
cmd.CommandText = "SELECT username FROM characters WHERE id=?"; //Use ? as placeholder for parameters, and add parameters in the order they appear in your query.
cmd.Parameters.Add(new MySqlParameter("@userid", MySqlDbType.Int, userid));
using(IDataReader reader = cmd.ExecuteReader())
{
//You should only expect one record. You might want to test for more than 1 record.
if (reader.Read())
{
user = reader.GetString(reader.GetOrdinal("username")); //Think also about null value checking.
}
}
}
}
You might have a DAO class, or a method on a user class to do this. For example, if it was a method on user, you might do something like:
User myUser = new User(7);
myUser.Load();
Inside of Load, one of the methods you might call is PopulateFromDB() which would contain the code above, and would load all of the properties of this user. You might also have a DAO class that does the same thing:
UserLoader loader = new UserLoader();
string userName = loader.GetUserName(int userId);
which would return the username using the code in the example above. I'd prefer this method to be on a class like User as it's logically connected to it. However, you then run the risk of mixing the DAO logic with the user business logic, which is a topic all on it's own.
Rather than write a lot of this data access logic, you might consider looking at some form of framework like an ORM or similar - this question has already been answered for MySql on SO. This could also save you a lot of time and effort, and will allow you to concentrate on design.