MyBatis 學(xué)習(xí)筆記(一)MyBatis的簡介與使用以及與其他ORM框架的比較
什么是MyBatis
MyBatis 前身是Apache基金會的開源項(xiàng)目iBatis,在2010年該項(xiàng)目脫離Apache基金會并正式更名為MyBatis,在2013年11月,MyBatis遷移到了GitHub。
MyBatis 是一個(gè)輕量級的,半自動的持久化(ORM)框架, 其通過XML映射配置文件或者注解來配置和映射原生類型,接口和Java的POJO(Plain Old Java Objects,普通老式Java對象)為數(shù)據(jù)庫中的記錄。之所以是半自動化的框架,是因?yàn)槠洳荒芟馠ibernate一樣實(shí)現(xiàn)自動生成SQL,其需要用戶手動編寫SQL語句。方便用戶對SQL語句進(jìn)行優(yōu)化,適用于大數(shù)據(jù)量,高并發(fā)場景。
MyBatis 是一塊比較容易上手的框架,使用者只需要通過簡單的學(xué)習(xí)即可掌握其常用特性。
為什么要使用MyBatis
使用MyBatis訪問數(shù)據(jù)庫
首先在pom文件中引入依賴
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
正如前面所說MyBatis 是一個(gè)半自動持久化框架。所以,需要我們自己來維護(hù)sql 語句,編寫sql語句的xml文件叫做映射文件。在此處,我建立了一個(gè)StudentMapper.xml 文件來維護(hù)sql 語句。
<mapper namespace="com.jay.mapper.StudentMapper">
<resultMap id="BaseColumn" type="com.jay.entity.Student">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
</resultMap>
<select id="selectByName" resultMap="BaseColumn">
select id,name,age from student where name LIKE '%'#{name}'%'
</select>
</mapper>
上面的sql語句表示的意思是通過學(xué)生名稱來模糊匹配學(xué)生
public interface StudentMapper {
/**
* @param name
* @return
*/
List<Student> selectByName(@Param("name") String name);
}
維護(hù)完映射文件和對應(yīng)的接口之后,我們還需要一個(gè)XML配置文件來對MyBatis進(jìn)行一些核心設(shè)置,包括獲取數(shù)據(jù)庫連接實(shí)例的數(shù)據(jù)源(DataSource)和決定事務(wù)作用域和控制方式的事務(wù)管理器(TransactionManager)以及SQL映射文件的位置信息等。本節(jié)所使用的配置如下:
<configuration>
<!--加載配置文件->jdbc.properties 數(shù)據(jù)庫文件 -->
<properties resource="jdbc.properties"/>
<!-- 設(shè)置一個(gè)默認(rèn)的連接環(huán)境信息 -->
<environments default="development">
<!--連接環(huán)境信息,取一個(gè)任意唯一的名字 -->
<environment id="development">
<!-- mybatis使用jdbc事務(wù)管理方式 -->
<transactionManager type="JDBC"/>
<!-- mybatis使用連接池方式來獲取連接 -->
<dataSource type="POOLED">
<!-- 配置與數(shù)據(jù)庫交互的4個(gè)必要屬性 -->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 加載映射文件-->
<mappers>
<mapper resource="xml/StudentMapper.xml"/>
</mappers>
</configuration>
到此,MyBatis所需的環(huán)境就配置好了,接下來我們將MyBatis跑起來。測試代碼如下
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() {
String resource = "chapter1/mybatis-cfg.xml";
try {
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream, "development");
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void mybatisTest() {
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = mapper.selectByName("點(diǎn)點(diǎn)");
if (studentList != null) {
System.out.println("----->"+studentList.get(0).toString());
}
sqlSession.commit();
sqlSession.close();
}
如上測試代碼,首先,我們根據(jù)配置文件得到文件流,然后通過SqlSessionFactoryBuilder工廠類構(gòu)造器得到SqlSessionFactory,再通過SqlSessionFactory工廠類得到SqlSession。然后根據(jù)SqlSession的getMapper()方法得到需要執(zhí)行的mapper。得到之后調(diào)用相應(yīng)的方法得到結(jié)果。
運(yùn)行結(jié)果如下:
使用JDBC訪問數(shù)據(jù)庫
現(xiàn)在我們使用原生的JDBC來操作數(shù)據(jù)庫,主要流程有以下幾個(gè):1. 加載數(shù)據(jù)庫驅(qū)動,2. 連接數(shù)據(jù)庫,3,通過PreparedStatement執(zhí)行sql得到ResultSet,4,對ResultSet 進(jìn)行處理。流程固定。
public class JdbcTest {
public static void main(String[] args) {
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/mybatisdemo";
String userName = "root";
String password = "admin";
Connection conn = null;
PreparedStatement statement = null;
ResultSet resultSet = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, userName, password);
String sql = "select id,name,age from student where name LIKE ?";
statement = conn.prepareStatement(sql);
statement.setString(1, "%點(diǎn)點(diǎn)%");
resultSet = statement.executeQuery();
List<Student> studentList = new ArrayList<Student>();
if (resultSet != null) {
while (resultSet.next()) {
Student student = new Student();
student.setId(resultSet.getInt("id"));
student.setName(resultSet.getString("name"));
student.setAge(resultSet.getInt("age"));
studentList.add(student);
}
}
System.out.println("----->執(zhí)行的sql={}"+sql);
System.out.println("----->resultSet={}"+studentList.get(0).toString());
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
if (statement != null) {
statement.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
代碼比較簡單,執(zhí)行結(jié)果如下:
上面的代碼的步驟比較多,但是核心步驟只有兩步,分別是執(zhí)行SQL和處理查詢結(jié)果。從開發(fā)人員的角度來說,我們只關(guān)心這兩個(gè)步驟。原生的JDBC的缺點(diǎn)主要有如下幾點(diǎn):
- 每次為了執(zhí)行某個(gè)SQL需要寫很多額外的代碼,比如加載驅(qū)動,創(chuàng)建數(shù)據(jù)庫連接,代碼冗余。
- 將SQL寫在代碼中,如果要改動SQL,就需要到代碼中進(jìn)行修改,這樣做不合適,因?yàn)楦膭恿薐ava代碼就需要重新編譯Java文件,在打包發(fā)布,同時(shí)將SQL和Java代碼混在一起,會降低代碼的可讀性,不利于維護(hù)。
- 關(guān)于執(zhí)行結(jié)果的處理,需要手動的將數(shù)據(jù)從ResultSet中取出,并設(shè)置到我們需要的對象中,如果屬性過多,用這種方式處理會非常繁瑣。
- 每次都要手動管理數(shù)據(jù)庫連接,使用好之后又要手動關(guān)閉。
MyBatis VS JDBC
首先我們來看看MyBatis訪問數(shù)據(jù)庫的過程
- 讀取配置文件
- 創(chuàng)建SqlSessionFactoryBuilder對象
- 通過SqlSessionFactoryBuilder創(chuàng)建SqlSessionFactory對象
- 通過SqlSessionFactory創(chuàng)建SqlSession
- 為Dao 接口生成代理類
- 調(diào)用接口方法訪問數(shù)據(jù)庫
需要注意的是,在MyBatis中SqlSessionFactoryBuilder 和 SqlSessionFactory 以及 SqlSession 等對象的作用域和生命周期是不一樣的。
SqlSessionFactoryBuilder
這個(gè)類可以被實(shí)例化,使用和丟棄,一旦創(chuàng)建了SqlSessionFactory,就不需要它了,所以,SqlSessionFactoryBuilder實(shí)例的最佳作用域是方法作用域(也就是局部方法變量)
SqlSessionFactory
SqlSessionFactory一旦被創(chuàng)建就應(yīng)該在應(yīng)用的運(yùn)行期間一直存在,沒有任何理由丟棄它或重新創(chuàng)建另外一個(gè)實(shí)例,使用SqlSessionFactory的最佳實(shí)踐食雜應(yīng)用運(yùn)行期間不要重復(fù)創(chuàng)建多起,多次重建SqlSessionFactory被視為一種代碼”壞味道“。因此SqlSessionFactory的最佳作用域是應(yīng)用作用域,有很多方法可以做到,最簡單的就是使用單例模式或者靜態(tài)單例模式。
SqlSession
每個(gè)線程都應(yīng)該有它自己的SqlSession實(shí)例,SqlSession的實(shí)例不是線程安全的,因此是不能被共享的,所有它的最佳的作用域是請求或方法作用域,絕對不能講SqlSession實(shí)例的引用放在了一個(gè)類的靜態(tài)域,比如Servlet框架中的HttpSession中。
映射器實(shí)例
映射器是一些由你創(chuàng)建的,綁定你映射的語句的接口,映射器接口的實(shí)例是從SqlSession中獲得的,因此從技術(shù)層面講,任何映射器實(shí)例的最大作用域是請求他們的的SqlSession相同的,盡管如此,映射器實(shí)例的最佳作用域是方法作用域。也就是說,映射器實(shí)例應(yīng)該在調(diào)用它們的方法中被請求,用過之后即可丟棄。并不需要顯示地關(guān)閉映射器實(shí)例。
總的來說,MyBatis在易用性上要比JDBC好太多,不過JDBC與MyBatis的目標(biāo)不同,JDBC是作為一種基礎(chǔ)服務(wù),而MyBatis則是構(gòu)建在基礎(chǔ)服務(wù)之上的框架。所以JDBC的流程繁瑣,從JDBC的角度來說,這里的每一個(gè)步驟對于完成數(shù)據(jù)訪問請求來說都是必須的。
使用Spring JDBC訪問數(shù)據(jù)庫
Spring JDBC是在JDBC上面做的一層比較薄的封裝,主要是為了解決直接使用JDBC的一些痛點(diǎn),易用性得到了不少的提升。
引入的依賴
<properties>
<spring.version>4.3.17.RELEASE</spring.version>
</properties>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
在使用Spring JDBC之前我們需要做一些配置,我們新建一個(gè)配置文件,命名為application.xml,在此配置文件中,我們配置了
數(shù)據(jù)庫的連接信息dataSource,注冊了JdbcTemplate實(shí)例。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder location="jdbc.properties"/>
<bean id="dataSource" class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<!-- 配置與數(shù)據(jù)庫交互的4個(gè)必要屬性 -->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
配置完成之后,我們可以寫一個(gè)測試類來測試一下。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:chapter1/application.xml")
public class SpringJdbcTest {
@Autowired
private JdbcTemplate jdbcTemplate;
@Test
public void testSpringJdbc() {
String sql = "select id,name,age from student where name LIKE ?";
List<Student> studentList = jdbcTemplate.query(sql, new Object[]{"%點(diǎn)點(diǎn)%"}, new BeanPropertyRowMapper<Student>(Student.class));
System.out.println("----->執(zhí)行的sql={}"+sql);
System.out.println("----->查詢結(jié)果={}"+studentList.get(0).toString());
}
}
運(yùn)行結(jié)果
從上面的測試代碼我們可以看出,相對于原生JDBC,Spring JDBC 易用性大大提升,注入jdbcTemplate之后,我們就可以通過jdbcTemplate來操作,只關(guān)注sql的執(zhí)行以及結(jié)果的處理即可。代碼簡化了很多。但是SQL語句仍然寫在代碼中。
使用Hibernate 訪問數(shù)據(jù)庫
本節(jié)會像之前的章節(jié)一樣,我會先寫代碼進(jìn)行演示,然后在對比Hibernate 和MyBatis的區(qū)別。
Hibernate 訪問數(shù)據(jù)庫的過程演示
首先,在POM文件中添加所需依賴
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.2.Final</version>
</dependency>
接著進(jìn)行環(huán)境配置,主要是關(guān)于數(shù)據(jù)庫方面的配置。
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mybatisdemo</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">admin</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="hibernate.show_sql">true</property>
<mapping resource="chapter1/xml/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
環(huán)境配置完成之后,我們接著編寫映射文件,將表字段與實(shí)體類的屬性關(guān)聯(lián)起來。如下Student.hbm.xml
<hibernate-mapping package="com.jay.entity">
<class table="student" name="Student">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="name" column="name"/>
<property name="age" column="age"/>
<property name="classId" column="class_id"/>
</class>
</hibernate-mapping>
所有配置完成之后,我們就可以開始編寫測試代碼進(jìn)行測試:
public class HibernateTest {
private SessionFactory sessionFactory;
@Before
public void init() {
Configuration configuration = new Configuration();
configuration.configure("chapter1/hibernate.cfg.xml");
sessionFactory = configuration.buildSessionFactory();
}
@After
public void destroy() {
sessionFactory.close();
}
@Test
public void testORM() {
System.out.println("--------------ORM Query-------------");
Session session = null;
try {
session = sessionFactory.openSession();
int id = 1;
Student student = session.get(Student.class, id);
System.out.println("ORM Query Result:");
System.out.println(student.toString());
System.out.println();
} finally {
if (Objects.nonNull(session)) {
session.close();
}
}
}
@Test
public void testHQL() {
System.out.println("--------------HQL Query-----------");
Session session = null;
try {
session = sessionFactory.openSession();
String hql = "FROM Student WHERE name=:name";
Query query = session.createQuery(hql);
query.setParameter("name", "點(diǎn)點(diǎn)");
List<Student> studentList = query.list();
System.out.println("HQL Query Result:");
studentList.forEach(System.out::println);
System.out.println();
} finally {
if (Objects.nonNull(session)) {
session.close();
}
}
}
@Test
public void testJpaCriteria() {
System.out.println("-------------JPA Criteria-------------");
Session session = null;
try {
session = sessionFactory.openSession();
CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder();
CriteriaQuery<Student> criteriaQuery = criteriaBuilder.createQuery(Student.class);
// 定義FROM子句
Root<Student> student = criteriaQuery.from(Student.class);
// 構(gòu)建查詢條件
Predicate equal = criteriaBuilder.equal(student.get("name"), "點(diǎn)點(diǎn)");
// 通過具有語義化的方法構(gòu)建SQL,等價(jià)于SELECT ... FROM student WHERE ...
criteriaQuery.select(student).where(equal);
Query<Student> query = session.createQuery(criteriaQuery);
List<Student> studentList = query.getResultList();
System.out.println("JPA Criteria Query Result:");
studentList.forEach(System.out::println);
} finally {
if (Objects.nonNull(session)) {
session.close();
}
}
}
}
如上代碼清單所示,我編寫了三個(gè)測試用例,第一個(gè)直接使用Hibernate生成SQL的功能,如果查詢比較簡單可以采用此種方式,生成的SQL是
select student0_.id as id1_0_0_, student0_.name as name2_0_0_, student0_.age as age3_0_0_, student0_.class_id as class_id4_0_0_ from student student0_ where student0_.id=?
- 1
第二個(gè)測試用例,我編寫了一條HQL語句,并通過Query來設(shè)置參數(shù),同樣Hibernate在運(yùn)行時(shí)會將HQL轉(zhuǎn)化成對應(yīng)的SQL,轉(zhuǎn)化后的SQL如下:
select student0_.id as id1_0_, student0_.name as name2_0_, student0_.age as age3_0_, student0_.class_id as class_id4_0_ from student student0_ where student0_.name=?
- 1
第三個(gè)測試用例,我們使用JPA Criteria 進(jìn)行查詢,JPA Criteria 具有類型安全,面向?qū)ο蠛驼Z義化的特點(diǎn),使用JPA Criteria,我們可以用寫Java 代碼的方式進(jìn)行數(shù)據(jù)庫操作,無需手寫SQL,第三個(gè)用例和第二個(gè)用例進(jìn)行的是同樣的查詢,所以生成的SQL區(qū)別不大。
MyBatis VS Hibernate
至此,我們已經(jīng)對MyBatis和Hibernate訪問數(shù)據(jù)庫的過程都做了一次演示,下面我們來對比下MyBatis和Hibernate
- MyBatis 需要使用者自行維護(hù)SQL,靈活性高,方便對sql進(jìn)行優(yōu)化,Hibernate 可以自動生成SQL,使用成本小。
- MyBatis 適合于需求變動頻繁,業(yè)務(wù)量的系統(tǒng),Hibernate 更加適合于變動比較小的系統(tǒng),比如OA系統(tǒng)
使用Spring Data JPA 訪問數(shù)據(jù)庫
首先引入依賴
<properties>
<spring.version>4.3.17.RELEASE</spring.version>
</properties>
<!--///Spring JPA-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.12</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.12</version>
</dependency>
接著添加配置文件application-jpa.xml,主要是配置數(shù)據(jù)庫連接信息,以及事務(wù)相關(guān)的信息
<!--啟用注解配置和包掃描-->
<context:annotation-config/>
<context:component-scan base-package="com.jay"/>
<!--創(chuàng)建Spring Data JPA實(shí)例對象-->
<jpa:repositories base-package="com.jay.chapter1"/>
<context:property-placeholder location="jdbc.properties"/>
<bean id="dataSource"
class="org.apache.ibatis.datasource.pooled.PooledDataSource">
<!-- 配置與數(shù)據(jù)庫交互的4個(gè)必要屬性 -->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan" value="com.jay.entity"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="generateDdl" value="true"/>
<property name="showSql" value="true"/>
</bean>
</property>
</bean>
<!--事務(wù)管理器-->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!--事務(wù)管理-->
<tx:advice id="transactionAdvice"
transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="daoPointCut" expression="execution(* com.jay.chapter1.mapper.*.*(..))"/>
<aop:advisor advice-ref="transactionAdvice" pointcut-ref="daoPointCut"/>
</aop:config>
配置文件添加完成之后,接著我們編寫一個(gè)接口繼承CrudRepository接口,使其具備基本的增刪改查功能。
public interface JpaStudentDao extends CrudRepository<JpaStudent,Integer>{
/**
* @param name
* @return
*/
List<JpaStudent> getByNameLike(String name);
}
DAO接口添加完成之后,接著我們添加一個(gè)測試類進(jìn)行測試。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:chapter1/application-jpa.xml")
public class JPATest {
@Autowired
JpaStudentDao jpaStudentDao;
@Before
public void init() {
JpaStudent jpaStudent = new JpaStudent("張三", 12, "121");
jpaStudentDao.save(jpaStudent);
}
@Test
public void testCrudRepostitory() {
List<JpaStudent> jpaStudents = jpaStudentDao.getByNameLike("張三");
jpaStudents.forEach(System.out::println);
System.out.println();
}
}
如上測試類所示,我先使用了JPA自帶的save方法向數(shù)據(jù)庫中插入了一條數(shù)據(jù),接著自定義了一個(gè)查詢方法。JPA中查詢方法可以由我們聲明的命名查詢生成,也可以由方法名解析
方法名以find…By, read…By, query…By, count…By和 get…By做開頭。在By之前可以添加Distinct表示查找不重復(fù)數(shù)據(jù)。By之后是真正的查詢條件。
可以查詢某個(gè)屬性,也可以使用條件進(jìn)行比較復(fù)雜的查詢,例如Between, LessThan, GreaterThan, Like,And,Or等。
字符串屬性后面可以跟IgnoreCase表示不區(qū)分大小寫,也可以后跟AllIgnoreCase表示所有屬性都不區(qū)分大小寫。
可以使用OrderBy對結(jié)果進(jìn)行升序或降序排序。
可以查詢屬性的屬性,直接將幾個(gè)屬性連著寫即可,如果可能出現(xiàn)歧義屬性,可以使用下劃線分隔多個(gè)屬性。
運(yùn)行結(jié)果如下:
MyBatis VS JPA
通過上面的實(shí)例,我們可以了解到JPA的使用,JPA類似于Hibernate都可以自動生成SQL,不同之處是,JPA還可以根據(jù)方法名來解析生成sql。MyBatis 還是需要使用者自行維護(hù)sql。
總結(jié)
本篇文章對MyBatis 是什么,為什么使用,以及與其他ORM框架進(jìn)行了對比。
參考文獻(xiàn)
MyBatis官方文檔
MyBatis 源碼分析系列文章導(dǎo)讀
《MyBatis 技術(shù)內(nèi)幕》- 徐郡明
Spring Data JPA 介紹和使用
源代碼
https://github.com/XWxiaowei/MyBatisLearn/tree/master/mybatisDemo
作者:碼農(nóng)飛哥
微信公眾號:碼農(nóng)飛哥