Mybatis核心配置文件就是为了配置Configration
因此要首先会解析Mybatis核心配置文件
首先使用dom4J解析Mybatis核心配置文件
新建模块演示dom4j解析.xml
目录放错了 无所谓
引入依赖
从原来项目可以拷贝过来
就些简单配置就好
解析核心配置文件和解析xxxMapper.xml映射文件代码
- import org.dom4j.Document;
- import org.dom4j.DocumentException;
- import org.dom4j.Element;
- import org.dom4j.Node;
- import org.dom4j.io.SAXReader;
- import org.junit.Test;
-
- import java.io.InputStream;
- import java.util.List;
-
- /**
- * @author hrui
- * @date 2023/9/10 18:24
- */
- public class ParseXMLByDom4JTest {
-
-
- //解析Mapper映射文件
- @Test
- public void testParseSqlMapperXML() throws DocumentException {
- //创建SAXReader对象
- SAXReader reader=new SAXReader();
- //获取输入流(将resources目录下的mybatis-config1.xml转输入流)
- InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mapper/CarMapperABC.xml");
- //读XML文件
- Document document=reader.read(inputStream);
- String xpath="/mapper";
- Element mapper =(Element) document.selectSingleNode(xpath);
- String namespace = mapper.attributeValue("namespace");
- System.out.println(namespace);//aaa
- //获取mapper节点下所有子节点
- List<Element> elements = mapper.elements();
- elements.forEach(e->{
- //获取sqlId
- String id = e.attributeValue("id");
- //获取resultType 没有返回null
- System.out.println(id);
- //获取标签中的sql语句,取出前后空白
- String sql = e.getTextTrim();
- System.out.println(sql);//insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
- //现在是:insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
- //内部肯定使用JDBC:insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,?,?,?,?,?)
- //转换
- String newSql = sql.replaceAll("#\\{[0-9A-Za-z_$]*}", "?");//使用正则替换
- System.out.println(newSql);//insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,?,?,?,?,?)
- });
- }
-
-
-
- //解析核心配置文件
- @Test
- public void testParseMybatisConfigXML() throws DocumentException {
- //创建SAXReader对象
- SAXReader reader=new SAXReader();
- //获取输入流(将resources目录下的mybatis-config1.xml转输入流)
- InputStream inputStream = ClassLoader.getSystemClassLoader().getResourceAsStream("mybatis-config1.xml");
- //读XML文件
- Document document=reader.read(inputStream);
- //System.out.println(document);
- //获取根标签
- Element root = document.getRootElement();
- //System.out.println(root.getName());//configuration
- //获取跟标签后肯定是去获取环境 environments 获取里面的default数据库id
- //获取默认的环境id
- //xpath是做标签路径匹配的.能够让我们快速定位XML文件中的元素
- //以下的xpath:从跟下开始找configuration,然后找configuration标签下的子标签environments
- String xpath="/configuration/environments";
- Element element = (Element)document.selectSingleNode(xpath);
- //System.out.println(element);
- //获取属性的值 默认环境id
- String aDefaultEnvivironmentId = element.attributeValue("default");
- //System.out.println("默认环境id是:"+aDefaultEnvivironmentId);//development
-
- //去找environment的 id属性,然后和默认环境id比较,确定默认使用哪个数据库
- //下面是xpath的写法 意思找
- xpath="/configuration/environments/environment[@id='"+aDefaultEnvivironmentId+"']";
- Element enviroment =(Element) document.selectSingleNode(xpath);
- //System.out.println(enviroment.getName());environment
- //获取environment节点下的transactionManager
- Element transactionManager = enviroment.element("transactionManager");
- String transactionType = transactionManager.attributeValue("type");
- //System.out.println("事务管理器的类型:"+transactionType);//获取事务管理器类型----->JDBC
- //接着获取datasource节点
- Element datasource = enviroment.element("dataSource");
- String dataSourcetype = datasource.attributeValue("type");
- System.out.println("数据源的类型:"+dataSourcetype);//POOLED
- //获取dataSource下的所有子节点
- List<Element> propertyElements = datasource.elements();
- //遍历
- propertyElements.forEach(e->{
- String name = e.attributeValue("name");
- String value = e.attributeValue("value");
- System.out.println("name="+name+",value="+value);
- });
-
- //获取所有的mapper标签
- //如果你不想从跟下开始获取,而是想从任意位置开始,获取某个标签,xpath可以这样写
- xpath="//mapper";// 两个//开始
- List<Node> mappers = document.selectNodes(xpath);
- //遍历
- mappers.forEach(n->{
- Element e=(Element)n;
- String resource = e.attributeValue("resource");
- System.out.println(resource);
- });
-
- }
- }
新建module
引入依赖
可以回顾下标准写法
逆推下
Resources
SqlSessionFactoryBuilder
SqlSessionFactory
transaction
SqlSession
SQL Mapper
思路:1.Resources用来加载核心配置文件,返回一个InputStream流,
2.SqlSessionFactoryBuilder里有个build方法,该方法用来返回一个SqlSessionFactory对象
这里要考虑,SqlSessionFactory里有些什么,用来做什么.
那么这样就明了了,build方法用来解析核心配置文件,用以给SqlSessionFactory里的属性赋值,而属性有哪些,就是上面这些呗(事务管理器,JDBC连接需要的driver,url,username,password)
另外
和映射文件
是否考虑用一个容器Map存放,key为sql的id value是其他
将这个对象也封装到SqlSessionFactory中
这个对象中该有哪些属性:暂时放sql语句和resultType 当然实际放的不只这两个 获取不到就是null
SqlSessionFactory中还需要一个事务管理器,这个事务管理器可以是JDBC也可以是MANAGED,那么可以定义为接口,另外定义两个具体的实现 这里使用JDBC事务管理器
而我们定义了事务管理器之后,事务管理器需要搞定的就三个方法,commit,rollback,close
但是这三个方法需要连接对象,而要获取连接对象可以定义个数据源
在核心配置文件中,数据源有三个选项,分别是POOLED UNPOOLED JNDI
那好办,定义为接口呗
这里有个JDK规范,不管你是POOLED UNPOOLED JNDI所有的数据源都需要实现JDK里的DataSource接口 那么接口也不用定义了 直接写三个实现类 这里使用UNPOOLED 不使用连接池
那么在实现类里需要driver url username password属性
然后又个SqlSession对象
里面又insert方法 xxx 方法 需要用到什么,再解决
基本思路就是这样
整体结构
1.Resources
- package com.gmybatis.utils;
-
- import java.io.InputStream;
-
- /**
- * 工具类
- * 用于"类路径"中资源的加载
- * @author hrui
- * @date 2023/9/10 20:25
- */
- public class Resources {
- //工具类建议构造方法私有化,因为工具类一般方法都是静态的,是种编程习惯
-
- public Resources() {
- }
-
- /**
- * 用于"类路径"种加载资源
- * @param resource
- * @return
- */
- public static InputStream getResourceAsStream(String resource){
- return ClassLoader.getSystemClassLoader().getResourceAsStream(resource);
- }
- }
2.SqlSessionFactoryBuilder 构建器对象
- package com.gmybatis.core;
-
- import com.gmybatis.utils.Resources;
- import jdk.nashorn.internal.ir.ReturnNode;
- import org.dom4j.Document;
- import org.dom4j.DocumentException;
- import org.dom4j.Element;
- import org.dom4j.Node;
- import org.dom4j.io.SAXReader;
-
-
- import javax.sql.DataSource;
- import java.io.InputStream;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
-
- /**
- * SqlSessionFactory的构建器对象
- * 通过SqlSessionFactoryBuilder的build方法来解析核心配置文件,
- * 然后创建SqlSessionFactory对象
- * @author hrui
- * @date 2023/9/10 20:31
- */
- public class SqlSessionFactoryBuilder {
-
- public SqlSessionFactoryBuilder() {
- }
-
-
- /**
- * 解析核心配置文件,来构建SqlSessionFactory
- * @param in
- * @return
- */
- public SqlSessionFactory build(InputStream in){
- SqlSessionFactory sqlSessionFactory=null;
- try {
- //解析核心配置文件
- //创建SAXReader对象
- SAXReader reader=new SAXReader();
-
- //读XML文件
- Document document=reader.read(in);
- //获取environments
- Element environments =(Element) document.selectSingleNode("/configuration/environments");
- //获取default属性值
- String defaultId = environments.attributeValue("default");
-
- //拿匹配的环境节点
- Element environment = (Element)document.selectSingleNode("/configuration/environments/environment[@id='"+defaultId+"']");
- //获取transactionManager
- Element transactionManagerEle = environment.element("transactionManager");
- //获取dataSource
- Element dataSourceEle = environment.element("dataSource");
- //获取mapper
- List<Node> mapperList = document.selectNodes("//mapper");//获取整个配置文件中所有的mapper标签
- //用于封装所有mappers里面的mapper的路径
- List<String> sqlMapperXMLPathList=new ArrayList<>();
- mapperList.forEach(n->{
- Element e=(Element) n;
- String resource = e.attributeValue("resource");
- sqlMapperXMLPathList.add(resource);
- });
-
-
- //获取数据源对象
- DataSource dataSource=getDataSource(dataSourceEle);
-
- //定义事务管理器
- Transaction transaction=getTransaction(transactionManagerEle,dataSource);
-
-
- //key是namespase+sql的id
- Map<String,MappedStatement> MappedStatements=getMappedStatements(sqlMapperXMLPathList);
-
- //解析完成之后,构建出SqlSessionFactory对象
- sqlSessionFactory=new SqlSessionFactory(transaction,MappedStatements);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return sqlSessionFactory;
- }
-
- private Map<String, MappedStatement> getMappedStatements(List<String> sqlMapperXMLPathList) {
- Map<String,MappedStatement> map=new HashMap<>();
- sqlMapperXMLPathList.forEach(path->{
- try {
- //创建SAXReader对象
- SAXReader reader=new SAXReader();
- //读XXXMapper.XML映射文件
- Document document=reader.read(Resources.getResourceAsStream(path));
- //解析映射文件
- Element mapper = (Element)document.selectSingleNode("mapper");//带不带/都可以
- String namespace = mapper.attributeValue("namespace");
- List<Element> elements = mapper.elements();
- elements.forEach(e->{
- String id = e.attributeValue("id");
- //namespase+id
- String sqlId=namespace+"."+id;
- String resultType = e.attributeValue("resultType");
- String sqlContent = e.getTextTrim();
- MappedStatement mappedStatement=new MappedStatement(sqlContent,resultType);
-
- map.put(sqlId,mappedStatement);
- });
- } catch (DocumentException e) {
- e.printStackTrace();
- }
- });
- return map;
- }
-
- private DataSource getDataSource(Element dataSourceEle) {
- Map<String,String> map=new HashMap<>();
- //获取节点下所有property
- List<Element> propertys = dataSourceEle.elements("property");
- propertys.forEach(e->{
- String name = e.attributeValue("name");
- String value = e.attributeValue("value");
- map.put(name,value);
- });
-
- DataSource dataSource=null;
- //type 可能是 POOLED UNPOOLED JNDI
- String type = dataSourceEle.attributeValue("type");
- // if(type.equalsIgnoreCase("POOLED")){ //这里简易定义常量类
- //
- // }
- if(type.equalsIgnoreCase(Const.POOLED_DATASOURCE)){
- dataSource=new POOLEDDataSource();
- }
- if(type.equalsIgnoreCase(Const.UN_POOLED_DATASOURCE)){//只对这个做了实现
- dataSource=new UNPOOLEDDataSource(map.get("driver"),map.get("url"),map.get("username"),map.get("password"));
- }
- if(type.equalsIgnoreCase(Const.JNDI_DATASOURCE)){
- dataSource=new JNDIDataSource();
- }
- return dataSource;
- }
-
- private Transaction getTransaction(Element transactionManager, DataSource dataSource) {
-
- Transaction transaction=null;
- String type = transactionManager.attributeValue("type");
- if(type.equalsIgnoreCase(Const.JDBC_TRANSACTION)){
- transaction=new JDBCTransaction(dataSource,false );//只对JDBCTransaction做了实现
- }
- if(type.equalsIgnoreCase(Const.MANAGED_TRANSACTION)){
- transaction=new MANAGEDTransaction();
- }
- return transaction;
- }
-
-
- }
3.SqlSessionFactory
- package com.gmybatis.core;
-
- import java.util.Map;
-
- /**
- *SqlSessionFactory对象,一个数据库对应一个SqlSessionFactory对象
- * 通过SqlSessionFactory对象可以获得SqlSession对象(开启会话)
- * 一个SqlSessionFactory对象可以开启多个SqlSession会话
- * @author hrui
- * @date 2023/9/10 20:34
- */
- public class SqlSessionFactory {
- //事务管理器 可以是JDBC:原生JDBC事务 也可以是MANAGED:交容器管理,比如Spring 可以灵活切换建议定义为接口
- private Transaction transaction;
-
- //数据源属性 因为已经在事务管理器里定义了数据源,因此这里不需要定义 可以通过事务管理器来获取
-
-
- private Map<String,MappedStatement> mappedStatementMap;
-
- public SqlSessionFactory() {
- }
-
- public SqlSessionFactory(Transaction transaction, Map<String, MappedStatement> mappedStatementMap) {
- this.transaction = transaction;
- this.mappedStatementMap = mappedStatementMap;
- }
-
- public Transaction getTransaction() {
- return transaction;
- }
-
- public void setTransaction(Transaction transaction) {
- this.transaction = transaction;
- }
-
- public Map<String, MappedStatement> getMappedStatementMap() {
- return mappedStatementMap;
- }
-
- public void setMappedStatementMap(Map<String, MappedStatement> mappedStatementMap) {
- this.mappedStatementMap = mappedStatementMap;
- }
-
- // public SqlSession openSession(boolean flag){
- // return null;
- // }
- }
Transaction接口及实现类,这里只实现了JDBCTransaction
- package com.gmybatis.core;
-
- import java.sql.Connection;
-
- /**
- * 事务管理器接口,所有的事务管理器都应该实现该接口
- * JDBC事务管理器,MANAGED事务管理器都应该实现这个接口
- * 提供控制事务的方法
- * @author hrui
- * @date 2023/9/10 21:14
- */
- public interface Transaction {
-
- //提交事务
- void commit();
-
- //回滚事务
- void rollback();
-
- //关闭事务
- void close();
-
- /**
- * 是否需要其他方法后续再看
- * 真正开启数据库连接
- */
- void openConnection();
-
- Connection getConnection();
- }
JDBCTransaction
- package com.gmybatis.core;
-
- import javax.sql.DataSource;
- import java.sql.Connection;
- import java.sql.SQLException;
-
- /**
- * JDBC事务管理器
- * @author hrui
- * @date 2023/9/10 21:19
- */
- public class JDBCTransaction implements Transaction{
-
- //数据源属性
- private DataSource dataSource;
-
- /**
- * 自动提交标志
- * true为自动提交
- * false为不自动提交
- */
- private Boolean aotoCommit;
-
- private Connection connection;
-
- /**
- * 用于外界获取Connection
- * 外界用的Connection对象 必须和事务管理器的是同一个
- * 这样才可以在事务管理器里 commit rollback closed
- * @return
- */
- @Override
- public Connection getConnection() {
- return connection;
- }
-
- //用于给属性connection赋值 只要事务管理器不换 连接就是同一个连接、
- @Override
- public void openConnection(){
- if(connection==null){
- try {
- connection=dataSource.getConnection();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
-
- public JDBCTransaction(DataSource dataSource, Boolean aotoCommit) {
- this.dataSource = dataSource;
- this.aotoCommit = aotoCommit;
- }
-
- @Override
- public void commit() {
- //控制事务的时候需要调用JDBC里的连接对象 需要数据源
- try {
- connection.commit();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void rollback() {
- try {
- connection.rollback();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void close() {
- try {
- connection.commit();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
MANAGEDTransaction
- package com.gmybatis.core;
-
- import java.sql.Connection;
-
- /**
- * MANAGED事务管理器
- * @author hrui
- * @date 2023/9/10 21:19
- */
- public class MANAGEDTransaction implements Transaction{
- @Override
- public void commit() {
-
- }
-
- @Override
- public void rollback() {
-
- }
-
- @Override
- public void close() {
-
- }
-
- @Override
- public void openConnection() {
-
- }
-
- @Override
- public Connection getConnection() {
- return null;
- }
- }
实现DataSource的3个实现 只实现了UNPOOLEDDataSource
- package com.gmybatis.core;
-
- import javax.sql.DataSource;
- import java.io.PrintWriter;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.SQLException;
- import java.sql.SQLFeatureNotSupportedException;
- import java.util.logging.Logger;
-
- /**
- * 数据源的实现类--->UNPOOLED
- * 不使用数据库连接池
- * @author hrui
- * @date 2023/9/10 21:33
- */
- public class UNPOOLEDDataSource implements DataSource {
-
- private String driver;
-
- private String url;
-
- private String username;
-
- private String password;
-
-
- public UNPOOLEDDataSource(String driver, String url, String username, String password) {
- try {
- //直接注册驱动
- Class.forName("com.mysql.cj.jdbc.Driver");
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- this.driver = driver;
- this.url = url;
- this.username = username;
- this.password = password;
- }
-
-
-
- @Override
- public Connection getConnection() throws SQLException {
- //需要driver url username password 定义为属性
- Connection connection = DriverManager.getConnection(url, username, password);
- return connection;
- }
-
- @Override
- public Connection getConnection(String username, String password) throws SQLException {
- return null;
- }
-
- @Override
- public
T unwrap(Class iface) throws SQLException { - return null;
- }
-
- @Override
- public boolean isWrapperFor(Class> iface) throws SQLException {
- return false;
- }
-
- @Override
- public PrintWriter getLogWriter() throws SQLException {
- return null;
- }
-
- @Override
- public void setLogWriter(PrintWriter out) throws SQLException {
-
- }
-
- @Override
- public void setLoginTimeout(int seconds) throws SQLException {
-
- }
-
- @Override
- public int getLoginTimeout() throws SQLException {
- return 0;
- }
-
- @Override
- public Logger getParentLogger() throws SQLFeatureNotSupportedException {
- return null;
- }
- }
- package com.gmybatis.core;
-
- import javax.sql.DataSource;
- import java.io.PrintWriter;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.sql.SQLFeatureNotSupportedException;
- import java.util.logging.Logger;
-
- /**
- * 数据源的实现类--->POOLED
- * 使用数据库连接池 这里不写连接池
- * @author hrui
- * @date 2023/9/10 21:32
- */
- public class POOLEDDataSource implements DataSource {
- @Override
- public Connection getConnection() throws SQLException {
- //从数据库连接池获取Connection对象 这里不写连接池
- return null;
- }
-
- @Override
- public Connection getConnection(String username, String password) throws SQLException {
- return null;
- }
-
- @Override
- public
T unwrap(Class iface) throws SQLException { - return null;
- }
-
- @Override
- public boolean isWrapperFor(Class> iface) throws SQLException {
- return false;
- }
-
- @Override
- public PrintWriter getLogWriter() throws SQLException {
- return null;
- }
-
- @Override
- public void setLogWriter(PrintWriter out) throws SQLException {
-
- }
-
- @Override
- public void setLoginTimeout(int seconds) throws SQLException {
-
- }
-
- @Override
- public int getLoginTimeout() throws SQLException {
- return 0;
- }
-
- @Override
- public Logger getParentLogger() throws SQLFeatureNotSupportedException {
- return null;
- }
- }
JNDIDataSource
- package com.gmybatis.core;
-
- import javax.sql.DataSource;
- import java.io.PrintWriter;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.sql.SQLFeatureNotSupportedException;
- import java.util.logging.Logger;
-
- /**
- * 数据源的实现类--->JNDI
- * 使用第三方的数据库连接池获取Connection对象
- * @author hrui
- * @date 2023/9/10 21:33
- */
- public class JNDIDataSource implements DataSource {
- @Override
- public Connection getConnection() throws SQLException {
- return null;
- }
-
- @Override
- public Connection getConnection(String username, String password) throws SQLException {
-
- return null;
- }
-
- @Override
- public
T unwrap(Class iface) throws SQLException { - return null;
- }
-
- @Override
- public boolean isWrapperFor(Class> iface) throws SQLException {
- return false;
- }
-
- @Override
- public PrintWriter getLogWriter() throws SQLException {
- return null;
- }
-
- @Override
- public void setLogWriter(PrintWriter out) throws SQLException {
-
- }
-
- @Override
- public void setLoginTimeout(int seconds) throws SQLException {
-
- }
-
- @Override
- public int getLoginTimeout() throws SQLException {
- return 0;
- }
-
- @Override
- public Logger getParentLogger() throws SQLFeatureNotSupportedException {
- return null;
- }
- }
定义了一个常量类
- package com.gmybatis.core;
-
- /**
- * 整个框架的常量类
- * @author hrui
- * @date 2023/9/10 22:26
- */
- public class Const {
-
- public static final String UN_POOLED_DATASOURCE="UNPOOLED";
-
- public static final String POOLED_DATASOURCE="POOLED";
-
- public static final String JNDI_DATASOURCE="JNDI";
-
- public static final String JDBC_TRANSACTION="JDBC";
-
- public static final String MANAGED_TRANSACTION="MANAGED";
- }
注意测试时候事务管理要选用JDBC 数据源类型要选用UNPOOLED
mapper路径要写对
测试基本没问题
下面把SqlSession加进去
- package com.gmybatis.core;
-
- import java.lang.reflect.Method;
- import java.sql.Connection;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- import java.util.Locale;
-
- /**
- * 专门负责执行SQL语句的会话对象
- * @author hrui
- * @date 2023/9/10 23:40
- */
- public class SqlSession {
-
- private SqlSessionFactory sqlSessionFactory;
-
- public SqlSession(SqlSessionFactory sqlSessionFactory) {
- this.sqlSessionFactory = sqlSessionFactory;
- }
-
-
- //测试
- public static void main(String[] args) {
- String sql="insert into t_car values(#{id},#{asd},#{name})";
- int fromIndex=0;
- int index=1;
- while(true) {
- int jingIndex = sql.indexOf("#",fromIndex);
-
- if(jingIndex<0){
- break;
- }
- System.out.println(index);
- index++;
- int youkuohaoIndex = sql.indexOf("}",fromIndex);
- String propertyName = sql.substring(jingIndex + 2, youkuohaoIndex).trim();
- System.out.println(propertyName);
- fromIndex = youkuohaoIndex + 1;
- }
-
- }
-
-
- public int insert(String sqlId,Object obj){
- //JDBC代码
- Connection connection=null;
- PreparedStatement ps=null;
- ResultSet rs=null;
- int count = 0;
- try {
- connection=sqlSessionFactory.getTransaction().getConnection();
- String sql=sqlSessionFactory.getMappedStatementMap().get(sqlId).getSql();
- String sql1 = sql.replaceAll("#\\{[0-9A-Za-z_$]*}", "?");//使用正则替换
- ps = connection.prepareStatement(sql1);
- //有几个?号 不知道将pojo对象中的哪个属性给哪个 暂时全当String
-
- int fromIndex=0;
- int index=1;
- while(true) {
- int jingIndex = sql.indexOf("#",fromIndex);
-
- if(jingIndex<0){
- break;
- }
- //System.out.println(index);
-
- int youkuohaoIndex = sql.indexOf("}",fromIndex);
- String propertyName = sql.substring(jingIndex + 2, youkuohaoIndex).trim();
- //System.out.println(propertyName);
- fromIndex = youkuohaoIndex + 1;
- String getMethodName="get"+propertyName.toUpperCase().charAt(0)+propertyName.substring(1);
- Method getMethod=obj.getClass().getDeclaredMethod(getMethodName);
- Object invoke = getMethod.invoke(obj);
- ps.setString(index,invoke.toString());
- index++;
- }
-
- count = ps.executeUpdate();
- } catch (Exception e) {
- e.printStackTrace();
- }
- //这里不要加 不然直接关闭了
- // finally {
- // if(rs!=null){
- // try {
- // rs.close();
- // } catch (SQLException e) {
- // e.printStackTrace();
- // }
- // }
- // if(ps!=null){
- // try {
- // ps.close();
- // } catch (SQLException e) {
- // e.printStackTrace();
- // }
- // }
- // if(connection!=null){
- // try {
- // connection.close();
- // } catch (SQLException e) {
- // e.printStackTrace();
- // }
- // }
- // }
- return count;
- }
-
-
- public Object selectOne(){
- return null;
- }
-
- public void commit(){
- sqlSessionFactory.getTransaction().commit();
- }
-
- public void rollback(){
- sqlSessionFactory.getTransaction().rollback();
- }
-
- public void close(){
- sqlSessionFactory.getTransaction().close();
- }
- }
修改sqlSessionFactory
- package com.gmybatis.core;
-
- import java.util.Map;
-
- /**
- *SqlSessionFactory对象,一个数据库对应一个SqlSessionFactory对象
- * 通过SqlSessionFactory对象可以获得SqlSession对象(开启会话)
- * 一个SqlSessionFactory对象可以开启多个SqlSession会话
- * @author hrui
- * @date 2023/9/10 20:34
- */
- public class SqlSessionFactory {
- //事务管理器 可以是JDBC:原生JDBC事务 也可以是MANAGED:交容器管理,比如Spring 可以灵活切换建议定义为接口
- private Transaction transaction;
-
- //数据源属性 因为已经在事务管理器里定义了数据源,因此这里不需要定义 可以通过事务管理器来获取
-
-
- private Map<String,MappedStatement> mappedStatementMap;
-
- public SqlSessionFactory() {
- }
-
- public SqlSessionFactory(Transaction transaction, Map<String, MappedStatement> mappedStatementMap) {
- this.transaction = transaction;
- this.mappedStatementMap = mappedStatementMap;
- }
-
- public Transaction getTransaction() {
- return transaction;
- }
-
- public void setTransaction(Transaction transaction) {
- this.transaction = transaction;
- }
-
- public Map<String, MappedStatement> getMappedStatementMap() {
- return mappedStatementMap;
- }
-
- public void setMappedStatementMap(Map<String, MappedStatement> mappedStatementMap) {
- this.mappedStatementMap = mappedStatementMap;
- }
-
- /**
- * 获取sql会话对象
- * @param flag
- * @return
- */
- public SqlSession openSession(){
- //开启会话的前提是开启连接
- transaction.openConnection();
- //创建SqlSession对象
- SqlSession sqlSession=new SqlSession(this);
- return sqlSession;
- }
- }
JDBCTransaction的openConnection的代码加上开启事务
- package com.gmybatis.core;
-
- import javax.sql.DataSource;
- import java.sql.Connection;
- import java.sql.SQLException;
-
- /**
- * JDBC事务管理器
- * @author hrui
- * @date 2023/9/10 21:19
- */
- public class JDBCTransaction implements Transaction{
-
- //数据源属性
- private DataSource dataSource;
-
- /**
- * 自动提交标志
- * true为自动提交
- * false为不自动提交
- */
- private boolean aotoCommit;
-
- private Connection connection;
-
- /**
- * 用于外界获取Connection
- * 外界用的Connection对象 必须和事务管理器的是同一个
- * 这样才可以在事务管理器里 commit rollback closed
- * @return
- */
- @Override
- public Connection getConnection() {
- return connection;
- }
-
- //用于给属性connection赋值 只要事务管理器不换 连接就是同一个连接、
- @Override
- public void openConnection(){
- if(connection==null){
- try {
- connection=dataSource.getConnection();
- //开启事务
- connection.setAutoCommit(aotoCommit);
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
-
- public JDBCTransaction(DataSource dataSource, Boolean aotoCommit) {
- this.dataSource = dataSource;
- this.aotoCommit = aotoCommit;
- }
-
- @Override
- public void commit() {
- //控制事务的时候需要调用JDBC里的连接对象 需要数据源
- try {
- connection.commit();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void rollback() {
- try {
- connection.rollback();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public void close() {
- try {
- connection.commit();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
- }
引入mysql依赖测试 新建表
新建实体类
- package com.gmybatis.core;
-
- /**
- * @author hrui
- * @date 2023/9/11 0:31
- */
- public class Car {
- private String id;
- private String name;
- private String age;
-
- public Car() {
- }
-
- public Car(String id, String name, String age) {
- this.id = id;
- this.name = name;
- this.age = age;
- }
-
- public String getId() {
- return id;
- }
-
- public void setId(String id) {
- this.id = id;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getAge() {
- return age;
- }
-
- public void setAge(String age) {
- this.age = age;
- }
- }
映射文件