MyBatis(四) 插入、刪除、修改操作

1.實現插入操作

1.1 基本插入操作:

1.先實現最簡單的插入操作(不考慮foreign key情況)。先創建測試表:

test_order_detail_mm.sql:

CREATE TABLE `test_order_detail_mm` (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `order_id` int(20) NOT NULL,
  `goods_name` varchar(50) DEFAULT NULL,
  `single_price` decimal(19,2) DEFAULT NULL,
  `num` int(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

創建對應實體類TestOrderDetailMm.java,駝峯模式創建屬性和get、set方法。

2.mapper文件,TestOrderDetailMm.xml:

<insert id="addOrderDetail" parameterType="com.vip.model.TestOrderDetailMm"
useGeneratedKeys="true" keyProperty="id">
	insert into test_order_detail_mm (order_id,goods_name,single_price,num) values
	(#{orderId},#{goodsName},#{singlePrice},#{num})
</insert>

解釋:

輸入參數是實體類TestOrderDetailMm;useGeneratedKeys表示mybatis使用mysql的jdbc的自增字段的方法來獲得,默認是false的;keyProperty表示設置java類中用來接收getGeneratedKeys、selectKey返回的key的屬性,設置java哪個屬性來接收key值。

3.測試類:

	@Test
	public void testSimpleInsert() {
		//構建需要創建的記錄(對象),自增字段不管。
		TestOrderDetailMm todm = new TestOrderDetailMm();
		todm.setOrderId(1);
		todm.setGoodsName("衣服");
		todm.setSinglePrice(198.5);
		todm.setNum(2);
		SqlSession session = sqlSessionFactory.openSession();
		try {
			int count = session.insert("com.vip.mapping.TestOrderDetailMm.addOrderDetail", todm);
		} catch (Exception e) {
			e.printStackTrace();
			session.rollback();
		}
		session.commit();
		session.close();
	}

必須要設置事務提交,數據才能順利的插入庫中。如果發生錯誤,在catch中回滾事務。


1.2 主外鍵關係插入操作:


在實際應用中,我們有一張訂單表(test_order_mm)和一張訂單明細表(test_order_detail_mm),兩張表通過order表的id連接,當新增一個訂單時(該訂單中也包含訂單明細),需要先插入訂單表,這時候生成一個訂單id,再將該id取過來增加訂單明細信息,該需求的實現如下:


(1)首先,需要定義order和orderDetail各自的mapper文件:

order_detail的mapper:

<insert id="addOrderDetail" parameterType="com.vip.model.TestOrderDetailMm"
useGeneratedKeys="true" keyProperty="id">
	insert into test_order_detail_mm (order_id,goods_name,single_price,num) values
	(#{orderId},#{goodsName},#{singlePrice},#{num})
</insert

order的mapper:

	<insert id="addOrder" parameterType="com.vip.model.TestOrderMm">
		<selectKey keyProperty="id"  resultType="int" order="AFTER" >
			SELECT LAST_INSERT_ID()
		</selectKey>
		insert into test_order_mm (order_no,order_address,price,person_id) values
		(#{orderNo},#{orderAddress},#{price},#{personId})
	</insert>

上邊,我們看到了<selectKey>標籤,該標籤可以將標籤內SELECT字句的值返回給TestOrderMm對象的id屬性中。order屬性:先插入再返回id值;還是先返回id值,再插入。

(2)下面定義測試方法:

@Test
	public void testComplexInsert() {
		
		SqlSession session = sqlSessionFactory.openSession();
		//構建需要創建的訂單記錄:
		TestOrderMm t1 = new TestOrderMm();
		t1.setOrderNo("00066");
		t1.setOrderAddress("NewYork");
		t1.setPrice(2321);
		t1.setPersonId(2);
		
		try{
			session.insert("com.vip.mapping.TestOrderMm.addOrder", t1);
			
			TestOrderDetailMm todm = new TestOrderDetailMm();
			todm.setGoodsName("notebook");
			todm.setNum(1);
			todm.setOrderId(t1.getId());
			todm.setSinglePrice(2321);
			session.insert("com.vip.mapping.TestOrderDetailMm.addOrderDetail", todm);
			
		}catch (Exception e) {
			e.printStackTrace();
			session.rollback();
		}
		session.commit();
		session.close();
	}

上邊程序中,先定義order對象類,執行order的insert語句,這時會把mysql自動生成的id返回給t1對象的id屬性。之後我們再構建order_detail對象,setOrderId時,使用todm.setOrderId(t1.getId())。最後再執行order_detail的insert語句,這樣就可以完成上邊敘述的需求了。

(3)執行結果:

DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@7ce3cb8e]
DEBUG - ==>  Preparing: insert into test_order_mm (order_no,order_address,price,person_id) values (?,?,?,?) 
DEBUG - ==> Parameters: 00066(String), NewYork(String), 2321.0(Double), 2(Integer)
DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@7ce3cb8e]
DEBUG - ==>  Preparing: SELECT LAST_INSERT_ID() 
DEBUG - ==> Parameters: 
DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@7ce3cb8e]
DEBUG - ==>  Preparing: insert into test_order_detail_mm (order_id,goods_name,single_price,num) values (?,?,?,?) 
DEBUG - ==> Parameters: 10(Integer), notebook(String), 2321.0(Double), 1(Integer)

程序執行陳宮,我們可以看到使用這種方法生成的sql都是預編譯的,可以防止sql注入問題。最後一步的insert我們獲得了上一步自動生成的order_id 10。


2.實現修改操作

1.修改操作比較簡單,跟insert操作類似,在輸入參數對象時,需要設定id了(確定要修改哪一個)。

mapper文件,TestOrderDetailMm.xml:

	<update id="UpdateOrderDetail" parameterType="com.vip.model.TestOrderDetailMm" >
		Update test_order_detail_mm 
		SET order_id = #{orderId},
		goods_name = #{goodsName},
		single_price = #{singlePrice},
		num = #{num}
		WHERE id = #{id}
	</update>

2.測試文件:

	@Test
	public void testSimpleUpdate() {
		//需要設置逐漸id
		TestOrderDetailMm todm = new TestOrderDetailMm();
		todm.setId(7);		
		todm.setOrderId(4);
		todm.setGoodsName("智能手錶");
		todm.setSinglePrice(2498);
		todm.setNum(1);
		SqlSession session = sqlSessionFactory.openSession();
		try {
			int count = session.update("com.vip.mapping.TestOrderDetailMm.UpdateOrderDetail", todm);
		} catch (Exception e) {
			e.printStackTrace();
			session.rollback();
		}
		session.commit();
		session.close();
	}

(1)上邊代碼中,在初始化參數對象todm時,這時候,需要setId,把逐漸也set上。

(2)上邊代碼有不好的地方,就是在new參數對象時,需要set每一個屬性值,否則就會將數據庫中的記錄set成null值,最好是先讀出來再update。


3.實現刪除操作

  1. 刪除類實現,根據id字段來刪除數據的邏輯:

mapper文件:

	<delete id="DeleteOrderDetail" parameterType="java.lang.Integer">
		Delete from test_order_detail_mm where id = #{id}
	</delete>

因爲參數只是一個integer的變量,而不是對象,所以#{}內可以是任意的字符串,不一定是id。


測試類:

	@Test
	public void testDelete() {
		SqlSession session = sqlSessionFactory.openSession();
		try {
			int count = session.delete("com.vip.mapping.TestOrderDetailMm.DeleteOrderDetail", 4);
		} catch (Exception e) {
			e.printStackTrace();
			session.rollback();
		}
		session.commit();
		session.close();
	}


4.Mybatis使用別名:

4.1 自定義別名:

1. 別名需要在根目錄的配置文件sqlMapConfig.xml中定義,在標籤<configuration>下一級,使用標籤typeAliases。

2. 要定義的別名必須是一個數據類型。例如parameterType或resultType等指定的類型,一定不能爲id值指定別名。

如下例所示:

<typeAliases>
	<typeAlias type="com.vip.model.TestOrderDetailMm" alias="TestOrderDetailMm"></typeAlias>
</typeAliases>

type:準備要被取別名的數據類型;

alias:數據類型被取的別名。

3.這個功能可以減少我們的代碼輸入量。


4.2 非自定義別名:

  1. jdk中的所有類都使用了非自定義別名,別名內容是類名(不區分大小寫)。例如,java.util.Map可以簡寫成map。

  2. 非自定義別名不需要我們在配置文件中定義。

  3. 如果是包裝類(例如java.lang.Integer、java.lang.Character),還可以使用其基本數據類型的名字。例如,java.lang.Integer可以直接簡寫成“int”。


這部分內容比較簡單,可以自行測試。


4.3 定義sql片段:

1.sql片段是一段代碼,這段代碼,很多程序可以共用。

下面程序片段,定義在mapper文件中<mapper>下一級標籤:

<sql id="colums">
	id,order_id,goods_name,single_price,num
</sql>

<select id="selectOrderDetail" resultMap="com.vip.model.TestOrderDetailMm">
	select <include refid="colums"/> from test_order_detail_mm 
</select>

(1)定義sql片段使用sql標籤,id指定sql片段的id;

(2)其中<include>標籤,可以引用sql片段,refid屬性指定的是sql片段的id;

(3)sql片段可以供不同程序共享使用。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章