前置工作準備
- 建立Maven專案 , 引入依賴(mybatis依賴 ,mysql 驅動依賴 ,junit依賴 ,logback 依賴)
- 將xml檔案放到類的根路徑下
- 提供com.north.mybatis.utils.SqlSessionUtil工具類
- 建立測試用例:com.north.mybatis.CarMapperTest
補充知識:什麼是CRUD
C: Create增
R: Retrieve查(檢索)
U: Update改
D: Delete刪
1. insert(Create )
先說理論知識 : 在sql語句中使用 #{map集合的key}來完成傳值 等同於JDBC中的 ? ,#{}就是佔位符
<insert id="insertCar">
insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
values(null,'1003','豐田霸道',30.0,'2000-10-11','燃油車');
</insert>
上述程式碼的問題是:
- 值 顯然是寫死到配置檔案中的。
- 這個在實際開發中是不存在的。一定是前端的form表單提交過來資料。然後將值傳給sql語句。
例如:JDBC的程式碼是怎麼寫的?String sql = "insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,?,?,?,?,?)";
在JDBC當中佔位符采用的是?,在mybatis當中是什麼呢?
和?等效的寫法是:#{}
在mybatis當中不能使用?佔位符,必須使用 #{} 來代替JDBC當中的 ?
{} 和 JDBC當中的 ? 是等效的。
insert的細節之處
java程式中使用POJO類給SQL語句的佔位符傳值:
- 注意:佔位符#{},大括號裡面寫:pojo類的屬性名 , 但是這樣說也並不是很嚴謹
嚴格意義上來說:如果使用POJO物件傳遞值的話,#{}這個大括號中到底寫什麼?
- 寫的是get方法的方法名去掉get,然後將剩下的單詞首字母小寫,然後放進去。
- 例如:getUsername() --> #
也就是說mybatis在底層給 ? 傳值的時候,先要獲取值,怎麼獲取的 ?
- 呼叫了pojo物件的get方法。例如:car.getCarNum(),car.getCarType(),car.getBrand()
如果採用map集合傳參,#{} 裡寫的是map集合的key,如果key不存在不會報錯,資料庫表中會插入NULL。
程式碼演示 ,這裡我自己吸取之前的教訓 ,把基本完整的給寫出來 ,防止以後再來看的話 , 不知道都代表著是什麼意思😊😊😊
工具類程式碼:
public class SqlSessionUtil {
// 工具類的構造方法一般都是私有化的。
// 工具類中所有的方法都是靜態的,直接採用類名即可呼叫。不需要new物件。
// 為了防止new物件,構造方法私有化。
private SqlSessionUtil(){}
private static SqlSessionFactory sqlSessionFactory;
// 類載入時執行
// SqlSessionUtil工具類在進行第一次載入的時候,解析mybatis-config.xml檔案。建立SqlSessionFactory物件。
static {
try {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/*public static SqlSession openSession(){
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// SqlSessionFactory物件:一個SqlSessionFactory對應一個environment,一個environment通常是一個資料庫。
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}*/
/**
* 獲取會話物件。
* @return 會話物件
*/
public static SqlSession openSession(){
return sqlSessionFactory.openSession();
}
}
測試類:
@Test
public void testInsertCarByPOJO() {
SqlSession sqlSession = SqlSessionUtil.openSession();
// 封裝資料
Car car = new Car(null , "1005" , "比亞迪漢" , 30.0 , "2020-11-11" , "新能源");
int rows = sqlSession.insert("insertCar" , car);
System.out.println("插入成功的行數:" + rows);
sqlSession.commit();
sqlSession.close();
}
CarMapper.xml檔案中的insert標籤:
<insert id="insertCar">
insert into t_car(id , car_num , brand , guide_price , produce_time , car_type)
values (null , #{carNum} , #{brand} , #{guidePrice} , #{produceTime} , #{carType})
</insert>
2. delete (Delete)
注意:如果佔位符只有一個,那麼#{}的大括號裡可以隨意。但是最好見名知意。
需求:根據id進行刪除資料
CarMapper.xml檔案中的delete標籤:
<delete id="deleteCar">
delete from t_car where id = #{id}
</delete>
測試類:
@Test
public void testDeleteById() {
SqlSession sqlSession = SqlSessionUtil.openSession();
int rows = sqlSession.delete("deleteCar", 16);
System.out.println("刪除的行數:" + rows);
sqlSession.commit();
sqlSession.close();
}
3. update(Update)
根據id修改某條資料的程式碼演示
CarMapper.xml檔案中的update標籤:
<update id="updateCar">
update t_car
set
car_num = #{carNum} ,
brand = #{brand} ,
guide_price = #{guidePrice} ,
produce_time = #{produceTime} ,
car_type = #{carType}
where
id = #{id}
</update>
測試類:
@Test
public void testUpdateById() {
SqlSession sqlSession = SqlSessionUtil.openSession();
Car car = new Car(4L , "3333" , "梅特賽斯" , 146.8 , "2018-11-11" , "燃油車");
int rows = sqlSession.update("updateCar", car);
System.out.println("受影響的行數:" + rows);
sqlSession.commit();
sqlSession.close();
}
4. select(Retrieve)
select語句和其它語句不同的是:查詢會有一個結果集
4.1 查詢一條資料
其中 ,查一個,根據主鍵查詢的話,返回的結果一定是一個。
需求:根據id進行查詢
需要特別注意的是:
select標籤中resultType屬性,這個屬性用來告訴mybatis,查詢結果集封裝成什麼型別的java物件。你需要告訴mybatis。
resultType通常寫的是:全限定類名。
注意:select語句查詢的時候,查詢結果集的列名是可以使用as關鍵字起別名的。
查詢的時候需要在select標籤中進行封裝結果接對映 ,也就是寫上resultType屬性 , 不然會進行報錯
CarMapper.xml檔案中的select標籤:
<select id="selectById" resultType="com.north.mybatis.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>
測試類:
@Test
public void testSelectById() {
SqlSession sqlSession = SqlSessionUtil.openSession();
Object selectOne = sqlSession.selectOne("selectById", 1);
System.out.println(selectOne);
sqlSession.close();
}
查詢結果展示:
4.2 查詢多條資料
需求:查詢所有資料
需要注意的是:
resultType還是指定要封裝的結果集的型別。不是指定List型別,是指定List集合中元素的型別。
selectList方法:mybatis透過這個方法就可以得知你需要一個List集合。它會自動給你返回一個List集合。
CarMapper.xml檔案中的select標籤:
<select id="selectAll" resultType="com.north.mybatis.pojo.Car">
select
id ,
car_num as carNum ,
brand ,
guide_price as guidePrice ,
produce_time as produceTime ,
car_type as carType
from
t_car
</select>
測試類:
@Test
public void testSelectAll() {
SqlSession sqlSession = SqlSessionUtil.openSession();
List<Object> selectAll = sqlSession.selectList("selectAll");
selectAll.forEach(car -> System.out.println(car));
sqlSession.close();
}
執行結果展示:
5. 關於SQL Mapper的namespace
namespace的作用
在sql mapper.xml檔案當中有一個namespace,這個屬性是用來指定名稱空間的。用來防止id重複。
實際上,本質上,mybatis中的sqlId的完整寫法:namespace.id