工具類的使用
上篇文章我們熟悉運用MyBatis進行增刪改查,並且手寫了一個mybatis的工具類,學習了一些關於單元測試和關於日誌的配置,沒有看的讀者請移步:MyBatis框架教程「實踐與工具類封裝」
這篇文章我們將通過一個案例繼續學習MyBatis,並且達到熟練使用工具類的目的,注意:實踐開發中的項目式不會使用工具類方式開發的,但是爲了讓讀者學習的更全面理解這個框架,我就要更認真更系統的寫教程。
小案例基本思路是:
我們在 MyBatisTest.java 中進行單元測試,單元測試中調用dao層實現類UserDaoImpl中的方法。在 UserDaoImpl.java 中運用我們手寫的mybatis工具類進行獲取sqlsession,執行映射文件中的sql,並把查詢結果返回MyBatisTest.java中的調用方法以輸出顯示。
mybatis工具類用來完成加載核心配置文件,創建sqlsession工廠等工作,接下來繼續我們案例的完成。
1. 項目截圖
2. 導入Jar包
右鍵項目->Build Path 添加JUnit單元測試的支持
3. 添加Log4J的配置:
# Global loggingconfigurationlog4j.rootLogger=ERROR,stdout#注意 namespace爲我們自己需要日誌處理的路徑名log4j.logger.com.jujidi.model.User=TRACE# Console output...log4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%5p[%t]-%m%n
4. 配置文件
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTDConfig 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 配置環境 --> <environments default="jujidi"> <environment id="jujidi"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/dbname"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 加載映射文件 --> <mappers> <mapper resource="com/jujidi/model/UserMapper.xml"/> </mappers> </configuration>
這是Mybatis框架的核心配置文件,其中配置了相關環境和加載映射文件,環境中確定數據源,在數據源中配置你需要鏈接數據庫的相關信息,比如用戶名、密碼。映射文件就是你編寫SQL的xml,通過此核心配置文件進行加載關聯。
5. MyBatisUtil.java
public finalclass MybatisUtil { private MybatisUtil(){} private static final String PATH = "mybatis-config.xml"; private static InputStream is = null; privates tatic SqlSessionFactory sqlSessionFactory = null; static{ try{ //加載核心配置文件 is = Resources.getResourceAsStream(PATH); //創建sqlsession工廠 -->相當於connection sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); }catch(IOException e){ e.printStackTrace(); throw new RuntimeException("加載映射文件失敗可能是你的映射文件寫錯了原因:"+e.getMessage()); } } //獲取sqlsession -->相當於執行sql語句對象 public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession(); } public static void closeSqlSession(SqlSession sqlSession){ if(sqlSession!=null){ sqlSession.close(); } } }
上方是一個MyBatis的工具類,根據核心配置文件創建sqlsession工廠,每一個SQL操作都要創建sqlsession工廠,我們就把創建工廠和獲取sqlsession的共同代碼提前出來,封裝成工具類,便於以後調用。
6. UserDao.java
public interface UserDao { User load(Integer user_id); User login(Map<String , Object> map); User loginByUser(User user); }
7. UserDaoImpl.java
public class UserDaoImpl implements UserDao { SqlSession sqlSession = null; @Override public User load(Integer user_id ) { try{ sqlSession = MybatisUtil.getSqlSession(); //User.classgetName()是獲取User model的全路徑名 User user = sqlSession.selectOne(User.class.getName()+".load",user_id); return user; }catch(Exception e){ e.printStackTrace(); throw new RuntimeException("查詢失敗"+e.getMessage()); }finally{ MybatisUtil.closeSqlSession(sqlSession); } } @Override public User login(Map<String ,Object> map ) { try{ sqlSession = MybatisUtil.getSqlSession(); User user = sqlSession.selectOne(User.class.getName()+".login",map); return user; }catch(Exception e){ e.printStackTrace(); throw new RuntimeException("登錄失敗"+e.getMessage()); }finally{ MybatisUtil.closeSqlSession(sqlSession); } } @Override public User loginByUser(User user ) { try{ sqlSession = MybatisUtil.getSqlSession(); User u = sqlSession.selectOne(User.class.getName()+".loginByUser",user); return; }catch(Exception e){ e.printStackTrace(); throw new RuntimeException("登錄失敗"+e.getMessage()); }finally{ MybatisUtil.closeSqlSession(sqlSession); } } }
上面式UserDao接口的實現類,其中有三個方法:load、login、loginByUser,這些方法都是調用工具類來獲取sqlSession,利用sqlSession來執行映射文件中的SQL,並且傳遞相關參數。可以通過全限定類名來找到對應的映射文件SQL。
8. User.java
public class User { private Integer userId; private String userName; private String account; private String pwd; private Integer status; }
注意:此處要生成getter,setter和tostring方法,爲了更良好的瀏覽體驗此處沒有給出。
9. UserMapper.xml
<?xml version="1.0"encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTDMapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.jujidi.model.User"> <sql id="jujidi"> user_name userName,user_iduserId,account,password pwd,status </sql> <select id="load" parameterType="integer"resultType="com.jujidi.model.User"> select <include refid="jujidi"></include> from user where user_id=#{user_id} </select> <select id="login" parameterType="map"resultType="com.jujidi.model.User"> select <include refid="jujidi"></include> from user where account=#{account} and password=#{password} </select> <select id="loginByUser" parameterType="com.jujidi.model.User" resultType="com.jujidi.model.User"> select <include refid="jujidi"></include> from user where account=#{account} and password=#{pwd} </select> </mapper>
對於上方的配置文件我們給出兩個注意:
注意一:上方的配置文件中的sql標籤:
<sql id="jujidi"> user_name userName,user_iduserId,account,password pwd,status </sql>
上方SQL標籤,可以在下方的Select語句中通過<include>標籤來引入這條sql語句。
值得注意的是,我們上一篇文章講過如果model 中的屬性名和數據庫中字段名稱不相同是獲取不到值的,但是我們現在可以通過上方sql標籤的方法解決。
也就是說我們數據庫中數據字段名稱爲:user_name,而我們的model中User的屬性名字爲:userName,我們可以通過類似下方語句:
Select user_name as userName from user
添加別名的方解決,當然 as 可以省略。
注意二:
<select id="login" parameterType="map"resultType="com.jujidi.model.User"> select <include refid="jujidi"></include> from user where account=#{account} and password=#{password} </select>
password=#{password} 中的#{password}必須是參數map的key,#{}會默認給包含的值加上單引號。
key 就是下方 MyBatisTest.java 文件中的map.put("password",value)的第一個參數。
並且 標籤配置中password=#{password}中的 password(等號前的字段)要和數據庫中的字段對應。
10. MyBatisTest.java:
public class MybatisTest { UserDao userDao = null; @Before public void init(){ userDao = new UserDaoImpl(); } @Test public void load() { User user = userDao.load(1); System.out.println(user); } @Test public void login() { Map<String , Object> map = new HashMap<String, Object>(); map.put("account" , "admin"); map.put("password" , "admin"); User user = userDao.login(map); System.out.println(user); } @Test public void loginByUser() { User user = new User(); user.setAccount("admin"); user.setPwd("admin"); User u = userDao.loginByUser(user); System.out.println(u); } }
上方是測試類,使用 @Before和 @Test 註解之前必須導入JUnit的相關Jar包,關於JUnit的介紹我們已經在前面文章講過,可以翻翻MyBatis教程系列查看。在測試方法中分別測試3個方法,來完成對mybatis工具類的使用。
總結
這裏我們已經可以熟練運用自己手寫的MyBatis工具類了,而且我們掌握了單元測試基本的用法和簡單的MyBatis的操作,對於工作中複雜的業務邏輯,僅僅簡單的CRUD是無法勝任,我們在以後的文章將會講解:模糊查詢,動態sql語句等知識。
重要說明:實際開發中是不會使用Mybatis工具類來進行開發的,而是SSM框架整合後,通過接口代理的方式來實現對數據庫的操縱。
爲了使初學者對Mybatis框架有一個獨立且系統的認識,所以採用這種系統的教學方式,而不是一開始就是整合。我們會在學習過程中逐漸拓展,最終達到實際開發所需要的本領。