本課程視頻教程地址爲:http://edu.51cto.com/course/14674.html
1、爲什麼要學習MyBatis
1.1、傳統jdbc回顧
package cn.org.kingdom.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.junit.Test;
public class TestJdbc {
@Test
public void test() throws ClassNotFoundException, SQLException {
//加載驅動
Class.forName("org.gjt.mm.mysql.Driver");
//獲取連接
String url = "jdbc:mysql://localhost:3306/mytest?useUnicode=true&characterEncoding=utf8";
String username = "root";
String pwd = "root";
Connection conn = DriverManager.getConnection(url, username, pwd);
//執行sql
String sql = "select * from user where userid = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
//結果迭代
while(rs.next()) {
System.out.println(rs.getInt("userid"));
System.out.println(rs.getString("username"));
}
//釋放資源
rs.close();
pstmt.close();
conn.close();
}
}
1.2、傳統JDBC代碼存在的問題
1.數據庫連接頻繁的創建和關閉,缺點浪費數據庫的資源,影響操作效率
解決方式:採用了連接池機制來解決
2.sql語句是硬編碼,如果需求變更需要修改sql,就需要修改java代碼,需要重新編譯,系統不易維護。
解決方式:將sql語句統一配置在文件中,修改sql不需要修改java代碼
3.通過preparedStatement向佔位符設置參數,存在硬編碼( 參數位置,參數)問題。系統不易維護
解決方式:將sql中的佔位符及對應的參數類型配置在配置文件中,能夠自動輸入映射
4.遍歷查詢結果集存在硬編碼(列名)
自動進行sql查詢結果向java對象的映射(輸出映射)
2、MyBatis
2.1、Mybatis簡介
MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,並且改名爲MyBatis,實質上Mybatis對ibatis進行一些改進。 目前mybatis在github上託管。git(分佈式版本控制,當前比較流程)
MyBatis是一個優秀的持久層框架,它對jdbc的操作數據庫的過程進行封裝,使開發者只需要關注 SQL 本身,而不需要花費精力去處理例如註冊驅動、創建connection、創建statement、手動設置參數、結果集檢索等jdbc繁雜的過程代碼。
Mybatis通過xml或註解的方式將要執行的各種statement(statement、preparedStatemnt、CallableStatement)配置起來,並通過java對象和statement中的sql進行映射生成最終執行的sql語句,最後由mybatis框架執行sql並將結果映射成java對象並返回。
2.2、MyBatis架構
3、MyBatis快速入門
3.1、建表
CREATE TABLE tb_user (
userid number(4) NOT NULL primary key,
user_name varchar2(100),
pwd varchar2(100),
age number(3) ,
sex varchar(2),
birthday date
);
create sequence seq_user;
--插入測試數據
insert into tb_user(userid,user_name,pwd,age,sex,birthday)
values(seq_user.nextval,'張三','123456',10,'男',sysdate);
insert into tb_user(userid,user_name,pwd,age,sex,birthday)
values(seq_user.nextval,'李四','123456',10,'男',sysdate);
insert into tb_user(userid,user_name,pwd,age,sex,birthday)
values(seq_user.nextval,'王五','123456',10,'男',sysdate);
insert into tb_user(userid,user_name,pwd,age,sex,birthday)
values(seq_user.nextval,'趙六','123456',10,'男',sysdate);
select * from tb_user;
3.2、添加jar包
1、mybatis-3.2.3.jar(MyBatis的核心jar包)
2、mysql-connector-java-5.0.4-bin.jar(mysql的jar包)或者 classes12.jar(Oracle的jar包)
3、log4j-1.2.17.jar、slf4j-api-1.7.5.jar、slf4j-log4j12-1.7.5.jar(日誌包)
3.3、全局配置文件
在src目錄建立一個xml文件,一般情況下命令爲:mybatis-config.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 default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:njwb"/>
<property name="username" value="scott"/>
<property name="password" value="tiger"/>
</dataSource>
</environment>
</environments>
</configuration>
3.4、添加日誌的配置文件
src下目錄下建立log4j.properties 文件
log4j.rootLogger=debug,stdout,logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=jbit.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout\t
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %F %p %m%n
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
3.5、測試連接
package cn.org.kingdom.test;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
public class MyBatisTest {
@Test
public void test() throws IOException{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
System.out.println("sqlSessionFactory:"+sqlSessionFactory);
SqlSession sqlsession = sqlSessionFactory.openSession();
System.out.println("sqlsession:"+sqlsession);
Connection conn = sqlsession.getConnection();
System.out.println("conn:"+conn);
}
}
3.6、運行結果
DEBUG - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
sqlSessionFactory:org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@42bf7a35
sqlsession:org.apache.ibatis.session.defaults.DefaultSqlSession@73bb9f3f
DEBUG - Opening JDBC Connection
DEBUG - Created connection 404536294.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@181cbbe6]
conn:oracle.jdbc.driver.T4CConnection@181cbbe6
3.7、創建一個實體類(User)
package cn.org.kingdom.entity;
import java.io.Serializable;
import java.sql.Date;
public class User implements Serializable {
private int userid;
private String userName;
private String pwd;
private int age;
private String sex;
private Date birthday;
public User() {
super();
}
public User(String userName, String pwd, int age, String sex, Date birthday) {
super();
this.userName = userName;
this.pwd = pwd;
this.age = age;
this.sex = sex;
this.birthday = birthday;
}
public User(int userid, String userName, String pwd, int age, String sex,
Date birthday) {
super();
this.userid = userid;
this.userName = userName;
this.pwd = pwd;
this.age = age;
this.sex = sex;
this.birthday = birthday;
}
public int getUserid() {
return userid;
}
public void setUserid(int userid) {
this.userid = userid;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
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;
}
@Override
public String toString() {
return "User [userid=" + userid + ", userName=" + userName + ", pwd="
+ pwd + ", age=" + age + ", sex=" + sex + ", birthday="
+ birthday + "]";
}
}
3.8、創建Mapper映射文件
在src目錄下建立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="cn.org.kingdom.entity.User">
<select id="findUserById" resultType="User">
select * from tb_user where userid = #{id}
</select>
</mapper>
此時還需要將此文件關聯到全局配置文件之中
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:njwb"/>
<property name="username" value="scott"/>
<property name="password" value="tiger"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="UserMapper.xml"/>
</mappers>
</configuration>
3.9、編寫測試文件
@Test
public void testHello() throws IOException{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
System.out.println("sqlSessionFactory:"+sqlSessionFactory);
SqlSession sqlsession = sqlSessionFactory.openSession();
User user = sqlsession.selectOne(User.class.getName()+".findUserById",1);
System.out.println(user);
}
3.10、運行結果
DEBUG - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
sqlSessionFactory:org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@42bf7a35
DEBUG - Opening JDBC Connection
DEBUG - Created connection 1476491893.
DEBUG - Setting autocommit to false on JDBC Connection [oracle.jdbc.driver.T4CConnection@58017a75]
DEBUG - ooo Using Connection [oracle.jdbc.driver.T4CConnection@58017a75]
DEBUG - ==> Preparing: select * from tb_user where userid = ?
DEBUG - ==> Parameters: 1(Integer)
DEBUG - <== Total: 1
User [userid=1, userName=null, pwd=123456, age=10, sex=男, birthday=2018-08-07]
此時我們發現,userName字段的值並沒有查詢出來,出現這個問題的原因主要在於我們的數據庫字段和實體類的映射不一致造成的,這裏我先給出一種解決方式,修改UserMappper.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="cn.org.kingdom.entity.User">
<select id="findUserById" resultType="cn.org.kingdom.entity.User">
select userid,user_name as userName,pwd,age,sex,birthday from tb_user where userid = #{userid}
</select>
</mapper>
重新測試,運行ok
3.11、MyBatis入門總結
1.創建配置文件:mybatis-config.xml,mapper.xml,log4j.properties
2.構建SqlSessionFactory對象
3.創建SqlSession對象
4.通過sqlsession去執行數據庫操作
5.提交事務
6.關閉sqlsession