JavaEE---MyBatis---單表的增、刪、改、查
阿新 • • 發佈:2019-01-27
準備資料
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" />
<!-- & 轉義 -->
<property name="url" value="jdbc:mysql:///mybatis?useUnicode=true&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(); //呼叫查詢所有
}