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映射文件@Testpublic 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->{//获取sqlIdString id = e.attributeValue("id");//获取resultType 没有返回nullSystem.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,?,?,?,?,?)});}//解析核心配置文件@Testpublic 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标签下的子标签environmentsString xpath="/configuration/environments";Element element = (Element)document.selectSingleNode(xpath);//System.out.println(element);//获取属性的值 默认环境idString 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节点下的transactionManagerElement 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);//获取environmentsElement environments =(Element) document.selectSingleNode("/configuration/environments");//获取default属性值String defaultId = environments.attributeValue("default");//拿匹配的环境节点Element environment = (Element)document.selectSingleNode("/configuration/environments/environment[@id='"+defaultId+"']");//获取transactionManagerElement transactionManagerEle = environment.element("transactionManager");//获取dataSourceElement dataSourceEle = environment.element("dataSource");//获取mapperList<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的idMap<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+idString 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<>();//获取节点下所有propertyList<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 JNDIString 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*/@Overridepublic Connection getConnection() {return connection;}//用于给属性connection赋值 只要事务管理器不换 连接就是同一个连接、@Overridepublic 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;}@Overridepublic void commit() {//控制事务的时候需要调用JDBC里的连接对象 需要数据源try {connection.commit();} catch (SQLException e) {e.printStackTrace();}}@Overridepublic void rollback() {try {connection.rollback();} catch (SQLException e) {e.printStackTrace();}}@Overridepublic 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{@Overridepublic void commit() {}@Overridepublic void rollback() {}@Overridepublic void close() {}@Overridepublic void openConnection() {}@Overridepublic 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;}@Overridepublic Connection getConnection() throws SQLException {//需要driver url username password 定义为属性Connection connection = DriverManager.getConnection(url, username, password);return connection;}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return null;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return false;}@Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {}@Overridepublic void setLoginTimeout(int seconds) throws SQLException {}@Overridepublic int getLoginTimeout() throws SQLException {return 0;}@Overridepublic 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 {@Overridepublic Connection getConnection() throws SQLException {//从数据库连接池获取Connection对象 这里不写连接池return null;}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return null;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return false;}@Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {}@Overridepublic void setLoginTimeout(int seconds) throws SQLException {}@Overridepublic int getLoginTimeout() throws SQLException {return 0;}@Overridepublic 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 {@Overridepublic Connection getConnection() throws SQLException {return null;}@Overridepublic Connection getConnection(String username, String password) throws SQLException {return null;}@Overridepublic <T> T unwrap(Class<T> iface) throws SQLException {return null;}@Overridepublic boolean isWrapperFor(Class<?> iface) throws SQLException {return false;}@Overridepublic PrintWriter getLogWriter() throws SQLException {return null;}@Overridepublic void setLogWriter(PrintWriter out) throws SQLException {}@Overridepublic void setLoginTimeout(int seconds) throws SQLException {}@Overridepublic int getLoginTimeout() throws SQLException {return 0;}@Overridepublic 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对象中的哪个属性给哪个 暂时全当Stringint 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*/@Overridepublic Connection getConnection() {return connection;}//用于给属性connection赋值 只要事务管理器不换 连接就是同一个连接、@Overridepublic 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;}@Overridepublic void commit() {//控制事务的时候需要调用JDBC里的连接对象 需要数据源try {connection.commit();} catch (SQLException e) {e.printStackTrace();}}@Overridepublic void rollback() {try {connection.rollback();} catch (SQLException e) {e.printStackTrace();}}@Overridepublic 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;}
}
映射文件