中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

模擬Mybatis的實現方法

發布時間:2020-08-25 13:24:36 來源:腳本之家 閱讀:194 作者:動力節點 欄目:編程語言

所需要用到的其他工具或技術:

項目管理工具 : Maven

測試運行工具 : Junit

數據庫 : Derby

XML操作工具:Dom4j

繼續不廢話

Maven Dependencies:

<dependency> 
 <groupId>junit</groupId> 
 <artifactId>junit</artifactId> 
 <version>4.9</version> 
 <scope>test</scope> 
 </dependency> 
 <dependency> 
 <groupId>org.apache.derby</groupId> 
 <artifactId>derby</artifactId> 
 <version>10.10.2.0</version> 
 </dependency> 
 <dependency> 
 <groupId>org.apache.derby</groupId> 
 <artifactId>derbyclient</artifactId> 
 <version>10.10.2.0</version> 
 </dependency> 
 <dependency> 
 <groupId>dom4j</groupId> 
 <artifactId>dom4j</artifactId> 
 <version>1.6.1</version> 
 </dependency> 

SQL 建表及數據插入(如果在第一節中作過,可以跳過此步):

CREATE TABLE USER_TEST_TB( 
ID INT PRIMARY KEY, 
USERNAME VARCHAR(20) NOT NULL, 
PASSWORD VARCHAR(20) NOT NULL, 
NICKNAME VARCHAR(20) NOT NULL 
); 
INSERT INTO USER_TEST_TB VALUES(1,'1st','111','Jack'); 
INSERT INTO USER_TEST_TB VALUES(2,'2nd','222','Rose'); 
INSERT INTO USER_TEST_TB VALUES(3,'3rd','333','Will'); 

Mybatis配置文件 src/main/resource源目錄下

test-mybatis-configuration.xml
<?xml version="1.0" encoding="UTF-8" ?> 
<configuration> 
 <properties> 
 <property name="driver" value="org.apache.derby.jdbc.ClientDriver" /> 
 <property name="url" 
 value="jdbc:derby://localhost:1527/bjpowernode;create=true" /> 
 </properties> 
 <environments default="development"> 
 <environment id="development"> 
 <transactionManager type="JDBC" /> 
 <dataSource type="POOLED"> 
 <property name="driver" value="${driver}" /> 
 <property name="url" value="${url}" /> 
 </dataSource> 
 </environment> 
 </environments> 
 <mappers> 
 <mapper class="com.bjpowernode.practice.annotation.UserMapper" /> 
 <mapper resource="com/bjpowernode/practice/xml/UserMapper.xml" /> 
 </mappers> 
</configuration> 

User.java對象類(src/main/java/com/bjpowernode/practice目錄下)

package com.bjpowernode.practice; 
/** 
 * 
 * User Model 
 * 
 */ 
public class User 
{ 
 private String id; 
 private String username; 
 private String password; 
 private String nickname; 
 public String getId() 
 { 
 return id; 
 } 
 public void setId(String id) 
 { 
 this.id = id; 
 } 
 public String getUsername() 
 { 
 return username; 
 } 
 public void setUsername(String username) 
 { 
 this.username = username; 
 } 
 public String getPassword() 
 { 
 return password; 
 } 
 public void setPassword(String password) 
 { 
 this.password = password; 
 } 
 public String getNickname() 
 { 
 return nickname; 
 } 
 public void setNickname(String nickname) 
 { 
 this.nickname = nickname; 
 } 
} 

Select.java 注解類(src/main/java/com/bjpowernode/practice/annotation目錄下)

package com.bjpowernode.practice.annotation; 
import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 
/** 標注此注解只能用在方法上 */ 
@Target(ElementType.METHOD) 
/** 標注此注解生命周期是在Runtime運行時 */ 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Select 
{ 
 String value(); 
} 

UserMapper.java 基于Annotation的配置類(src/main/java/com/bjpowernode/practice/annotation目錄下)

