mybatis的学习笔记01
1 MyBatis介紹
MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,并且改名為MyBatis 。2013年11月遷移到Github。 MyBatis是一個優秀的持久層框架,它對jdbc的操作數據庫的過程進行封裝,使開發者只需要關注 SQL 本身,而不需要花費精力去處理例如注冊驅動、創建connection、創建statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼。
Mybatis通過xml或注解的方式將要執行的各種statement(statement、preparedStatement、CallableStatement)配置起來,并通過java對象和statement中的sql進行映射生成最終執行的sql語句,最后由mybatis框架執行sql并將結果映射成java對象并返回。
2 使用jdbc編程問題總結
2.1 創建mysql數據庫
先導入創建數據庫的sql腳本導入到數據庫中。
2.2 創建工程
1、創建一個java工程。
2、導入jar包。此時需要mysql 的數據庫驅動。
2.3 jdbc編程步驟:
2.4 jdbc程序
public static void main(String[] args) {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;try {//加載數據庫驅動Class.forName("com.mysql.jdbc.Driver");//通過驅動管理類獲取數據庫鏈接connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "root");//定義sql語句 ?表示占位符String sql = "select * from user where username = ?";//獲取預處理statementpreparedStatement = connection.prepareStatement(sql);//設置參數,第一個參數為sql語句中參數的序號(從1開始),第二個參數為設置的參數值preparedStatement.setString(1, "王五");//向數據庫發出sql執行查詢,查詢出結果集resultSet = preparedStatement.executeQuery();//遍歷查詢結果集while(resultSet.next()){System.out.println(resultSet.getString("id")+" "+resultSet.getString("username"));}} catch (Exception e) {e.printStackTrace();}finally{//釋放資源if(resultSet!=null){try {resultSet.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(preparedStatement!=null){try {preparedStatement.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}if(connection!=null){try {connection.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}上邊使用jdbc的原始方法(未經封裝)實現了查詢數據庫表記錄的操作。
2.5 jdbc問題總結如下:
1、 數據庫鏈接創建、釋放頻繁造成系統資源浪費從而影響系統性能,如果使用數據庫鏈接池可解決此問題。
2、 Sql語句在代碼中硬編碼,造成代碼不易維護,實際應用sql變化的可能較大,sql變動需要改變java代碼。
3、 使用preparedStatement向占有位符號傳參數存在硬編碼,因為sql語句的where條件不一定,可能多也可能少,修改sql還要修改代碼,系統不易維護。
4、 對結果集解析存在硬編碼(查詢列名),sql變化導致解析代碼變化,系統不易維護,如果能將數據庫記錄封裝成pojo對象解析比較方便。
3 Mybatis架構
1、 mybatis配置
SqlMapConfig.xml,此文件作為mybatis的全局配置文件,配置了mybatis的運行環境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作數據庫的sql語句。此文件需要在SqlMapConfig.xml中加載。
2、 通過mybatis環境等配置信息構造SqlSessionFactory即會話工廠
3、 由會話工廠創建sqlSession即會話,操作數據庫需要通過sqlSession進行。
4、 mybatis底層自定義了Executor執行器接口操作數據庫,Executor接口有兩個實現,一個是基本執行器、一個是緩存執行器。
5、 Mapped Statement也是mybatis一個底層封裝對象,它包裝了mybatis配置信息及sql映射信息等。mapper.xml文件中一個sql對應一個Mapped Statement對象,sql的id即是Mapped statement的id。
6、 Mapped Statement對sql執行輸入參數進行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執行sql前將輸入的java對象映射至sql中,輸入參數映射就是jdbc編程中對preparedStatement設置參數。
7、 Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執行sql后將輸出結果映射至java對象中,輸出結果映射過程相當于jdbc編程中對結果的解析處理過程。
4 Mybatis入門程序
4.1 mybatis下載
mybaits的代碼由github.com管理,地址:https://github.com/mybatis/mybatis-3/releases
mybatis-3.2.7.jar—-mybatis的核心包
lib—-mybatis的依賴包
mybatis-3.2.7.pdf—-mybatis使用手冊
4.2 需求
實現以下功能:
根據用戶id查詢一個用戶信息
根據用戶名稱模糊查詢用戶信息列表
添加用戶
更新用戶
刪除用戶
4.3 工程搭建
4.3.1 第一步:創建java工程
4.3.2 第二步:加入jar包
加入mybatis核心包、依賴包、數據驅動包。
4.3.3 第三步:log4j.properties
在classpath下創建log4j.properties如下:
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%nmybatis默認使用log4j作為輸出日志信息。
4.3.4 第四步:SqlMapConfig.xml
在classpath下創建SqlMapConfig.xml,如下:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><!-- 和spring整合后 environments配置將廢除--><environments default="development"><environment id="development"><!-- 使用jdbc事務管理--><transactionManager type="JDBC" /><!-- 數據庫連接池--><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver" /><property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /><property name="username" value="root" /><property name="password" value="root" /></dataSource></environment></environments></configuration>SqlMapConfig.xml是mybatis核心配置文件,上邊文件的配置內容為數據源、事務管理。
4.3.5 第五步:po類
Po類作為mybatis進行sql映射使用,po類通常與數據庫表對應,User.java如下:
Public class User {private int id;private String username;// 用戶姓名private String sex;// 性別private Date birthday;// 生日private String address;// 地址get/set……4.3.5.1 Mybatis的自動映射
0x00:引子
在 MyBatis 的映射配置文件中,select 標簽查詢配置結果集時使用過 resultType 屬性,當在 resultType 中定義一個 Java 包裝類時,如果 sql 語句查詢的結果中有列名與該 Java 包裝類中的屬性名一致,則該字段就會被映射到該屬性上。這里用到的就是 MyBatis 的自動映射功能,
當 sql 語句查詢出結果時,如果對應輸出配置的 Java 包裝類中有相同名稱的屬性,且擁有 set 方法,則該結果就會被自動映射。
0x01:原理
MyBatis 的自動映射功能是建立在 resultMap 基礎之上的。resultType 屬性自動映射的原理是,當 sql 映射輸出配置為 resultType 時,MyBatis 會生成一個空的 resultMap,然后指定這個 resultMap 的 type 為指定的 resultType 的類型,接著 MyBatis 檢測查詢結果集中字段與指定 type 類型中屬性的映射關系,對結果進行自動映射。
4.3.6 第六步:sql映射文件
在classpath下的sqlmap目錄下創建sql映射文件Users.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="test"> </mapper>namespace :命名空間,用于隔離sql語句,后面會講另一層非常重要的作用。
4.3.7 第七步:加載映射文件
mybatis框架需要加載映射文件,將Users.xml添加在SqlMapConfig.xml,如下:
<mappers><mapper resource="sqlmap/User.xml"/> </mappers>4.4 根據id查詢用戶信息
4.4.1 映射文件:
在user.xml中添加:
<!-- 根據id獲取用戶信息 --><select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">select * from user where id = #{id}</select>4.4.2 測試程序:
public class Mybatis_first {//會話工廠private SqlSessionFactory sqlSessionFactory;@Beforepublic void createSqlSessionFactory() throws IOException {// 配置文件String resource = "SqlMapConfig.xml";InputStream inputStream = Resources.getResourceAsStream(resource);// 使用SqlSessionFactoryBuilder從xml配置文件中創建SqlSessionFactorysqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}// 根據 id查詢用戶信息@Testpublic void testFindUserById() {// 數據庫會話實例SqlSession sqlSession = null;try {// 創建數據庫會話實例sqlSessionsqlSession = sqlSessionFactory.openSession();// 查詢單個記錄,根據用戶id查詢用戶信息User user = sqlSession.selectOne("test.findUserById", 10);// 輸出用戶信息System.out.println(user);} catch (Exception e) {e.printStackTrace();} finally {if (sqlSession != null) {sqlSession.close();}}} }4.5 根據用戶名查詢用戶信息
4.5.1 映射文件:
在user.xml中添加:
<!-- 自定義條件查詢用戶列表 --><select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">select * from user where username like '%${value}%' </select>parameterType:定義輸入到sql中的映射類型,value表示使用參數將{value}替換,做字符串的拼接。
注意:如果是取簡單數量類型的參數,括號中的值必須為value
resultType:定義結果映射類型。
4.5.2 測試程序:
// 根據用戶名稱模糊查詢用戶信息 @Test public void testFindUserByUsername() {// 數據庫會話實例SqlSession sqlSession = null;try {// 創建數據庫會話實例sqlSessionsqlSession = sqlSessionFactory.openSession();// 查詢單個記錄,根據用戶id查詢用戶信息List<User> list = sqlSession.selectList("test.findUserByUsername", "張");System.out.println(list.size());} catch (Exception e) {e.printStackTrace();} finally {if (sqlSession != null) {sqlSession.close();}}}4.6 小結
4.6.1 #{}和${}
#{}表示一個占位符號,通過#{}可以實現preparedStatement向占位符中設置值,自動進行java類型和jdbc類型轉換,#{}可以有效防止sql注入。 #{}可以接收簡單類型值或pojo屬性值。 如果parameterType傳輸單個簡單類型值,#{}括號中可以是value或其它名稱。
表示拼接sql串,通過{}表示拼接sql串,通過表示拼接sql串,通過{}可以將parameterType 傳入的內容拼接在sql中且不進行jdbc類型轉換, 可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,{}可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,可以接收簡單類型值或pojo屬性值,如果parameterType傳輸單個簡單類型值,{}括號中只能是value。
4.6.2 parameterType和resultType
parameterType:指定輸入參數類型,mybatis通過ognl從輸入對象中獲取參數值拼接在sql中。
resultType:指定輸出結果類型,mybatis將sql查詢結果的一行記錄數據映射為resultType指定類型的對象。
4.6.3 selectOne和selectList
selectOne查詢一條記錄,如果使用selectOne查詢多條記錄則拋出異常:
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)selectList可以查詢一條或多條記錄。
4.7 添加用戶
4.7.1 映射文件:
在在user.xml中添加:
<!-- 添加用戶 --><insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})</insert>4.7.2 測試程序:
// 添加用戶信息@Testpublic void testInsert() {// 數據庫會話實例SqlSession sqlSession = null;try {// 創建數據庫會話實例sqlSessionsqlSession = sqlSessionFactory.openSession();// 添加用戶信息User user = new User();user.setUsername("張小明");user.setAddress("河南鄭州");user.setSex("1");user.setPrice(1999.9f);sqlSession.insert("test.insertUser", user);//提交事務sqlSession.commit();} catch (Exception e) {e.printStackTrace();} finally {if (sqlSession != null) {sqlSession.close();}}}4.7.3 mysql自增主鍵返回
通過修改sql映射文件,可以將mysql自增主鍵返回:
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"><!-- selectKey將主鍵返回,需要再返回 --><selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">select LAST_INSERT_ID()</selectKey>insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address});</insert>添加selectKey實現將主鍵返回
keyProperty:返回的主鍵存儲在pojo中的哪個屬性
order:selectKey的執行順序,是相對與insert語句來說,由于mysql的自增原理執行完insert語句之后才將主鍵生成,所以這里selectKey的執行順序為after
resultType:返回的主鍵是什么類型
LAST_INSERT_ID():是mysql的函數,返回auto_increment自增列新記錄id值。
4.7.4 Mysql使用 uuid實現主鍵
需要增加通過select uuid()得到uuid值
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> <selectKey resultType="java.lang.String" order="BEFORE" keyProperty="id"> select uuid() </selectKey> insert into user(id,username,birthday,sex,address) values(#{id},#{username},#{birthday},#{sex},#{address}) </insert>注意這里使用的order是“BEFORE”
總結
以上是生活随笔為你收集整理的mybatis的学习笔记01的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ssm框架的搭建--向数据库查询数据
- 下一篇: 这21个不太好搜索其含义的特殊符号你都知