1、在前一篇中,存在一些問題:java
1. 沒有使用接口編程,Java是面向接口編程語言。應該對數據庫操做定義一些接口,調用dao接口完成數據庫操做。spring
public interface UserDao { //根據Id查詢用戶信息 public User findUserById(int userId) throws Exception; //添加用戶 public void insertUser(User user) throws Exception; //修改用戶 public void updateUser(User user) throws Exception; //刪除用戶 public void deleteUser(int userId) throws Exception; } public class UserDaoImpl implements UserDao { private SqlSessionFactory sqlSessionFactory; //經過spring將 SqlSessionFactory 注入,這裏沒有spring,暫時使用構造方法代替 public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; } public UserDaoImpl(SqlSessionFactory sqlSessionFactory) { this.setSqlSessionFactory(sqlSessionFactory); } @Override public User findUserById(int userId) throws Exception { SqlSession sqlSession = null; User user = null; try { //經過SqlSessionFactory獲取SqlSession sqlSession = sqlSessionFactory.openSession(); //使用session操做數據庫 //selectOne第一個參數:指定sql的id(statement id),注意帶上namespace;第二個參數:向sql中傳的參數值 user = sqlSession.selectOne("test.findUserById", userId); System.out.println(user); } catch (Exception e) { // TODO: handle exception } finally { if (sqlSession != null) { sqlSession.close(); } } return user; } @Override public void insertUser(User user) throws Exception { SqlSession sqlSession = null; try { //經過SqlSessionFactory獲取SqlSession sqlSession = sqlSessionFactory.openSession(); //使用session操做數據庫 sqlSession.insert("test.insertUser", user); //提交事務 sqlSession.commit(); } catch (Exception e) { // TODO: handle exception } finally { if (sqlSession != null) { sqlSession.close(); } } } }
2. 雖然上面改寫成Dao接口實現類的方式,但訪問sql映射文件中定義的sql時須要調用 SqlSession 的 selectOne() 方法, 並將 sql 的位置(命名空間 + id)和參數傳遞到 selectOne() 方法中,且第一個參數是長字符串,第二個參數是object 對象,編寫代碼時出現錯誤沒法 在編譯階段發現。sql
優化:
數據庫
第一步:定義UserMapper.xml, 還用原來的不用變編程
第二步:定義mapper接口session
public interface UserMapper { //根據Id查詢用戶信息 public User findUserById(int userId) throws Exception; //添加用戶 public void insertUser(User user) throws Exception; //修改用戶 public void updateUserById(User user) throws Exception; //刪除用戶 public void deleteUserById(int userId) throws Exception; }
接口定義有如下特色:mybatis
a. Mapper 接口方法名和 UserMapper.xml 中定義的每一個 sql 的 id 同名。
app
b. Mapper 接口方法的輸入參數類型和 UserMapper.xml 中定義的 sql parameterType 類型相同。
編程語言
c. Mapper 接口的輸出參數類型和 UserMapper.xml 中 定義的 sql 的 resultType 類型相同。
ide
第三步:修改 UserMapper.xml 的namespace
修改後的 namespace 便是 Mapper 接口的類路徑。
<mapper namespace="mybatis.mapper.UserMapper">
第四步:經過 Mapper 接口調用statement 去操做數據庫
public class UserMapperTest extends TestCase { private SqlSessionFactory sqlSessionFactory; String resource = "SqlMapConfig.xml"; //任何測試方法都要執行的方法 @Override protected void setUp() throws Exception { super.setUp(); //經過輸入流讀取配置文件 InputStream inputStream = Resources.getResourceAsStream(resource); //獲取SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } public User testFindUserById() throws Exception { //獲取SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); //指定 mapper 接口的類型,MyBatis經過動態代理的方式實現mapper接口 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.findUserById(100101); sqlSession.commit(); sqlSession.close(); //查詢主鍵爲100101的用戶並輸出 System.out.println("user---" + user); return user; } public void testInsertUser() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); //指定 mapper 接口的類型,MyBatis經過動態代理的方式實現mapper接口 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setUsername("Dina"); user.setSex("0"); user.setBirthday(new Date()); user.setAddress("Redwood City"); user.setDetail("good person"); user.setScore(99.2f); userMapper.insertUser(user); sqlSession.commit(); sqlSession.close(); } public void testUpdateUserById() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); //指定 mapper 接口的類型,MyBatis經過動態代理的方式實現mapper接口 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = new User(); user.setUserId(100102); user.setUsername("Golden"); user.setSex("0"); user.setBirthday(new Date()); user.setAddress("Shen zhen"); user.setDetail("good person"); user.setScore(89.2f); userMapper.updateUserById(user); sqlSession.commit(); sqlSession.close(); } public void testDeleteUserById() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.deleteUserById(100110); sqlSession.commit(); sqlSession.close(); } }
總結:
使用 Mapper 接口的方式,不用寫接口實現類接口完成數據庫操做,簡單方便,此方法是官方推薦。
是MyBatis一種很重要的用法。
使用 Mapper 接口調用必須具有如下條件:
Mapper 接口方法名 和 UserMapper.xml 中定義的每一個 sql 的 id 同名。
Mapper 接口方法的輸入參數類型和 UserMapper.xml 中定義的 sql parameterType 類型相同。
Mapper 接口的輸出參數類型和 UserMapper.xml 中 定義的 sql 的 resultType 類型相同。
UserMapper.xml 文件中的 namespace 便是 Mapper 接口的類路徑。