package com.bjpowernode.practice.annotation; 
import com.bjpowernode.practice.User; 
import java.util.List; 
public interface UserMapper 
{ 
 @Select("select * from USER_TEST_TB") 
 public List<User> getUser(); 
} 

Mapper.java 對象類(src/main/java/com/bjpowernode/practice/simulation目錄下)

package com.bjpowernode.practice.simulation; 
/** 
 * 
 * 存儲查詢結果對象 
 * 
 */ 
public class Mapper 
{ 
 /** 
 * 返回類型 
 */ 
 private String resultType; 
 /** 
 * 查詢SQL 
 */ 
 private String querySql; 
 public String getResultType() 
 { 
 return resultType; 
 } 
 public void setResultType(String resultType) 
 { 
 this.resultType = resultType; 
 } 
 public String getQuerySql() 
 { 
 return querySql; 
 } 
 public void setQuerySql(String querySql) 
 { 
 this.querySql = querySql; 
 } 
} 

SQLSelectProxy.java AOP動態代理類(src/main/java/com/bjpowernode/practice/simulation目錄下)

package com.bjpowernode.practice.simulation; 
import com.bjpowernode.practice.annotation.Select; 
import java.lang.reflect.InvocationHandler; 
import java.lang.reflect.Method; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.util.List; 
public class SQLSelectProxy implements InvocationHandler 
{ 
 @Override 
 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
 { 
 /** 
 * 獲得Mapper方法上的Select注解,以此來取得注解中的SQL語句 
 */ 
 Select select = method.getAnnotation(Select.class); 
 if (!method.isAnnotationPresent(Select.class)) 
 { 
 throw new RuntimeException("缺少@Select注解!"); 
 } 
 PreparedStatement pstmt = null; 
 ResultSet rs = null; 
 Object obj = null; 
 try 
 { 
 pstmt = SqlSessionImpl.connection.prepareStatement(select.value()); 
 rs = pstmt.executeQuery(); 
 /** 
 * 獲得Method的返回對象類型,此處應當作判斷處理,當List的時候,當只返回一個對象的時候. 
 * 為了簡單實現功能并與第一節中測試文件不發生沖突起見,此處當作List處理 
 */ 
 String returnType = method.getGenericReturnType().toString();//java.util.List<com.bjpowernode.practice.User> 
 if (returnType.startsWith(List.class.getName())) 
 { 
 //去掉我們不需要的字符串,得到List中的類型 
 returnType = returnType.replace(List.class.getName(), "").replace("<", "").replace(">", ""); 
 } 
 else 
 { 
 // 返回其他對象應當作其他處理,此處為了簡單起見,暫不處理 
 } 
 obj = SqlSessionImpl.executeQuery(rs, returnType); 
 } 
 finally 
 { 
 if (rs != null && !rs.isClosed()) 
 { 
 rs.close(); 
 } 
 if (pstmt != null && !pstmt.isClosed()) 
 { 
 pstmt.close(); 
 } 
 } 
 return obj; 
 } 
} 

SqlSession.java Mybatis模擬接口(src/main/java/com/bjpowernode/practice/simulation目錄下)

package com.bjpowernode.practice.simulation; 
import java.util.List; 
/** 
 * 
 * 模擬SqlSession 
 * 
 */ 
public interface SqlSession 
{ 
 public <T> T getMapper(Class<T> clazz); 
 public <E> List<E> selectList(String query) throws Exception; 
} 

SqlSessionFactory.java Mybatis模擬類(src/main/java/com/bjpowernode/practice/simulation目錄下)

package com.bjpowernode.practice.simulation; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import org.dom4j.Document; 
import org.dom4j.DocumentException; 
import org.dom4j.Element; 
import org.dom4j.io.SAXReader; 
/** 
 * 
 * 模擬SqlSessionFactory 
 * 
 */ 
