mybatis入門之原始dao開發與mapper代理開發
前言:
相信很多朋友和筆者一樣,在開始學習mybatis的時候,看完一遍mybatis相關知識,並沒有記住多少,理解深刻就更談不上,渴求一個簡單的demo來測試一下自己到底瞭解多少,掌握多少以及mybatis到底是怎麼玩的,那麼機會來了,筆者將自己之前學習過程中練習的demo重新整理了下,並記錄總結。
在練習這兩種方式之前我們要清楚明白為什麼要使用mybatis?先看看原生的資料庫連線操作:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class TraditionalJdbcConn { public static void main(String[] args) { String driver = "com.mysql.jdbc.Driver"; String url = "jdbc:mysql://localhost:3306/name"; String user = "root"; String password = "root"; Connection conn = null; PreparedStatement pstm = null; ResultSet rs = null; try { Class.forName(driver);// 載入資料庫驅動 conn = DriverManager.getConnection(url, user, password);// 得到資料庫連線 String sql = "select *from new1 where id=?"; pstm = conn.prepareStatement(sql);// 得到預編譯物件 pstm.setInt(1, 19); rs = pstm.executeQuery();// 得到結果集 while (rs.next()) { System.out.println(rs.getInt(1) + "\t" + rs.getString(2)); } } catch (Exception e) { System.out.println(e.getMessage()); } finally { try { if (rs != null) rs.close(); if (pstm != null) pstm.close(); if (conn != null) conn.close(); } catch (SQLException e) { System.out.println(e.getMessage()); } } } }
上面是傳統的Jdbc庫連線資料庫的基本步驟,可以看出上述程式碼存在著一下幾個問題:
-
資料庫連線物件頻繁的建立和銷燬,存在很大開銷。(解決:資料庫連線池)
-
sql語句存在硬編碼問題,後期維護和升級存在著複雜性。(解決:把語句單獨寫到一個配置檔案中,按照一定規則讀取)
-
PreparedStatement設定引數存在著硬編碼問題。(解決:配置檔案中寫)(ps:這裡提醒一點,使用statement物件和preparedStatement物件的區別是preparedStatement是預編譯物件,對於同一條sql語句,第二次的執行效率遠高於第一次,但是如果一條sql語句就執行一次,那麼statement執行的速率更快,當然對於同一條語句的多次執行可以使用preparedStatement+批處理,其速度是遠超前兩者的)
-
結果集resultSet遍歷資料的時候存在硬編碼問題。(直接將資料對映成Java物件)
知道了為什麼要用mybatis後,就直接進入正題,關於原始dao開發和mapper代理開發:
專案結構:(包括原始dao開發和mapper代理開發)
環境準備:
JAR包下載:
POJO類:
public class User { private int id; private String content; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } @Override public String toString() { return "User [id=" + id + ", content=" + content + "]"; } public User(int id, String content) { super(); this.id = id; this.content = content; } public User() { super(); // TODO Auto-generated constructor stub } }
Log4j.properties配置檔案:(關於log4j的配置,詳情參見log4j日誌配置)
log4j.rootLogger=debug,console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d %-2p [%c.%M()] - %m%n
mybatis配置檔案:
<?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>
<!-- 載入屬性檔案db.properties -->
<properties resource="db.properties"></properties>
<!-- 和spring整合後,environments將被廢除 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC事務管理 ,事務控制由mybatis管理-->
<transactionManager type="JDBC"></transactionManager>
<!-- 資料庫連線池 ,由mybatis管理-->
<dataSource type="POOLED">
<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="sqlmap/user.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
db.properties檔案:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/name
jdbc.username=root
jdbc.password=root
原始dao開發:
開發人員需要編寫介面,介面實現類,以及相應的XML配置檔案。具體如下:
介面:
import h.l.pojo.User;
public interface UserDao {
public User findUserById(int id) throws Exception;// 根據id查詢查詢使用者
public void insertUser(User user) throws Exception;// 新增使用者
public void deleteUser(int id) throws Exception;// 刪除使用者
public void updateUser(User user) throws Exception;// 更新使用者
}
介面實現類:(ps:除了查詢,其他的操作都要commit)
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import h.l.pojo.User;
public class UserDaoImpl implements UserDao {
// 向dao實現類中注入SqlSessionFactory
// 這裡通過建構函式向實現類中注入SqlSessionFactory
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
// 因為SqlSession是執行緒不安全的,所有SqlSession物件應該在方法中建立,不能在類中建立
// 根據id查詢使用者
@Override
public User findUserById(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById", id);
// 釋放資源
sqlSession.close();
return user;
}
// 新增使用者
@Override
public void insertUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser", user);
sqlSession.commit();
sqlSession.close();
}
// 刪除使用者
@Override
public void deleteUser(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("test.deleteUser", id);
sqlSession.commit();
sqlSession.close();
}
// 更新使用者
@Override
public void updateUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.update("test.updateUser", user);
sqlSession.commit();
sqlSession.close();
}
}
User.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="test">
<select id="findUserById" parameterType="int"
resultType="h.l.pojo.User">
select * from new1 where id=#{id}
</select>
<insert id="insertUser" parameterType="h.l.pojo.User">
insert into new1(id,content) values(#{id},#{content})
</insert>
<delete id="deleteUser" parameterType="int">
delete from new1 where
id=#{id}
</delete>
<update id="updateUser" parameterType="h.l.pojo.User">
update new1 set content=#{content} where id=#{id}
</update>
</mapper>
測試類:
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import h.l.pojo.User;
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
// 建立sqlSessionFactory
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() throws Exception {
// 建立UserDao
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
// 呼叫UserDao方法
User user = userDao.findUserById(5);
System.out.println(user);
}
@Test
public void testInsertUser() throws Exception {
// 建立UserDao
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
// 建立一個物件
User user = new User();
user.setContent("5000");
// 呼叫UserDao方法
userDao.insertUser(user);
}
@Test
public void testDeleteUser() throws Exception {
// 建立UserDao
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
// 呼叫UserDao方法
userDao.deleteUser(18);
}
@Test
public void testUpdateUser() throws Exception {
// 建立UserDao
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User user = new User();
user.setContent("江西上饒");
user.setId(19);
userDao.updateUser(user);
}
}
Mapper代理開發:
開發人員只需要編寫介面和XML檔案即可,mybatis可以自動生成mapper介面實現類代理物件。但是介面的編寫需要按照一定的規則:
- 在mapper.xml中namespace等於mapper介面地址。
- mapper.java介面中的方法名和mapper.xml中statement的id一致。
- mapper.java介面中的方法輸入引數型別和mapper.xml中statement的parameterType指定的型別一致。
- mapper.java介面中的方法返回值型別和mapper.xml中statement的resultType指定的型別一致。
mapper介面:
import h.l.pojo.User;
public interface UserMapper {
public User findUserById(int id) throws Exception;// 根據id查詢使用者
}
XXXMapper.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="h.l.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="h.l.pojo.User">
select *from new1 where id=#{id}
</select>
</mapper>
測試檔案:
import java.io.InputStream;
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.Before;
import org.junit.Test;
import h.l.pojo.User;
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(19);
System.out.println(user);
}
}
上述就是原始到開發和mapper代理開發的簡單入門,通過上面方法的比較,我們可以發現,程式設計師可以通過mybatis拜託硬編碼的問題,使得後期的維護能夠更加方便。關於mybatis的其他知識也會陸陸續續總結,請多關照~
注:以上文章僅是個人學習過程總結,若有不當之處,望不吝賜教。