mybatis 原理和使用
參考:https://mybatis.org/mybatis-3/zh/getting-started.html
一、JDBC
JDBC 是 Java 和資料庫之間的一個橋樑,是一個規範而不是一個實現,能夠執行 SQL 語句。它由一組用 Java 語言編寫的類和介面組成。各種不同型別的資料庫都有相應的實現,下面是針對 Mysql 資料庫實現的。
public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); Connection connection= DriverManager.getConnection("jdbc:mysql://10.10.130.161:3306/my", "root", "123456"); connection.setAutoCommit(false); PreparedStatement preparedStatement = connection .prepareStatement("insert into t_dep (name, age) values (?, ?)"); preparedStatement.setString(1, "xiali1"); preparedStatement.setInt(2, 18); try { preparedStatement.executeUpdate(); connection.commit(); } catch (Exception e){ connection.rollback(); e.printStackTrace(); } finally { if(preparedStatement != null){ preparedStatement.close(); } if(connection != null){ connection.close(); } } }
二、Mybatis 簡介
Mybatis 是一個優秀的持久層框架。他是一種對 JDBC 的封裝。
每個基於 Mybatis 的應用都是以一個 SqlSessionFactory 的例項為核心的。SqlSessionFactory 的例項可以通過 SqlSessionFactoryBuilder 獲得。而 SqlSessionFactoryBuilder 則可以從 XML 配置檔案或一個預先配置的 Configuration 例項來構建出 SqlSessionFactory 例項。
public static void main(String[] args) throws IOException { // 從配置檔案構建 SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 從 SqlSessionFactory 中獲取 SqlSession try (SqlSession session = sqlSessionFactory.openSession()) { Dept dept1 = (Dept)session.selectOne("com.pea.mybatis.asconfig.DeptMapper.selectDept",1); System.out.println("dept1 = " + dept1.toString()); DeptMapper mapper = session.getMapper(DeptMapper.class); Dept dept2 = mapper.selectDept(2); System.out.println("dept2 = " + dept2.toString()); } }
三、Mybatis 配置
1. 類型別名(typeAliases)
類型別名可為 Java 型別設定一個縮寫的名字。它僅用於 XML 配置,意在降低冗餘的全限定類名書寫。
2. 型別處理器(typeHandlers)
Mybatis 在設定預處理語句(PreparedStatement)中的引數或從結果集中取出一個值時,都會用型別處理器將獲取到的值以合適的方式轉換成 Java 型別。
可以重寫已有的型別處理器或者建立新的型別處理器來處理不支援的或非標準的型別。具體做法為:實現 org,apache,ibatis.type.TypeHandler 介面,或繼承 org.apache.ibatis.type.BaseTypeHandler。
3. 物件工廠(objectFactory)
每次 Mybatis 建立結果物件的新例項時,它都會使用一個物件工廠(ObjectFactory)例項來完成例項化工作。預設的物件工廠做的僅僅是例項化目標類,要麼通過無參構造方法,要麼通過存在的引數對映來呼叫帶有引數的構造方法。如果想要覆蓋物件工廠的預設行為,可以通過建立自己的物件工廠來實現。比如: public class ExampleObjectFactory extends DefaultObjectFactory{...}
4. 外掛(plugins)
Mybatis 允許在對映語句執行過程中的某一點進行攔截呼叫。預設情況下,Mybatis 允許使用外掛來攔截的方法呼叫包括:
- Executor(update,query,flushStatements,commit,rollback,getTransaction,close,isClosed)
- ParameterHandler(getParameterObject,setParameters)
- ResultSetHandler(handleResultSets,handleOutputParameters)
- StatementHandler(prepare,parameterize,batch,update,query)
通過 Mybatis 提供的強大機制,使用外掛時,只需要實現 Interceptor 介面,並指定想要攔截的方法簽名即可。
@Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})) public class SelectInterceptor implements Interceptor { private Properties properties = new Properties(); @Override public Object intercept(Invocation invocation) throws Throwable { System.out.println(" plugin plugin plugin plugin plugin "); final Object[] args = invocation.getArgs(); RowBounds rowBounds = (RowBounds) args[2]; MappedStatement mappedStatement = (MappedStatement) args[0]; Object o = invocation.proceed(); return o; } @Override public Object plugin(Object o) { return Plugin.wrap(o, this); } @Override public void setProperties(Properties properties) { this.properties = properties; } }
除了使用外掛來修改 Mybatis 核心行為外,還可以通過完全覆蓋配置類來達到目的。只需繼承配置類後覆蓋其中的某個方法,再把它傳遞到 SqlSessionFactoryBuilder.build(myConfig) 方法即可。但是,需要謹慎。
四、動態 SQL
<set> 可以忽略最後一個更新欄位後面的逗號
<where> 可以忽略第一個前面的 and
<trim> 可以指定忽略
<foreach> 可以用 list、array、myMap.values
五、#{} 和 ${}
#{} 只可以用在 where 後面,才用預編譯的方式,能有效防止sql 注入
${} 可以用在任何地方,不能防止 sql 注入,但是如果是表名需要動態獲取的,可以用這種方式