1. 程式人生 > >JavaEE---MyBatis---單表的增、刪、改、查

JavaEE---MyBatis---單表的增、刪、改、查

準備資料

CREATE TABLE USER(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(30),
	age INT 
);

INSERT INTO USER(id,NAME,age) VALUES(1,"Jack",22);
INSERT INTO USER(id,NAME,age) VALUES(2,"張三",20);
INSERT INTO USER(id,NAME,age) VALUES(3,"Java",23);

準備JavaBean

package cn.hncu.domain;

/*
CREATE TABLE USER(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(30),
	age INT 
);
 */
public class User {
	private Integer id;
	private String name;
	private Integer age;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
}

對映檔案UserMapper.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">
  
<!-- 採用介面開發時,namespace的值必須是介面類的類全名
 -->
<mapper namespace="cn.hncu.domain.UserMapper">
	<!-- 使用介面開發,介面中的方法名必須跟id值一致 -->
	<select id="all" resultType="User"> <!-- 由於mybatis中設定了別名,所以resultType可以使用別名 -->
		select * from user
	</select>
	
	<!-- 單條件查詢 -->
	<select id="query1" parameterType="int" resultType="User">
		select * from user where id=#{id}
	</select>
	
	<!-- 多條件查詢 使用POJO、map、list或者QueryValueModel  parameterMap已經不推薦使用  -->
	
	<!-- 
		 select * from user where id=#{id} or name LIKE "%"#{name}"%"   AC
		 select * from user where id=#{id} or name LIKE concat("%",#{name},"%")    AC
		 select * from user where id=#{id} or name LIKE "%${name}%"    AC
	-->
	<!-- 使用${}類似於EL表示式,與 #{}相比,它不會把特殊字元進行轉義,有安全隱患-->
	<select id="query2" parameterType="cn.hncu.domain.User" resultType="User">
		select * from user where id=#{id} or name LIKE concat("%",#{name},"%")
	</select>
	
	<!-- 範圍查詢使用查詢值物件 -->
	<select id="query3" parameterType="cn.hncu.domain.UserQueryModel" resultType="User">
		select * 
		from user 
		where id=#{id} 
		or age <![CDATA[>=]]> #{age} 
		and age <![CDATA[<=]]> #{age2} 
	</select>
	
	<!-- 範圍查詢使用map封裝條件 -->
	<select id="query4" parameterType="map" resultType="User">
		select * 
		from user 
		where id=#{id} 
		or age <![CDATA[>=]]> #{age} 
		and age <![CDATA[<=]]> #{age2} 
	</select>
	
	<!-- 增 -->
	<insert id="add" parameterType="User" >
		insert into 
		user(name,age) 
		values(#{name},#{age})
	</insert>
	
	<!-- 刪 -->
	<delete id="del" parameterType="int">
		delete from user where id=#{id}
	</delete>
	<!-- 改 -->
	<update id="update" parameterType="User">
		update user 
		set name=#{name}, age=#{age} 
		where id=#{id}
	</update>
	
	<!-- 下面演示使用 sql標籤,作用:當一條sql重複使用時,可以使用sql標籤定義,
		   使用時用include標籤引入一下就可以了 
	-->
	<sql id="userColumn">
		id,name,age
	</sql>
	<select id="sqlDemo" resultType="User">
		select <include refid="userColumn"/> from user
	</select>
	
	<!-- 下面演示獲取自動增長id
		   當parameterType為值物件時,keyProperty必須與值物件中的主鍵屬名一致
		   如果想要不一致可以使用 map 作為parameterType的值,讀取時通過keyProperty的值作為key
	-->
	<insert id="autoKeys" 
			useGeneratedKeys="true"
			keyProperty="id"
			parameterType="User">
		insert into 
		user(name,age) 
		values(#{name},#{age})
	</insert>
	<insert id="autoKeys2" 
			useGeneratedKeys="true"
			keyProperty="iid"
			parameterType="map">
		insert into 
		user(name,age) 
		values(#{name},#{age})
	</insert>
	
</mapper>
  

對映介面

不採用介面也是可以執行起來的,但是採用介面的方式使以後面對龐大的資料表時,面向介面程式設計就不用到對映檔案中去查詢該如何呼叫,介面上的註解可以很清晰的表述出來,同時通過介面還可避免一些不必要的型別強轉異常。

package cn.hncu.domain;

import java.util.List;
import java.util.Map;

public interface UserMapper {
	/**
	 * 查詢所有user資訊
	 * @return 封裝所有使用者資訊的List
	 */
	public List<User> all();
	/**
	 * 根據使用者id查詢相應的使用者
	 * @param id User的id屬性,主鍵
	 * @return user 或者 null
	 */
	public User query1(int id);
	/**
	 * 模糊查詢,按理條件查詢應該使用查詢值物件
	 * @param user 值物件
	 * @return 封裝符合條件的使用者資訊的List
	 */
	public List<User> query2(User user);
	/**
	 * 範圍查詢,使用查詢值物件
	 * @param uqm 查詢值物件
	 * @return 封裝符合條件的使用者資訊的List
	 */
	public List<User> query3(UserQueryModel uqm);
	/**
	 * 範圍查詢,使用map封裝查詢條件,與查詢值物件相比較靈活,但是使用時需要注意key值的對應
	 * @param map 封裝查詢條件的map
	 * @return 封裝符合條件的使用者資訊的List
	 */
	public List<User> query4(Map<String, Object> map);
	
	/**
	 * 新增一條使用者記錄
	 * @param user 封裝了使用者資訊的值物件
	 */
	public Integer add(User user);
	/**
	 * 根據使用者id刪除相應的使用者記錄
	 * @param id 使用者id,主鍵
	 */
	public Integer del(Integer id);
	/**
	 * 修改使用者資訊
	 * @param user 新的使用者資訊
	 * @return
	 */
	public Integer update(User user);
	
	public List<User> sqlDemo();
	
	public Integer autoKeys(User user);
	public Integer autoKeys2(Map<String, Object> map);
}

全域性配置檔案中引入對映檔案

使用對映器介面實現類的完全限定類名:

<configuration>

        <mappers><mapper class="cn.hncu.domain.UserMapper"/></mappers>

</configuration>

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

	<!-- '類型別名' 是為 Java型別設定一個短的名字。它只和 'XML配置'有關,存在的意義僅在於用來減少類完全限定名的冗餘 -->
	<typeAliases>
		<typeAlias alias="User" type="cn.hncu.domain.User" />
	</typeAliases>

	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<!-- &amp; 轉義  -->
				<property name="url" value="jdbc:mysql:///mybatis?useUnicode=true&amp;characterEncoding=utf-8" />
				<property name="username" value="root" />
				<property name="password" value="1234" />
				
				<!-- 在任意時間可以存在的活動(也就是正在使用)連線數量,預設值:10-->
				<property name="poolMaximumActiveConnections" value="5"/>
				<!-- 在被強制返回之前,池中連線被檢出(checked out)時間,預設值:20000 毫秒(即 20 秒) -->
				<property name="poolMaximumCheckoutTime" value="30000"/>
			</dataSource>
		</environment>
	</environments>
	
	
	<mappers>
		
		<!-- 使用對映器介面實現類的完全限定類名 -->
		<mapper class="cn.hncu.domain.UserMapper"/>
		
		<!-- 使用相對於類路徑的資源引用 -->
		<mapper resource="cn/hncu/domain/UserMapper2.xml"/>
		
	</mappers>
	<!-- 
	 -->
</configuration>

查詢所有

注意:下面的所有演示中,User都是cn.hncu.domain.User的別名,因為在上面全域性配置檔案中使用了<typeAliases>進行取別名。

	<!-- 使用介面開發,介面中的方法名必須跟id值一致 -->
	<select id="all" resultType="User"> <!-- 由於mybatis中設定了別名,所以resultType可以使用別名 -->
		select * from user
	</select>
	//無條件查詢
	@Test
	public void all() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper( UserMapper.class );
		List<User> users = userMapper.all();
		for (User user : users) {
			System.out.println(user);
		}
	}

單條件查詢

    <!-- 單條件查詢 -->
	<select id="query1" parameterType="int" resultType="User">
		select * from user where id=#{id}
	</select>
	//單條件查詢
	@Test 
	public void query1() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper( UserMapper.class );
		User user = userMapper.query1(1);
		System.out.println( user );
	}

多條件查詢

POJO封裝查詢條件

	<!-- 多條件查詢 使用POJO、map、list或者QueryValueModel  parameterMap已經不推薦使用  -->
	
	<!-- 
		 select * from user where id=#{id} or name LIKE "%"#{name}"%"   AC
		 select * from user where id=#{id} or name LIKE concat("%",#{name},"%")    AC
		 select * from user where id=#{id} or name LIKE "%${name}%"    AC
	-->
	<!-- 使用${}類似於EL表示式,與 #{}相比,它不會把特殊字元進行轉義,有安全隱患-->
	<select id="query2" parameterType="cn.hncu.domain.User" resultType="User">
		select * from user where id=#{id} or name LIKE concat("%",#{name},"%")
	</select>
	//多條件查詢
	@Test 
	public void query2() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper( UserMapper.class );
		User user = new User();
		user.setId(1);
		/*
		 select * from user where id=#{id} or name LIKE '%${name}%'
		 user.setName("j%' or 1=1 or name ='");  //BUG
		 select * from user where id=#{id} or name LIKE "%${name}%"
		 user.setName("j%\" or 1=1 or name =\"");  //BUG
		 */
		user.setName("j%\" or 1=1 or name =\""); 
		//user.setName("j");
		List<User> users = userMapper.query2(user);
		
		for (User u : users) {
			System.out.println(u);
		}
	}

