栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

模拟Mybatis的实现方法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

模拟Mybatis的实现方法

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

项目管理工具 : Maven

测试运行工具 : Junit

数据库 : Derby

XML操作工具:Dom4j

继续不废话

Maven Dependencies:

 
 junit 
 junit 
 4.9 
 test 
  
  
 org.apache.derby 
 derby 
 10.10.2.0 
  
  
 org.apache.derby 
 derbyclient 
 10.10.2.0 
  
  
 dom4j 
 dom4j 
 1.6.1 
  

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
 
 
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
 

User.java对象类(src/main/java/com/bjpowernode/practice目录下)

package com.bjpowernode.practice; 
 
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) 
 
@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 getUser(); 
} 

Mapper.java 对象类(src/main/java/com/bjpowernode/practice/simulation目录下)

package com.bjpowernode.practice.simulation; 
 
public class Mapper 
{ 
  
 private String resultType; 
  
 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 
 { 
  
 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(); 
  
 String returnType = method.getGenericReturnType().toString();//java.util.List 
 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; 
 
public interface SqlSession 
{ 
 public  T getMapper(Class clazz); 
 public  List 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; 
 
public class SqlSessionFactory 
{ 
 private InputStream configuration; 
 public SqlSession openSession() throws IOException 
 { 
 SqlSessionImpl session = new SqlSessionImpl(); 
 loadConfigurations(session); 
 return session; 
 } 
  
 private void loadConfigurations(final SqlSessionImpl session) throws IOException 
 { 
 try 
 { 
 document document = new SAXReader().read(configuration); 
 Element root = document.getRootElement(); 
 List 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(); 
 } 
 } 
  
 private Map loadXMLConfiguration(String resource) throws documentException, IOException 
 { 
 Map map = new HashMap(); 
 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) 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; 
 
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; 
 
public class SqlSessionImpl implements SqlSession 
{ 
  
 public static Connection connection; 
 private Map xmlSQLs; 
 private List annotationClasses; 
 public SqlSessionImpl() 
 { 
  
 final String driverString = "org.apache.derby.jdbc.ClientDriver"; 
 final String connString = "jdbc:derby://localhost:1527/bjpowernode;create=true"; 
 try 
 { 
 Class.forName(driverString); 
  
 connection = DriverManager.getConnection(connString); 
 } 
 catch (Exception e) 
 { 
 System.out.println("获取DBConnection出错!"); 
 } 
 } 
  
 @Override 
 public  T getMapper(Class clazz) 
 { 
 T clazzImpl = 
 (T) Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[] {clazz}, new SQLSelectProxy()); 
 return clazzImpl; 
 } 
  
 @Override 
 public  List selectList(String query) throws Exception 
 { 
 PreparedStatement pstmt = null; 
 ResultSet rs = null; 
 try 
 { 
  
 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(); 
 } 
 } 
 } 
  
 public static  List executeQuery(ResultSet rs, String type) throws Exception 
 { 
 int count = rs.getmetaData().getColumnCount(); 
 List columnNames = new ArrayList(); 
 for (int i = 1; i <= count; i++) 
 { 
 columnNames.add(rs.getmetaData().getColumnName(i)); 
 } 
 final List list = new ArrayList(); 
 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 getXmlSQLs() 
 { 
 return xmlSQLs; 
 } 
 public void setXmlSQLs(Map xmlSQLs) 
 { 
 this.xmlSQLs = xmlSQLs; 
 } 
 public List getAnnotationClasses() 
 { 
 return annotationClasses; 
 } 
 public void setAnnotationClasses(List annotationClasses) 
 { 
 this.annotationClasses = annotationClasses; 
 } 
} 

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

 
  
 
  
  
 

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"; 
 } 
  
 @Test 
 public void testXMLConfingure() 
 { 
 try 
 { 
  
 inputStream = TestMyBatis.class.getClassLoader().getResourceAsStream(source); 
 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 
 SqlSession session = sqlSessionFactory.openSession(); 
  
 List users = (List) session.selectList("com.bjpowernode.practice.UserMapper.getUser"); 
 System.out.println("Query by XML configuration..."); 
  
 this.printUsers(users); 
 } 
 catch (Exception e) 
 { 
 e.printStackTrace(); 
 } 
 } 
  
 @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("rnQuery 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 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的实现方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号