public class SqlSessionFactory 
{ 
 private InputStream configuration; 
 public SqlSession openSession() throws IOException 
 { 
 SqlSessionImpl session = new SqlSessionImpl(); 
 loadConfigurations(session); 
 return session; 
 } 
 /** 
 * 
 * 通過Dom4j讀取配置文件信息 
 * 
 * @param session 
 * @throws IOException 
 */ 
 private void loadConfigurations(final SqlSessionImpl session) throws IOException 
 { 
 try 
 { 
 Document document = new SAXReader().read(configuration); 
 Element root = document.getRootElement(); 
 List<Element> mappers = root.element("mappers").elements("mapper"); 
 for (Element mapper : mappers) 
 { 
 if (mapper.attribute("resource") != null) 
 { 
  session.setXmlSQLs(loadXMLConfiguration(mapper.attribute("resource").getText())); 
 } 
 if (mapper.attribute("class") != null) 
 { 
 } 
 } 
 } 
 catch (Exception e) 
 { 
 System.out.println("讀取配置文件錯誤!"); 
 } 
 finally 
 { 
 configuration.close(); 
 } 
 } 
 /** 
 * 
 * 通過dom4j讀取Mapper.xml中的信息 
 * 
 * @param resource 
 * @return 
 * @throws DocumentException 
 * @throws IOException 
 */ 
 private Map<String, Mapper> loadXMLConfiguration(String resource) throws DocumentException, IOException 
 { 
 Map<String, Mapper> map = new HashMap<String, Mapper>(); 
 InputStream is = null; 
 try 
 { 
 is = this.getClass().getClassLoader().getResourceAsStream(resource); 
 Document document = new SAXReader().read(is); 
 Element root = document.getRootElement(); 
 if (root.getName().equalsIgnoreCase("mapper")) 
 { 
 String namespace = root.attribute("namespace").getText(); 
 for (Element select : (List<Element>) root.elements("select")) 
 { 
  Mapper mapperModel = new Mapper(); 
  mapperModel.setResultType(select.attribute("resultType").getText()); 
  mapperModel.setQuerySql(select.getText().trim()); 
  map.put(namespace + "." + select.attribute("id").getText(), mapperModel); 
 } 
 } 
 } 
 finally 
 { 
 is.close(); 
 } 
 return map; 
 } 
 public InputStream getConfiguration() 
 { 
 return configuration; 
 } 
 public void setConfiguration(InputStream configuration) 
 { 
 this.configuration = configuration; 
 } 
} 

SqlSessionFactoryBuilder.java Mybatis模擬類(src/main/java/com/bjpowernode/practice/simulation目錄下)

package com.bjpowernode.practice.simulation; 
import java.io.InputStream; 
/** 
 * 
 * 模擬SqlSessionFactoryBuilder 
 * 
 */ 
public class SqlSessionFactoryBuilder 
{ 
 public SqlSessionFactory build(InputStream is) 
 { 
 SqlSessionFactory sessionFactory = new SqlSessionFactory(); 
 sessionFactory.setConfiguration(is); 
 return sessionFactory; 
 } 
} 

SqlSessionImpl.java Mybatis模擬類(src/main/java/com/bjpowernode/practice/simulation目錄下)

package com.bjpowernode.practice.simulation; 
import java.lang.reflect.Method; 
import java.lang.reflect.Proxy; 
import java.sql.Connection; 
import java.sql.DriverManager; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 
/** 
 * 
 * 模擬SqlSessionImpl 
 * 
 */ 