查詢值物件封裝查詢條件

查詢值物件:繼承User,專用於封裝查詢條件的JavaBean。

package cn.hncu.domain;

public class UserQueryModel extends User {
	
	private Integer age2;

	public Integer getAge2() {
		return age2;
	}

	public void setAge2(Integer age2) {
		this.age2 = age2;
	}
	
}

ORM對映

	<!-- 範圍查詢使用查詢值物件 -->
	<select id="query3" parameterType="cn.hncu.domain.UserQueryModel" resultType="User">
		select * 
		from user 
		where id=#{id} 
		or age <![CDATA[>=]]> #{age} 
		and age <![CDATA[<=]]> #{age2} 
	</select>

測試

	//使用查詢值物件
	@Test
	public void query3() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper( UserMapper.class );
		UserQueryModel uqm = new UserQueryModel();
		uqm.setId(1);
		uqm.setAge(20);
		uqm.setAge2(22);
		List<User> users = userMapper.query3(uqm);
		for (User u : users) {
			System.out.println(u);
		}
	}

新增

	<!-- 增 -->
	<insert id="add" parameterType="User" >
		insert into 
		user(name,age) 
		values(#{name},#{age})
	</insert>
	//增
	@Test
	public void add() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper( UserMapper.class );
		User user = new User();
		user.setName("劉備");
		user.setAge(19);
		userMapper.add(user);
		//注意:增刪改都必須commit
		sqlSession.commit(); //提交事務
		all(); //呼叫查詢所有
	}

