通過上一小節,mybatis 和 jdbc 的區別:http://www.cnblogs.com/ysocean/p/7271600.html,我們對 mybatis有了一個大致的了解,下面我們通過一個入門實例來對mybatis有更近一步的了解。
我們用 mybatis 來對 user 表進行增刪改查操作。
ps:本篇博客源代碼鏈接:http://pan.baidu.com/s/1eSEfc8i 密碼:j480
1、創建MySQL數據庫:mybatisDemo和表:user
這里我們就不寫腳本創建了,創建完成后,再向其中插入幾條數據即可。
user 表字段如下:
2、建立一個Java工程,並導入相應的jar包,具體目錄如下
注意:log4j和Junit不是必須的,但是我們為了查看日志以及便於測試,加入了這兩個jar包
3、在 MyBatisTest 工程中添加數據庫配置文件 mybatis-configuration.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> <!-- 注意:environments標簽,當mybatis和spring整合之后,這個標簽是不用配置的 --> <!-- 可以配置多個運行環境,但是每個 SqlSessionFactory 實例只能選擇一個運行環境 一、development:開發模式 二、work:工作模式--> <environments default="development"> <!--id屬性必須和上面的default一樣 --> <environment id="development"> <!--事務管理器 一、JDBC:這個配置直接簡單使用了 JDBC 的提交和回滾設置。它依賴於從數據源得到的連接來管理事務范圍 二、MANAGED:這個配置幾乎沒做什么。它從來不提交或回滾一個連接。而它會讓容器來管理事務的整個生命周期 比如 spring 或 JEE 應用服務器的上下文,默認情況下,它會關閉連接。然而一些容器並不希望這樣, 因此如果你需要從連接中停止它,就可以將 closeConnection 屬性設置為 false,比如: <transactionManager type="MANAGED"> <property name="closeConnection" value="false"/> </transactionManager> --> <transactionManager type="JDBC"/> <!--dataSource 元素使用標准的 JDBC 數據源接口來配置 JDBC 連接對象源 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> </configuration>
4、定義表所對應的實體類
package com.ys.po; import java.util.Date; public class User { private int id; private String username; private String sex; private Date birthday; private String address; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address=" + address + "]"; } }
5、定義操作 user 表的sql映射文件userMapper.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="com.ys.po.userMapper"> <!-- 根據 id 查詢 user 表中的數據 id:唯一標識符,此文件中的id值不能重復 resultType:返回值類型,一條數據庫記錄也就對應實體類的一個對象 parameterType:參數類型,也就是查詢條件的類型 --> <select id="selectUserById" resultType="com.ys.po.User" parameterType="int"> <!-- 這里和普通的sql 查詢語句差不多,對於只有一個參數,后面的 #{id}表示占位符,里面不一定要寫id,寫啥都可以,但是不要空着,如果有多個參數則必須寫pojo類里面的屬性 --> select * from user where id = #{id} </select> <!-- 查詢 user 表的所有數據 注意:因為是查詢所有數據,所以返回的應該是一個集合,這個集合里面每個元素都是User類型 --> <select id="selectUserAll" resultType="com.ys.po.User"> select * from user </select> <!-- 模糊查詢:根據 user 表的username字段 下面兩種寫法都可以,但是要注意 1、${value}里面必須要寫value,不然會報錯 2、${}表示拼接 sql 字符串,將接收到的參數不加任何修飾拼接在sql語句中 3、使用${}會造成 sql 注入 --> <select id="selectLikeUserName" resultType="com.ys.po.User" parameterType="String"> select * from user where username like '%${value}%' <!-- select * from user where username like #{username} --> </select> <!-- 向 user 表插入一條數據 --> <insert id="insertUser" parameterType="com.ys.po.User"> insert into user(id,username,sex,birthday,address) value(#{id},#{username},#{sex},#{birthday},#{address}) </insert> <!-- 根據 id 更新 user 表的數據 --> <update id="updateUserById" parameterType="com.ys.po.User"> update user set username=#{username} where id=#{id} </update> <!-- 根據 id 刪除 user 表的數據 --> <delete id="deleteUserById" parameterType="int"> delete from user where id=#{id} </delete> </mapper>
6、向 mybatis-configuration.xml 配置文件中注冊 userMapper.xml 文件
<mappers> <!-- 注冊userMapper.xml文件, userMapper.xml位於com.ys.mapper這個包下,所以resource寫成com/ys/mapper/userMapper.xml--> <mapper resource="com/ys/mapper/userMapper.xml"/> </mappers>
7、創建測試類
package com.ys.test; import java.io.InputStream; import java.util.List; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import com.ys.po.User; public class CRUDTest { //定義 SqlSession SqlSession session =null; @Before public void init(){ //定義mybatis全局配置文件 String resource = "mybatis-configuration.xml"; //加載 mybatis 全局配置文件 InputStream inputStream = CRUDTest.class.getClassLoader() .getResourceAsStream(resource); //構建sqlSession的工廠 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //根據 sqlSessionFactory 產生 session session = sessionFactory.openSession(); } //根據id查詢user表數據 @Test public void testSelectUserById(){ /*這個字符串由 userMapper.xml 文件中 兩個部分構成 <mapper namespace="com.ys.po.userMapper"> 的 namespace 的值 <select id="selectUserById" > id 值*/ String statement = "com.ys.po.userMapper.selectUserById"; User user = session.selectOne(statement, 1); System.out.println(user); session.close(); } //查詢所有user表所有數據 @Test public void testSelectUserAll(){ String statement = "com.ys.po.userMapper.selectUserAll"; List<User> listUser = session.selectList(statement); for(User user : listUser){ System.out.println(user); } session.close(); } //模糊查詢:根據 user 表的username字段 @Test public void testSelectLikeUserName(){ String statement = "com.ys.po.userMapper.selectLikeUserName"; List<User> listUser = session.selectList(statement, "%t%"); for(User user : listUser){ System.out.println(user); } session.close(); } //向 user 表中插入一條數據 @Test public void testInsertUser(){ String statement = "com.ys.po.userMapper.insertUser"; User user = new User(); user.setUsername("Bob"); user.setSex("女"); session.insert(statement, user); //提交插入的數據 session.commit(); session.close(); } //根據 id 更新 user 表的數據 @Test public void testUpdateUserById(){ String statement = "com.ys.po.userMapper.updateUserById"; //如果設置的 id不存在,那么數據庫沒有數據更改 User user = new User(); user.setId(4); user.setUsername("jim"); session.update(statement, user); session.commit(); session.close(); } //根據 id 刪除 user 表的數據 @Test public void testDeleteUserById(){ String statement = "com.ys.po.userMapper.deleteUserById"; session.delete(statement,4); session.commit(); session.close(); } }
補充:如何得到插入數據之后的主鍵值?
第一種:數據庫設置主鍵自增機制
userMapper.xml 文件中定義:
<!-- 向 user 表插入一條數據 --> <insert id="insertUser" parameterType="com.ys.po.User"> <!-- 將插入的數據主鍵返回到 user 對象中 keyProperty:將查詢到的主鍵設置到parameterType 指定到對象的那個屬性 select LAST_INSERT_ID():查詢上一次執行insert 操作返回的主鍵id值,只適用於自增主鍵 resultType:指定 select LAST_INSERT_ID() 的結果類型 order:AFTER,相對於 select LAST_INSERT_ID()操作的順序 --> <selectKey keyProperty="id" resultType="int" order="AFTER"> select LAST_INSERT_ID() </selectKey> insert into user(username,sex,birthday,address) value(#{username},#{sex},#{birthday},#{address}) </insert>
測試:
//向 user 表中插入一條數據並獲取主鍵值 @Test public void testInsertUser(){ String statement = "com.ys.po.userMapper.insertUser"; User user = new User(); user.setUsername("Bob"); user.setSex("女"); session.insert(statement, user); //提交插入的數據 session.commit(); //打印主鍵值 System.out.println(user.getId()); session.close(); }
第二種:非自增主鍵機制
<!-- 向 user 表插入一條數據 --> <insert id="insertUser" parameterType="com.ys.po.User"> <!-- 將插入的數據主鍵返回到 user 對象中 流程是:首先通過 select UUID()得到主鍵值,然后設置到 user 對象的id中,在進行 insert 操作 keyProperty:將查詢到的主鍵設置到parameterType 指定到對象的那個屬性 select UUID():得到主鍵的id值,注意這里是字符串 resultType:指定 select UUID() 的結果類型 order:BEFORE,相對於 select UUID()操作的順序 --> <selectKey keyProperty="id" resultType="String" order="BEFORE"> select UUID() </selectKey> insert into user(id,username,sex,birthday,address) value(#{id},#{username},#{sex},#{birthday},#{address}) </insert>
總結:
①、parameterType:指定輸入參數的類型
②、resultType:指定輸出結果的類型,在select中如果查詢結果是集合,那么也表示集合中每個元素的類型
③、#{}:表示占位符,用來接收輸入參數,類型可以是簡單類型,pojo,HashMap等等
如果接收簡單類型,#{}可以寫成 value 或者其他名稱
如果接收 pojo 對象值,通過 OGNL 讀取對象中的屬性值,即屬性.屬性.屬性...的方式獲取屬性值
④、${}:表示一個拼接符,會引起 sql 注入,不建議使用
用來接收輸入參數,類型可以是簡單類型,pojo,HashMap等等
如果接收簡單類型,${}里面只能是 value
如果接收 pojo 對象值,通過 OGNL 讀取對象中的屬性值,即屬性.屬性.屬性...的方式獲取屬性值