public class SqlSessionImpl implements SqlSession 
{ 
 /** DB connection */ 
 public static Connection connection; 
 private Map<String, Mapper> xmlSQLs; 
 private List<String> annotationClasses; 
 public SqlSessionImpl() 
 { 
 /** 
 * driverString 和 connString 應該是從配置文件讀取,這里簡化了 
 */ 
 final String driverString = "org.apache.derby.jdbc.ClientDriver"; 
 final String connString = "jdbc:derby://localhost:1527/bjpowernode;create=true"; 
 try 
 { 
 Class.forName(driverString); 
 /** 獲得DB連接 */ 
 connection = DriverManager.getConnection(connString); 
 } 
 catch (Exception e) 
 { 
 System.out.println("獲取DBConnection出錯!"); 
 } 
 } 
 /** 
 * 基于Annotation的數據庫操作 
 * 
 */ 
 @Override 
 public <T> T getMapper(Class<T> clazz) 
 { 
 T clazzImpl = 
 (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {clazz}, new SQLSelectProxy()); 
 return clazzImpl; 
 } 
 /** 
 * 
 * 基于XML的查詢操作 
 */ 
 @Override 
 public <E> List<E> selectList(String query) throws Exception 
 { 
 PreparedStatement pstmt = null; 
 ResultSet rs = null; 
 try 
 { 
 /** 簡單的PreparedStateme JDBC實現 */ 
 pstmt = connection.prepareStatement(xmlSQLs.get(query).getQuerySql()); 
 rs = pstmt.executeQuery(); 
 /** 執行查詢操作 */ 
 return executeQuery(rs, xmlSQLs.get(query).getResultType()); 
 } 
 finally 
 { 
 if (!rs.isClosed()) 
 { 
 rs.close(); 
 } 
 if (!pstmt.isClosed()) 
 { 
 pstmt.close(); 
 } 
 } 
 } 
 /** 
 * 
 * 執行查詢操作,并將查詢到的結果與配置中的ResultType根據變量名一一對應,通過反射調用Set方法注入各個變量的值 
 * 
 * @param rs 
 * @param type 
 * @return 
 * @throws Exception 
 */ 
 public static <E> List<E> executeQuery(ResultSet rs, String type) throws Exception 
 { 
 int count = rs.getMetaData().getColumnCount(); 
 List<String> columnNames = new ArrayList<String>(); 
 for (int i = 1; i <= count; i++) 
 { 
 columnNames.add(rs.getMetaData().getColumnName(i)); 
 } 
 final List list = new ArrayList<Object>(); 
 while (rs.next()) 
 { 
 Class modelClazz = Class.forName(type); 
 Object obj = modelClazz.newInstance(); 
 for (Method setMethods : modelClazz.getMethods()) 
 { 
 for (String columnName : columnNames) 
 { 
  if (setMethods.getName().equalsIgnoreCase("set" + columnName)) 
  { 
  setMethods.invoke(obj, rs.getString(columnName)); 
  } 
 } 
 } 
 list.add(obj); 
 } 
 return list; 
 } 
 public Map<String, Mapper> getXmlSQLs() 
 { 
 return xmlSQLs; 
 } 
 public void setXmlSQLs(Map<String, Mapper> xmlSQLs) 
 { 
 this.xmlSQLs = xmlSQLs; 
 } 
 public List<String> getAnnotationClasses() 
 { 
 return annotationClasses; 
 } 
 public void setAnnotationClasses(List<String> annotationClasses) 
 { 
 this.annotationClasses = annotationClasses; 
 } 
} 

UserMapper.xml 基于XML的Mapper配置文件(src/main/java/com/bjpowernode/practice/xml目錄下)

<?xml version="1.0" encoding="UTF-8" ?> 
 <!-- namespace 當基于XML進行配置的時候是根據namespace+id來拼接進行SQL操作 --> 
<mapper namespace="com.bjpowernode.practice.UserMapper"> 
 <!-- select 查詢 --> 
 <select id="getUser" resultType="com.bjpowernode.practice.User"> 
 select * 
 from USER_TEST_TB 
 </select> 
</mapper> 

TestMyBatis.java 測試類(src/test/java/com/bjpowernode/practice目錄下)

