I'm a beginner PHP developer and it's my first time using MySQLi. I'm not sure if this is a correct implementation of the connection and query because some people defend this method and some others not. I need a solid implementation for heavy database usage.
Connection:
class bbddConnection {
private $_host = 'localhost';
private $_username = 'username';
private $_password = 'password';
private $_db_name = 'DBNAME';
private $_mysqli = NULL;
private static $_instance = NULL;
private function __construct() {
    $this->connection();
}
public static function get_instance() {
    if (!isset(self::$_instance)) {
        //echo "Creating new instance.\n";
        $class_name = __CLASS__;
        self::$_instance = new $class_name;
    }
    return self::$_instance;
}
private function connection() {
    //echo "Creating new connection.\n";
    try {
        //The mysqli object will be created once and only once
        if (!$this->_mysqli instanceof mysqli) {
            $this->_mysqli = new mysqli($this->_host, $this->_username, $this->_password);
        }
        if ($this->_mysqli->connect_errno) {
            throw new Exception('An error occured: ' . $this->_mysqli->connect_error);
        } else {
            $this->select_db();
        }
    } catch (Exception $e) {
        echo $e->getMessage() . "\n";
    }
}
private function select_db() {
    //echo "Selecting database.\n";
    try {
        $this->_mysqli->select_db($this->_db_name) or die('Could not find database');
    } catch (Exception $e) {
        echo $e->getMessage() . "\n";
    }
}
public function query($query) {
    if (!isset($query))
        return;
    //echo "Prevent SQL Injection. \n"
    $query = $this->_mysqli->real_escape_string($query);
    return $this->_mysqli->query($query);
}
public function stmt_init() {
    return $this->_mysqli->stmt_init();
}
public function __destruct() {
    if ($this->_mysqli instanceof mysqli) {
        $this->_mysqli->close();
    }
}
 private function __clone() {
    trigger_error('Clone is not allowed.', E_USER_ERROR);
}
  private function __wakeup() {
    trigger_error('Unserializing is not allowed.', E_USER_ERROR);
}
}
Query:
class gestorUsuarios {
private $db;
public function __construct() {
    $this->db = bbddConnection::get_instance();
}
/**
 * Returns the Name of the user according his ID
 * @param int id
 * @return string Nombre, if an error occurred.
 * returns <b>FALSE</b>
 */
function getUserName($id) 
{
    $stmt = $this->db->stmt_init();
    if ($stmt->prepare("Select Nombre from usuarios where id = ?")) {
        $name = '';
        $stmt->bind_param('i', $id);
        $stmt->execute();
        $stmt->bind_result($name);
        while ($stmt->fetch())
            $nombre = $name;
        $stmt->close();
        return $nombre;
    } else {
          return false;
    }
}
/**
 * Edit the Name of the user according his ID
 * @param String Nombre, int id
 * @return Boolean if an error occurred.
 * returns <b>FALSE</b>, else returns <b>TRUE</b>
 */
function setUserName($nombre, $id) 
{
    $stmt = $this->db->stmt_init();
    if ($stmt->prepare("UPDATE usuarios SET Nombre=? WHERE id =?")) {
        $stmt->bind_param('si', $nombre, $id);
        $stmt->execute();
        $stmt->close();
        return true;
    } else {
        return false;
    }
}
}