新增並獲取自動增長ID

<!-- 下面演示獲取自動增長id
		   當parameterType為值物件時,keyProperty必須與值物件中的主鍵屬名一致
		   如果想要不一致可以使用 map 作為parameterType的值,讀取時通過keyProperty的值作為key
	-->
	<insert id="autoKeys" 
			useGeneratedKeys="true"
			keyProperty="id"
			parameterType="User">
		insert into 
		user(name,age) 
		values(#{name},#{age})
	</insert>
	//演示獲取自動增長id---值物件封裝
	@Test
	public void autoKeys() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper( UserMapper.class );
		User user = new User();
		user.setName("麻花藤");
		user.setAge(38);
		userMapper.autoKeys(user);
		System.out.println(user);//User [id=7, name=馬化騰, age=38]
		sqlSession.commit();
	}

刪除

	<!-- 刪 -->
	<delete id="del" parameterType="int">
		delete from user where id=#{id}
	</delete>
	//刪
	@Test
	public void del() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper( UserMapper.class );
		userMapper.del(3);
		
		sqlSession.commit(); //提交事務
		all(); //呼叫查詢所有
	}

修改

	<!-- 改 -->
	<update id="update" parameterType="User">
		update user 
		set name=#{name}, age=#{age} 
		where id=#{id}
	</update>
	//改
	@Test
	public void update() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		UserMapper userMapper = sqlSession.getMapper( UserMapper.class );
		User user = new User();
		user.setName("老乾媽");
		user.setAge(18);
		user.setId(4);
		userMapper.update(user);
		//注意:增刪改都必須commit
		sqlSession.commit(); //提交事務
		all(); //呼叫查詢所有
	}