package com.bjpowernode.practice; 
import com.bjpowernode.practice.annotation.UserMapper; 
import com.bjpowernode.practice.simulation.SqlSession; 
import com.bjpowernode.practice.simulation.SqlSessionFactory; 
import com.bjpowernode.practice.simulation.SqlSessionFactoryBuilder; 
import com.bjpowernode.practice.simulation.SqlSessionImpl; 
import java.io.InputStream; 
import java.sql.SQLException; 
import java.text.MessageFormat; 
import java.util.List; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 
public class TestMyBatis 
{ 
 /** 配置置文件 */ 
 private String source; 
 private InputStream inputStream; 
 private SqlSessionFactory sqlSessionFactory; 
 @Before 
 public void setUp() 
 { 
 source = "test-mybatis-configuration.xml"; 
 } 
 /** 
 * 
 * 基于XML格式配置的測試方法 
 * 
 */ 
 @Test 
 public void testXMLConfingure() 
 { 
 try 
 { 
 /** 
 * 獲得Session 
 */ 
 inputStream = TestMyBatis.class.getClassLoader().getResourceAsStream(source); 
 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 
 SqlSession session = sqlSessionFactory.openSession(); 
 /** 
 * 執行Query操作 
 */ 
 List<User> users = (List) session.selectList("com.bjpowernode.practice.UserMapper.getUser"); 
 System.out.println("Query by XML configuration..."); 
 /** 
 * 打印結果 
 */ 
 this.printUsers(users); 
 } 
 catch (Exception e) 
 { 
 e.printStackTrace(); 
 } 
 } 
 /** 
 * 
 * 基于Annotation配置的測試方法 
 * 
 */ 
 @Test 
 public void testAnnotationConfingure() 
 { 
 try 
 { 
 inputStream = TestMyBatis.class.getClassLoader().getResourceAsStream(source); 
 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 
 SqlSession session = sqlSessionFactory.openSession(); 
 UserMapper userMapper = session.getMapper(UserMapper.class); 
 System.out.println("\r\nQuery by annotation configuration..."); 
 this.printUsers(userMapper.getUser()); 
 } 
 catch (Exception e) 
 { 
 e.printStackTrace(); 
 } 
 } 
 @After 
 public void clearUp() throws SQLException 
 { 
 if (SqlSessionImpl.connection != null && !SqlSessionImpl.connection.isClosed()) 
 { 
 SqlSessionImpl.connection.close(); 
 } 
 } 
 private void printUsers(final List<User> users) 
 { 
 int count = 0; 
 for (User user : users) 
 { 
 System.out.println(MessageFormat.format("==User[{0}]=================", ++count)); 
 System.out.println("User Id: " + user.getId()); 
 System.out.println("User UserName: " + user.getUsername()); 
 System.out.println("User Password: " + user.getPassword()); 
 System.out.println("User nickname: " + user.getNickname()); 
 } 
 } 
} 

以上就是基于XML以及Annotation的方式對Mybatis實現了一個簡單的模擬。旨在理解Mybatis的工作原理。

筆者一直覺得當學習一個工具類技術的時候,路線應該是

1.實現一個小例子

2.找材料理解其中原理

3.學習技術細節,并動手全部實現

4.在全部學完之后動手做一個小項目,盡可能的使用這個在技術中的各個環節。

總結

以上所述是小編給大家介紹的模擬Mybatis的實現方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對億速云網站的支持!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

大同市| 保靖县| 忻州市| 体育| 广丰县| 永德县| 甘肃省| 台江县| 东方市| 垫江县| 海丰县| 白城市| 招远市| 石景山区| 格尔木市| 长沙市| 安平县| 新宾| 霞浦县| 马边| 长宁区| 大洼县| 小金县| 高邑县| 繁昌县| 靖西县| 碌曲县| 丰原市| 鞍山市| 全南县| 天长市| 德州市| 泗水县| 濮阳县| 新密市| 泌阳县| 哈尔滨市| 灵丘县| 札达县| 清远市| 淳安县|