1. 程式人生 > 其它 >Mybatis全解-03

Mybatis全解-03

ResultMap

當實體類的屬性與資料庫中的表字段名不一致時出現的問題。

與之前的User類不同,這一次將其中的密碼屬性改為password。

而資料庫中的表字段還是pwd。

public class User {

   private int id;  //id
   private String name;   //姓名
   private String password;   //密碼和資料庫不一樣!
   
   //構造
   //set/get
   //toString()
}

介面和對映檔案不變

//根據id查詢使用者
User selectUserById(int id);
<select 
id="selectUserById" resultType="user"> select * from user where id = #{id} </select>

測試

@Test
public void testSelectUserById() {
   SqlSession session = MybatisUtils.getSession();  //獲取SqlSession連線
   UserMapper mapper = session.getMapper(UserMapper.class);
   User user = mapper.selectUserById(1);
   System.out.println(user);
   session.close();
}

結果發現,password='null'

結論:mybatis會根據查詢的列名(自動將列名轉化為小寫,資料庫不區分大小寫),然後在對應的實體類中查詢與列名對應的set方法設定值,由於找不到對應的setPwd();因此,查詢的password值為空。

為了解決資料庫列名與物件屬性名不一致的問題,有下面兩種解決方法。

1.為列名指定別名,別名和物件的屬性名一致。 關鍵詞:as

<select id="selectUserById" resultType="User">
  select id , name , pwd as password from user where id = #{id}
</select>

2.使用結果集對映。關鍵詞:ResultMap

<resultMap id="UserMap" type="User">
   <!-- id為主鍵 -->
   <id column="id" property="id"/>
   <!-- column是資料庫表的列名 , property是對應實體類的屬性名 -->
   <result column="name" property="name"/>
   <result column="pwd" property="password"/>
</resultMap>

<select id="selectUserById" resultMap="UserMap">
  select id , name , pwd from user where id = #{id}
</select>

ResultMap的設計思想是,對於簡單的語句根本不需要配置顯示的結果對映,而對於複雜一點的語句只需要描述他們之間的關係就好了

日誌工廠

日誌的實現有多種工具,你只需要在mybatis核心配置檔案mybatis-config.xml中配置即可。

標準的日誌實現,配置好下面的設定之後,你就可以在控制檯看到有大量的日誌輸出,有利於程式排錯。

<settings>
       <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

Log4j 最為常用的日誌工具

通過Log4j,可以控制日誌資訊輸出的目的地,如:控制檯、文字、GUI元件...

並且可以控制每一條日誌的輸出格式。

通過定義每一條日誌資訊的級別,我們能夠更加細緻地控制日誌的生成過程。所有的一切我們僅僅需要通過一個配置檔案來完成,而不需要修改應用的程式碼。

使用Log4j的步驟:

1.在pom中匯入Log4j的jar包

<dependency>
   <groupId>log4j</groupId>
   <artifactId>log4j</artifactId>
   <version>1.2.17</version>
</dependency>

2.控制日誌的配置檔案編寫

#將等級為DEBUG的日誌資訊輸出到console和file這兩個目的地,console和file的定義在下面的程式碼
log4j.rootLogger=DEBUG,console,file

#控制檯輸出的相關設定
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#檔案輸出的相關設定
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/li.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日誌輸出級別
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

3.在mybatis核心配置檔案中,新增Log4j的實現

<settings>
   <setting name="logImpl" value="LOG4J"/>
</settings>

4.在應用程式中使用Log4j進行輸出

//注意導包:org.apache.log4j.Logger
static Logger logger = Logger.getLogger(MyTest.class);

@Test
public void selectUser() {
   logger.info("info:進入selectUser方法");
   logger.debug("debug:進入selectUser方法");
   logger.error("error: 進入selectUser方法");
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);
   List<User> users = mapper.selectUser();
   for (User user: users){
       System.out.println(user);
  }
   session.close();
}

5.結果

還生成了一個對應的日誌檔案

分頁

limit分頁

為什麼需要分頁,減少資料庫的查詢壓力。

#語法
SELECT * FROM table LIMIT stratIndex,pageSize

SELECT * FROM table LIMIT 5,10; // 檢索記錄行 6-15  

#為了檢索從某一個偏移量到記錄集的結束所有的記錄行,可以指定第二個引數為 -1:   
SELECT * FROM table LIMIT 95,-1; // 檢索記錄行 96-last.  

#如果只給定一個引數,它表示返回最大的記錄行數目:   
SELECT * FROM table LIMIT 5; //檢索前 5 個記錄行  

#換句話說,LIMIT n 等價於 LIMIT 0,n。 

示例:

//選擇全部使用者實現分頁
List<User> selectUser(Map<String,Integer> map);
<select id="selectUser" parameterType="map" resultType="user">
  select * from user limit #{startIndex},#{pageSize}
</select>

注意公式:起始位置=(當前頁面-1)*頁面大小

//分頁查詢 , 兩個引數startIndex , pageSize
@Test
public void testSelectUser() {
   SqlSession session = MybatisUtils.getSession();
   UserMapper mapper = session.getMapper(UserMapper.class);

   int currentPage = 1;  //第幾頁
   int pageSize = 2;  //每頁顯示幾個
   Map<String,Integer> map = new HashMap<String,Integer>();
   map.put("startIndex",(currentPage-1)*pageSize);
   map.put("pageSize",pageSize);

   List<User> users = mapper.selectUser(map);

   for (User user: users){
       System.out.println(user);
  }

   session.close();
}

RowBounds分頁

除了使用limit在sql層面實現分頁,也可以使用RowBounds在java程式碼層面實現分頁,瞭解即可,不推薦使用。

//選擇全部使用者RowBounds實現分頁
List<User> getUserByRowBounds();
<select id="getUserByRowBounds" resultType="user">
select * from user
</select>
@Test
public void testUserByRowBounds() {
   SqlSession session = MybatisUtils.getSession();

   int currentPage = 2;  //第幾頁
   int pageSize = 2;  //每頁顯示幾個
   RowBounds rowBounds = new RowBounds((currentPage-1)*pageSize,pageSize);

   //通過session.**方法進行傳遞rowBounds,[此種方式現在已經不推薦使用了]
   List<User> users =session.selectList("com.li.mapper.UserMapper.getUserByRowBounds", null,rowBounds);

   for (User user: users){
       System.out.println(user);
  }
   session.close();
}

第三方外掛:PageHelper,還有MybatisPlus