MyBatis框架安排
目錄
2. 第二天:
1. MyBatis的增刪改查操作(操作配置文件SqlMapConfig.xml)
-
在SqlMapConfig.xml中向數據庫中增加條目
<!-- 插入數據 --> <!-- parameterType="com.liuzeyu.domin.User"參數類型,通過反射爲#{username}...賦值--> <insert id="save" parameterType="com.liuzeyu.domin.User"> <!-- 插入數後返回id,keyProperty="id"對應實體類屬性,keyColumn="id"對應數據庫列名,AFTER:操作最後執行--> <selectKey keyProperty="id" keyColumn="id" order="AFTER" resultType="int"> <!-- SELECT last_insert_id() 返回剛剛插入的數據id-- > SELECT last_insert_id() </selectKey> insert into user (username,birthday,sex,address)VALUES (#{username},#{birthday},#{sex},#{address}) </insert>
-
在SqlMapConfig.xml中向數據庫中刪除條目
<!-- 根據id刪除--> <delete id="delete" parameterType="int"> delete from user where id=#{uid} </delete>
-
在SqlMapConfig.xml向數據庫中修改條目
<!-- 更新數據 --> <update id="update" parameterType="com.liuzeyu.domin.User"> UPDATE user SET username=#{username},birthday=#{birthday},address=#{address},sex=#{sex} where id=#{id} </update>
-
在SqlMapConfig.xml向數據庫中查詢條目
<!-- 根據id查找一個 --> <select id="findById" resultType="com.liuzeyu.domin.User" parameterType="int"> select * from user where id=#{uid} </select> <!-- 根據name查找集合 --> <select id="findByName" resultType="com.liuzeyu.domin.User" parameterType="string"> select * from user where username like #{string} <!-- select * from user where username like '%${value}%' --> </select> <!-- 查詢總記錄數--> <select id="findTotal" resultType="int"> SELECT count(*) FROM USER </select>
測試類:
```
package com.liuzeyu.test;
import com.liuzeyu.dao.IUserDao;
import com.liuzeyu.domin.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class Test {
private InputStream is = null;
private IUserDao userDao = null;
private SqlSession session = null;
/**
* 初始化
* @throws IOException
*/
@Before //測試開始前執行
public void init() throws IOException {
//1.解析xml配置文件
is = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.構建工廠
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//3.工廠生產SqlSession對象
session = factory.openSession();
//4.創建代理Dao的對象
userDao = session.getMapper(IUserDao.class);
}
@After //測試結束後執行
public void destory(){
session.commit();
//7.釋放資源
if( session != null){
session.close();
}
if( is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
@org.junit.Test
public void testSelect() throws IOException {
//5.使用代理對象執行方法
List<User> users = userDao.findAll();
//6.遍歷對象
for (User user : users) {
System.out.println(user);
}
}
@org.junit.Test
public void testSave() throws IOException {
User user = new User();
user.setUsername("liuzeyu");
user.setBirthday(new Date());
user.setAddress("莆田");
user.setSex("男");
System.out.println("保存前:"+user);
userDao.save(user);
System.out.println("保存後:"+user);
}
@org.junit.Test
public void testUpdate() throws IOException {
User user = new User();
user.setId(48);
user.setUsername("duyangting");
user.setBirthday(new Date());
user.setAddress("廈門");
user.setSex("女");
userDao.update(user);
}
@org.junit.Test
public void testDelete() throws IOException {
userDao.delete(46);
}
@org.junit.Test
public void testFindOne() throws IOException {
User user = userDao.findById(42);
System.out.println(user);
}
@org.junit.Test
public void testFindOneByName() throws IOException {
List<User> users = userDao.findByName("%王%");//使用的是PreparedStatement的查詢方式,Preparing: select * from user where username like ?
// List<User> users = userDao.findByName("王"); //使用的是拼接字符串的查詢方式,Preparing: select * from user where username like '%王%'
for (User user : users) {
System.out.println(user);
}
}
@org.junit.Test
public void testFindTotal() throws IOException {
int total = userDao.findTotal();
System.out.println(total);
}
}
```
2. 多個對象組成一個查詢條件
- 將user 對象使用類QueryStringVo包裝
/** * 將查詢條件封裝到一個類中 */ public class QueryStringVo { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
- 在SqlMapConfig.xml向數據庫中查詢條件
</select>
<!-- 根據queryStringVo查詢-->
<select id="findByVo" resultType="com.liuzeyu.domin.User" parameterType="com.liuzeyu.vo.QueryStringVo">
select * from user where username like #{user.username}
<!-- select * from user where username like '%${value}%' -->
</select>
-
測試函數(結果與模糊查詢一致)
@org.junit.Test public void testFindOneByVo() throws IOException { QueryStringVo vo = new QueryStringVo(); User user = new User(); user.setUsername("%王%"); vo.setUser(user); List<User> users = userDao.findByVo(vo);//使用的是PreparedStatement的查詢方式,Preparing: select * from user where username like ? for (User u : users) { System.out.println(u); } }
3. OGNL表達式介紹
OGNL :Object Graphic Navigation Lanuage (對象圖導航語言)
它是通過對象取值方法來獲取數據的,在寫法上把類似JavaBean的get方法給刪掉了。
類中的寫法 user.getUsername
OGNL表達式:user.username
例如上面的
<insert id="save" parameterType="com.liuzeyu.domin.User">
insert into user (username,birthday,sex,address)VALUES (#{username},#{birthday},#{sex},#{address})
</insert>
由於parameterType屬性已經提供了類的路徑,則要獲取values的username需要之需要寫User類的屬性即可#{username},否則需要寫user.username
類似於:
<!-- 根據queryStringVo查詢-->
<select id="findByVo" resultType="com.liuzeyu.domin.User" parameterType="com.liuzeyu.vo.QueryStringVo">
select * from user where username like #{user.username}
<!-- select * from user where username like '%${value}%' -->
</select>
4. 數據庫表字段和實體類屬性不一致問題
解決方法有兩個:
方法一:通過對發送的sql語句字段名取別名來處理
<!-- 打印user表數據 -->
<select id="findAll" resultType="com.liuzeyu.domin.User">
<!-- 取別名來和實體類產生關係 -->
<!--SELECT id as userId,username as userName,address as userAddress,birthday as userBirthday ,sex as userSex from user -->
</select>
其中userId,userName,userAddress,userBirthday ,userSex 是實體類的屬性。
對應的數據庫列名:id,username,address,birthday,sex
這樣查詢出來的結果的字段名就是userId,userName,userAddress,userBirthday ,userSex ,此時就與實體類一一對應了。
方法二:通過配置文件來實現:
<!-- 配置查詢的列名和實體類直接的對應關係-->
<resultMap id="userMap" type="com.liuzeyu.domin.User">
<!-- 主鍵id對應,property="userId"實體類屬性, column="id"數據庫列字段名-->
<id property="userId" column="id"/>
<!-- 非主鍵字段的對應關係-->
<result property="userName" column="username"/>
<result property="userAddress" column="address"/>
<result property="userBirthday" column="birthday"/>
<result property="userSex" column="sex"/>
</resultMap>
在操作數據庫的標籤內添加resultMap屬性引用即可,如:
<!-- 打印user表數據 -->
<select id="findAll" resultType="com.liuzeyu.domin.User" resultMap="userMap">
SELECT * from USER
</select>
方法一比方法二的執行效率更高,但是方法二比方法一開發效率更高,就是說當項目比較大時,使用方法二會提高開發效率。
5. 優化主配置文件
- 引用外部連接數據庫的連接信息
在主配置文件下< configuration >標籤內部添加properties 的resource配置或url配置引用外部配置文件
<!-- 配置標籤內部的屬性連接數據庫的信息,可以通過引用外部資源文件-->
<!--1. resource的配置方式-->
<!--<properties resource="jdbcConfig.properties">-->
<!--</properties>-->
<!--2. url的配置方式-->
<!--
url 與 uri的區別
url:uniform resource locator 統一資源定位 唯一標識一個資源的位置
寫法:
協議://主機:端口/uri
http://localhost:80/servlet/index
uri:uniform resource Identifier 統一資源標識 在應用中唯一定位一個資源
-->
<properties url="file:\\\C:\Users\lzy\IdeaProjects\day02_mybatis_modify\src\main\resources\jdbcConfig.properties">
</properties>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis
jdbc.username=root
jdbc.password=809080
之後再JDBC的連接池裏面以$獲取實際配置文件中的值
<!-- JDBC連接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
- 爲標籤屬性取別名
取完別名後,可以再映射配置文件中直接使用
<!--自定義爲配置文件取別名-->
<typeAliases>
<!--<typeAlias type="com.liuzeyu.domin.User" alias="user"/>-->
<package name="com.liuzeyu.domin"/>
</typeAliases>
使用typeAlias 標籤去別名和package有一個區別?
typeAlias 指定type對象後,alias是別名,並且再映射配置文件中使用它可以不區分大小寫,如:
package標籤是指定取別名的包,當指定後,該包下所有的實體類都會被指定別名,並且類名就是別名,不再區分大小寫。
-
簡化主配置的映射接口配置
<mappers> <!--<mapper resource="com/liuzeyu/dao/IUserDao.xml"></mapper>--> <package name="com.liuzeyu.dao"></package> </mappers>
上面這種配置有一個好處是,再package標籤下指定dao接口所在的包,就可以不用再寫mapper以及class和resource屬性了,它可以直接找到映射配置文件