create SqlSession Class
package com.wsd.core;
/**
* @description: 执行sql
* @author: Mr.Wang
* @create: 2023-06-24 16:55
**/
public class SqlSession {
}
SqlSessionFactory 中创建 openSqlSession method to get a sql session instance
/**
* @description Get sql session instance
* @param null
* @return
*/
public SqlSession openSqlSession(){
return null;
}
package com.wsd.core;
import java.util.Map;
/**
* @program: spring_learn
* @description:
* @author: Mr.Wang
* @create: 2023-06-22 21:39
**/
public class SqlSessionFactory {
/**
* @description 事务管理器 transactionManager
* 根据配置的不同而使用不同的实现类
*/
private Transaction transaction;
/**
* @description
* map 的 key 为 sql标签的 id , value 为MappedStatement 对象
* The key of the map is the id of the SQL tag, and the value is the MappedStatement object
*/
private Map<String,MappedStatement> mappedStatementMap;
public SqlSessionFactory(Transaction transaction, Map<String, MappedStatement> mappedStatementMap) {
this.transaction = transaction;
this.mappedStatementMap = mappedStatementMap;
}
/**
* @description Get sql session instance
* @param null
* @return
*/
public SqlSession openSqlSession(){
return null;
}
}
SqlSessionFactory 中创建 openSqlSession method to get a sql session instance
获取 sql session instance,需要先有一个connection
/**
* @description Get sql session instance
* @param null
* @return
*/
public SqlSession openSqlSession(){
//创建connection
this.transaction.openConnection();
return null;
}
//创建SqlSession instance,将 this 作为参数传给SqlSession instance ,sqlSession 就可以使用 SqlSessionFactory 的属性
SqlSession sqlSession = new SqlSession(this);
/**
* @description Get sql session instance
* @param null
* @return
*/
public SqlSession openSqlSession(){
//创建connection
this.transaction.openConnection();
//创建SqlSession instance
SqlSession sqlSession = new SqlSession(this);
return sqlSession;
}
SqlSession 添加属性和构造方法
package com.wsd.core;
/**
* @description: 执行sql
* @author: Mr.Wang
* @create: 2023-06-24 16:55
**/
public class SqlSession {
private SqlSessionFactory sqlSessionFactory;
public SqlSession(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
}
添加 insert 方法,执行 insert sql语句
/** * @description 执行 inert ,向数据库表中插入数据 * @param sqlId:sql 语句的 id * @param data:所需要的数据 * @return 成功插入的记录数量 */ public int insert(String sqlId, Object data){ return 0; }
package com.wsd.core;
/**
* @description: 执行sql
* @author: Mr.Wang
* @create: 2023-06-24 16:55
**/
public class SqlSession {
private SqlSessionFactory sqlSessionFactory;
public SqlSession(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
/**
* @description 执行 inert ,向数据库表中插入数据
* @param sqlId:sql 语句的 id
* @param data:所需要的数据
* @return 成功插入的记录数量
*/
public int insert(String sqlId, Object data){
return 0;
}
}
SqlSessionFactory 添加获取 属性的get方法public Transaction getTransaction() { return transaction; } public Map<String, MappedStatement> getMappedStatementMap() { return mappedStatementMap; }
package com.wsd.core;
import java.util.Map;
/**
* @program: spring_learn
* @description:
* @author: Mr.Wang
* @create: 2023-06-22 21:39
**/
public class SqlSessionFactory {
/**
* @description 事务管理器 transactionManager
* 根据配置的不同而使用不同的实现类
*/
private Transaction transaction;
/**
* @description
* map 的 key 为 sql标签的 id , value 为MappedStatement 对象
* The key of the map is the id of the SQL tag, and the value is the MappedStatement object
*/
private Map<String,MappedStatement> mappedStatementMap;
public SqlSessionFactory(Transaction transaction, Map<String, MappedStatement> mappedStatementMap) {
this.transaction = transaction;
this.mappedStatementMap = mappedStatementMap;
}
/**
* @description Get sql session instance
* @param null
* @return
*/
public SqlSession openSqlSession(){
//创建connection
this.transaction.openConnection();
//创建SqlSession instance
SqlSession sqlSession = new SqlSession(this);
return sqlSession;
}
public Transaction getTransaction() {
return transaction;
}
public Map<String, MappedStatement> getMappedStatementMap() {
return mappedStatementMap;
}
}
SqlSession 添加以下方法/** * @description commit transaction * @param null * @return */ public void commit(){ this.sqlSessionFactory.getTransaction().commit(); } /** * @description rollback transaction * @param null * @return */ public void rollback(){ this.sqlSessionFactory.getTransaction().rollback(); } /** * @description close connection * @param null * @return */ public void close(){ this.sqlSessionFactory.getTransaction().close(); }
package com.wsd.core;
/**
* @description: 执行sql
* @author: Mr.Wang
* @create: 2023-06-24 16:55
**/
public class SqlSession {
private SqlSessionFactory sqlSessionFactory;
public SqlSession(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
/**
* @description 执行 inert ,向数据库表中插入数据
* @param sqlId:sql 语句的 id
* @param data:所需要的数据
* @return 成功插入的记录数量
*/
public int insert(String sqlId, Object data){
return 0;
}
/**
* @description commit transaction
* @param null
* @return
*/
public void commit(){
this.sqlSessionFactory.getTransaction().commit();
}
/**
* @description rollback transaction
* @param null
* @return
*/
public void rollback(){
this.sqlSessionFactory.getTransaction().rollback();
}
/**
* @description close connection
* @param null
* @return
*/
public void close(){
this.sqlSessionFactory.getTransaction().close();
}
}
实现 insert method of SqlSession
/** * @description 执行 inert ,向数据库表中插入数据 * @param sqlId:sql 语句的 id * @param data:所需要的数据 * @return 成功插入的记录数量 */ public int insert(String sqlId, Object data){ try { //Get connection Connection connection = this.sqlSessionFactory.getTransaction().getConnection(); String sql = this.sqlSessionFactory.getMappedStatementMap().get(sqlId).getSql(); //将 #{} 替换为 ?,"#\\{[0-9A-Za-z_$]*}" 是匹配 #{} 的正则表达式 String preSql = sql.replaceAll("#\\{[0-9A-Za-z_$]*}", "?"); PreparedStatement preparedStatement = connection.prepareStatement(preSql); //给 ?占位符传递参数 } catch (SQLException e) { e.printStackTrace(); } return 0; }
给 ?占位符传递参数 如何实现?
尝试获取 #{value} 中的 value public static void main(String[] args) { String sql = "insert into t_car (id,car_num,brand,guide_price,produce_time,car_type) values (null,#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})"; // 按 #{ 分割 String[] sqlArray = sql.split("#\\{"); //分割后sqlArray[0]没有需要的内容,需要的内容再 #{ 之后,所以 从 sqlArray[0] 开始 for(int i = 1; i < sqlArray.length; i++){ //找到 } 的位置 int index = sqlArray[i].indexOf("}"); // } 之前的内容就是目标 String value = sqlArray[i].substring(0,index); System.out.println(value); } }
继续实现 insert 方法,给 ?占位符传递参数
/** * @description 执行 inert ,向数据库表中插入数据 * @param sqlId:sql 语句的 id * @param data:所需要的数据 * @return 成功插入的记录数量 */ public int insert(String sqlId, Object data){ int count = 0; try { //Get connection Connection connection = this.sqlSessionFactory.getTransaction().getConnection(); String sql = this.sqlSessionFactory.getMappedStatementMap().get(sqlId).getSql(); //将 #{} 替换为 ?,"#\\{[0-9A-Za-z_$]*}" 是匹配 #{} 的正则表达式 String preSql = sql.replaceAll("#\\{[0-9A-Za-z_$]*}", "?"); PreparedStatement preparedStatement = connection.prepareStatement(preSql); //获取 #{value} 中的 value String[] sqlArray = sql.split("#\\{"); for(int i = 1; i < sqlArray.length; i++){ int index = sqlArray[i].indexOf("}"); String value = sqlArray[i].substring(0,index); //给 ?占位符传递参数 //通过 get 方法 获取对应的属性值 //获取get 方法的 method name String methodName = "get" + value.toUpperCase().charAt(0) + value.substring(1); //获取 getter method Method getterdMethod = data.getClass().getDeclaredMethod(methodName); //调用 getter method 获取 属性值 Object propertyValue = getterdMethod.invoke(data); //给 ?占位符传值 preparedStatement.setString(i,propertyValue.toString()); } //执行 sql count = preparedStatement.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } return count; }
package com.wsd.core;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
/**
* @description: 执行sql
* @author: Mr.Wang
* @create: 2023-06-24 16:55
**/
public class SqlSession {
private SqlSessionFactory sqlSessionFactory;
public SqlSession(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
/**
* @description 执行 inert ,向数据库表中插入数据
* @param sqlId:sql 语句的 id
* @param data:所需要的数据
* @return 成功插入的记录数量
*/
public int insert(String sqlId, Object data){
int count = 0;
try {
//Get connection
Connection connection = this.sqlSessionFactory.getTransaction().getConnection();
String sql = this.sqlSessionFactory.getMappedStatementMap().get(sqlId).getSql();
//将 #{} 替换为 ?,"#\\{[0-9A-Za-z_$]*}" 是匹配 #{} 的正则表达式
String preSql = sql.replaceAll("#\\{[0-9A-Za-z_$]*}", "?");
PreparedStatement preparedStatement = connection.prepareStatement(preSql);
//获取 #{value} 中的 value
String[] sqlArray = sql.split("#\\{");
for(int i = 1; i < sqlArray.length; i++){
int index = sqlArray[i].indexOf("}");
String value = sqlArray[i].substring(0,index);
//给 ?占位符传递参数
//通过 get 方法 获取对应的属性值
//获取get 方法的 method name
String methodName = "get" + value.toUpperCase().charAt(0) + value.substring(1);
//获取 getter method
Method getterdMethod = data.getClass().getDeclaredMethod(methodName);
//调用 getter method 获取 属性值
Object propertyValue = getterdMethod.invoke(data);
//给 ?占位符传值
preparedStatement.setString(i,propertyValue.toString());
}
//执行 sql
count = preparedStatement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
return count;
}
/**
* @description commit transaction
* @param null
* @return
*/
public void commit(){
this.sqlSessionFactory.getTransaction().commit();
}
/**
* @description rollback transaction
* @param null
* @return
*/
public void rollback(){
this.sqlSessionFactory.getTransaction().rollback();
}
/**
* @description close connection
* @param null
* @return
*/
public void close(){
this.sqlSessionFactory.getTransaction().close();
}
}
test insert method
package com.wsd.core;
import com.wsd.core.util.Resources;
import com.wsd.pojo.Car;
import org.junit.Test;
/**
* @description: test
* @author: Mr.Wang
* @create: 2023-06-24 15:40
**/
public class TestMyBatis {
@Test
public void testInsert(){
try {
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourcesAsStream("mybatis-config.xml"));
SqlSession sqlSession = sqlSessionFactory.openSqlSession();
Car car = new Car();
car.setBrand("轮回");
car.setCarType("新能源");
sqlSession.insert("car.insertCar",car);
sqlSession.commit();
sqlSession.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
CarMapper.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="car">
<!--insert sql:保存一个汽车信息-->
<insert id="insertCar">
insert into t_car
(id,brand,car_type)
values
(null,#{brand},#{carType})
</insert>
<delete id="deleteByCarNum">
delete from t_car where car_num = #{carNum}
</delete>
<update id="updateCarById">
update t_car set
car_num = #{carNum},
brand = #{brand},
guide_price = #{guidePrice},
produce_time = #{produceTime},
car_type = #{carType}
where id = #{id}
</update>
<select id="selectCarById" resultType="com.wsd.pojo.Car">
select id,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carType
from t_car
where id = #{id}
</select>
<!--虽然结果是List集合,但是resultType属性需要指定的是List集合中元素的类型。-->
<select id="selectCarAll" resultType="com.wsd.pojo.Car">
<!--记得使用as起别名,让查询结果的字段名和java类的属性名对应上。-->
select
id, car_num as carNum, brand, guide_price as guidePrice, produce_time as produceTime, car_type as carType
from
t_car
</select>
</mapper>
Car Class
package com.wsd.core;
import com.wsd.core.util.Resources;
import com.wsd.pojo.Car;
import org.junit.Test;
/**
* @description: test
* @author: Mr.Wang
* @create: 2023-06-24 15:40
**/
public class TestMyBatis {
@Test
public void testInsert(){
try {
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourcesAsStream("mybatis-config.xml"));
SqlSession sqlSession = sqlSessionFactory.openSqlSession();
Car car = new Car();
car.setBrand("蓝雨");
car.setCarType("新能源");
sqlSession.insert("car.insertCar",car);
} catch (Exception e) {
e.printStackTrace();
}
}
}
修改:
创建connection and 开启 事务
this.connection.setAutoCommit(this.autoCommit);
public void openConnection() { if(this.connection == null){ try { this.connection = this.dataSource.getConnection(); //开启 事务 this.connection.setAutoCommit(this.autoCommit); } catch (SQLException e) { e.printStackTrace(); } } }
package com.wsd.core;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
/**
* @description: Jdbc Transaction
* @author: Mr.Wang
* @create: 2023-06-23 09:49
**/
public class JdbcTransaction implements Transaction {
private DataSource dataSource;
private Connection connection;
//true:自动提交
private Boolean autoCommit;
@Override
public void commit() {
try {
this.connection.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void rollback() {
try {
this.connection.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void close() {
try {
this.connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public JdbcTransaction(DataSource dataSource, Boolean autoCommit) {
this.dataSource = dataSource;
this.autoCommit = autoCommit;
}
/**
* @description
* 获取连接对象,为connection属性赋值,避免重复获取(commit,rollback 等操作需要使用同一个 connection)
* @return void
*/
@Override
public void openConnection() {
if(this.connection == null){
try {
this.connection = this.dataSource.getConnection();
//开启 事务
this.connection.setAutoCommit(this.autoCommit);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
@Override
public Connection getConnection() {
return this.connection;
}
}
test result :
修改
输出返回值(插入成功的记录数量)
int count = sqlSession.insert("car.insertCar",car);
System.out.println(count);
@Test public void testInsert(){ try { SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourcesAsStream("mybatis-config.xml")); SqlSession sqlSession = sqlSessionFactory.openSqlSession(); Car car = new Car(); car.setBrand("兴欣"); car.setCarType("新能源"); int count = sqlSession.insert("car.insertCar",car); System.out.println(count); sqlSession.commit(); sqlSession.close(); } catch (Exception e) { e.printStackTrace(); } }
package com.wsd.core;
import com.wsd.core.util.Resources;
import com.wsd.pojo.Car;
import org.junit.Test;
/**
* @description: test
* @author: Mr.Wang
* @create: 2023-06-24 15:40
**/
public class TestMyBatis {
@Test
public void testInsert(){
try {
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourcesAsStream("mybatis-config.xml"));
SqlSession sqlSession = sqlSessionFactory.openSqlSession();
Car car = new Car();
car.setBrand("兴欣");
car.setCarType("新能源");
int count = sqlSession.insert("car.insertCar",car);
System.out.println(count);
sqlSession.commit();
sqlSession.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
result :