一直在使用,從未系統的總結起來。因此這裏給你們帶來的是mybatis的總結,系統你們可以對這個框架有必定的系統的學習與認識。
mybatis和Hibernate應該是如今主流的ORM框架了。
mybatis學習的步驟:
mybatis入門 --> 全局配置文件和映射文件詳解 --> 高級映射(一對一,一對多,多對多) -->延遲加載機制 -->一級緩存,
二級緩存(整合ehcache) --> spring整合mybatis --> 逆向工程java
總結一下:mysql
MyBatis 是來和數據庫打交道。那麼在這以前,咱們是使用 JDBC 來對數據庫進行增刪改查等一系列操做的,而咱們之因此會放棄
使用 JDBC,轉而使用 MyBatis 框架,這是爲何呢?
爲何使用Mybatis比JDBC直接鏈接方便和性能上好不少呢?spring
public class Person { private Long pid; private String pname; public Long getPid() { return pid; } public void setPid(Long pid) { this.pid = pid; } public String getPname() { return pname; } public void setPname(String pname) { this.pname = pname; } }
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import javax.swing.DebugGraphics; import com.ys.bean.Person; public class CRUDDao { //MySQL數據庫驅動 public static String driverClass = "com.mysql.jdbc.Driver"; //MySQL用戶名 public static String userName = "root"; //MySQL密碼 public static String passWord = "654321"; //MySQL URL public static String url = "jdbc:mysql://localhost:3306/study"; //定義數據庫鏈接 public static Connection conn = null; //定義聲明數據庫語句,使用 預編譯聲明 PreparedStatement提升數據庫執行性能 public static PreparedStatement ps = null; //定義返回結果集 public static ResultSet rs = null; /** * 查詢 person 表信息 * @return:返回 person 的 list 集合 */ public static List<Person> readPerson(){ List<Person> list = new ArrayList<>(); try { //加載數據庫驅動 Class.forName(driverClass); //獲取數據庫鏈接 conn = DriverManager.getConnection(url, userName, passWord); //定義 sql 語句,?表示佔位符 String sql = "select * from person where pname=?"; //獲取預編譯處理的statement ps = conn.prepareStatement(sql); //設置sql語句中的參數,第一個爲sql語句中的參數的?(從1開始),第二個爲設置的參數值 ps.setString(1, "qzy"); //向數據庫發出 sql 語句查詢,並返回結果集 rs = ps.executeQuery(); while (rs.next()) { Person p = new Person(); p.setPid(rs.getLong(1)); p.setPname(rs.getString(2)); list.add(p); } } catch (Exception e) { e.printStackTrace(); }finally{ //關閉數據庫鏈接 if(rs!=null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if(ps!=null){ try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } return list; } public static void main(String[] args) { System.out.println(CRUDDao.readPerson()); } }
建立完成,隨便寫幾條數據進去。sql
備註:log4j和Junit不是必須的,可是咱們爲了查看日誌以及便於測試,加入了這兩個jar包
目錄結構:
數據庫
<?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 實例只能選擇一個運行環境 1、development:開發模式 2、work:工做模式--> <environments default="development"> <!--id屬性必須和上面的default同樣 --> <environment id="development"> <!--事務管理器 1、JDBC:這個配置直接簡單使用了 JDBC 的提交和回滾設置。它依賴於從數據源獲得的鏈接來管理事務範圍 2、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/study"/> <property name="username" value="root"/> <property name="password" value="654321"/> </dataSource> </environment> </environments> <mappers> <!-- 註冊userMapper.xml文件, userMapper.xml位於com.lance.mybatis這個包下,因此resource寫成com/lance/mybatis/userMapper.xml--> <mapper resource="com/lance/mybatis/mapper/userMapper.xml"/> </mappers> </configuration>
package com.lance.mybatis.bean; import java.util.Date; public class User { private int id; private String username; private int password; 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 int getPassword() { return password; } public void setPassword(int password) { this.password = password; } 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 + '\'' + ", password=" + password + ", sex='" + sex + '\'' + ", birthday=" + birthday + ", address='" + address + '\'' + '}'; } }
<?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.lance.mybatis.mapper.userMapper"> <!-- 根據 id 查詢 user 表中的數據 id:惟一標識符,此文件中的id值不能重複 resultType:返回值類型,一條數據庫記錄也就對應實體類的一個對象 parameterType:參數類型,也就是查詢條件的類型 --> <select id="selectUserById" resultType="com.lance.mybatis.bean.User" parameterType="int"> <!-- 這裏和普通的sql 查詢語句差很少,後面的 #{id}表示佔位符,裏面不必定要寫id,寫啥均可以,可是不要空着 --> select * from user where id = #{id} </select> <!-- 查詢 user 表的全部數據 注意:由於是查詢全部數據,因此返回的應該是一個集合,這個集合裏面每一個元素都是User類型 --> <select id="selectUserAll" resultType="com.lance.mybatis.bean.User"> select * from user </select> <!-- 模糊查詢:根據 user 表的username字段 下面兩種寫法均可以,可是要注意 一、${value}裏面必需要寫value,否則會報錯 二、${}表示拼接 sql 字符串,將接收到的參數不加任何修飾拼接在sql語句中 三、使用${}會形成 sql 注入 --> <select id="selectLikeUserName" resultType="com.lance.mybatis.bean.User" parameterType="String"> select * from user where username like '%${value}%' <!-- select * from user where username like #{username} --> </select> <!-- 向 user 表插入一條數據 --> <insert id="insertUser" parameterType="com.lance.mybatis.bean.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,password,sex,birthday,address) value(#{username},#{password},#{sex},#{birthday},#{address}) </insert> <!-- 根據 id 更新 user 表的數據 --> <update id="updateUserById" parameterType="com.lance.mybatis.bean.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>
package com.lance.mybatis.test; import com.lance.mybatis.bean.User; 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 java.io.InputStream; import java.util.Date; import java.util.List; /** * @author lance(ZYH) * @function * @date 2018-07-07 21:10 */ public class MybatisTest { SqlSession session = null; @Before public void init() { //定義mybatis全局配置文件 String resource = "com/lance/mybatis/config/mybatis-configuration.xml"; //加載 mybatis 全局配置文件 InputStream inputStream = MybatisTest.class.getClassLoader() .getResourceAsStream(resource); //構建sqlSession的工廠 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //根據 sqlSessionFactory 產生 session session = sessionFactory.openSession(); } //根據id查詢user表數據 @Test public void getUserById() { /*這個字符串由 userMapper.xml 文件中 兩個部分構成 <mapper namespace="com.lance.mybatis.userMapper"> 的 namespace 的值 <select id="selectUserById" > id 值*/ String statement = "com.lance.mybatis.mapper.userMapper.selectUserById"; User user = session.selectOne(statement, 1); System.out.println(user); session.close(); } //查詢全部user表全部數據 @Test public void testSelectUserAll() { String statement = "com.lance.mybatis.mapper.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.lance.mybatis.mapper.userMapper.selectLikeUserName"; List<User> listUser = session.selectList(statement, "%張%"); for(User user : listUser){ System.out.println(user); } session.close(); } //向 user 表中插入一條數據 @Test public void testInsertUser(){ String statement = "com.lance.mybatis.mapper.userMapper.insertUser"; User user = new User(); user.setUsername("劉美玲"); user.setPassword(98766); user.setSex("女"); user.setAddress("河南省啥子去"); session.insert(statement, user); //提交插入的數據 session.commit(); session.close(); } //根據 id 更新 user 表的數據 @Test public void testUpdateUserById(){ String statement = "com.lance.mybatis.mapper.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.lance.mybatis.mapper.userMapper.deleteUserById"; session.delete(statement,4); session.commit(); session.close(); } }
1)數據庫設置主鍵自增機制
userMapper.xml 文件中定義:apache
<!-- 向 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,password,sex,birthday,address) value(#{username},#{password},#{sex},#{birthday},#{address}) </insert>
2)非自增主鍵機制緩存
<!-- 向 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,passwor,sex,birthday,address) value(#{id},#{username},#{password},#{sex},#{birthday},#{address}) </insert>