mybatis mysql crud_Mybatis实现CRUD操作
Mybatis實(shí)現(xiàn)CRUD操作
導(dǎo)入相關(guān)依賴
創(chuàng)建實(shí)體類User
創(chuàng)建Mybatis主配置文件:SqlMapConfig.xml
創(chuàng)建IUserDao接口。
創(chuàng)建于接口對(duì)應(yīng)的映射配置文件:IUserDao.xml
創(chuàng)建測(cè)試類:MybatisTest
查詢所有用戶操作:findAll
添加用戶操作:saveUser
更新用戶操作:updateUser
刪除用戶操作:deleteUser
根據(jù)id查詢一個(gè)用戶信息:findById
模糊查詢操作:findAllByName
查詢用戶總記錄條數(shù):findTotal
獲得插入用戶的id: getIdAfterInsert 【重點(diǎn)】
OGNL表達(dá)式 【重點(diǎn)】
參數(shù)深入(QueryVo類)【重點(diǎn)】
返回值深入(解決實(shí)體類與表字段命名不相同時(shí)候的返回值封裝失敗問題)【重點(diǎn)】
導(dǎo)入相關(guān)依賴
jar
org.mybatis
mybatis
3.4.5
mysql
mysql-connector-java
5.1.32
log4j
log4j
1.2.17
junit
junit
4.12
創(chuàng)建實(shí)體類User
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//get、set、toString方法省略
}
創(chuàng)建Mybatis主配置文件:SqlMapConfig.xml
導(dǎo)入主配置文件約束
> <?xml version="1.0" encoding="UTF-8"?>
> /p>
> PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
> "http://mybatis.org/dtd/mybatis-3-config.dtd">
配置環(huán)境
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
創(chuàng)建IUserDao接口。路徑與中配置的路徑相同
public interface IUserDao {
}
創(chuàng)建于接口對(duì)應(yīng)的映射配置文件:IUserDao.xml 路徑與中配置的路徑相同,只是在resources中
導(dǎo)入映射文件約束
> <?xml version="1.0" encoding="UTF-8"?>
> /p>
> PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
創(chuàng)建測(cè)試類:MybatisTest
package itlearn.zhi.test;
import itlearn.zhi.dao.IUserDao;
import itlearn.zhi.domain.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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class MybatisTest {
private InputStream in;
private SqlSession session;
private IUserDao dao;
//定義初始化方法,并設(shè)置@Before:在測(cè)試方法執(zhí)行前執(zhí)行
@Before
public void init() throws IOException {
//1.讀取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.創(chuàng)建SqlSessionFactory工廠
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3.使用工廠生產(chǎn)SqlSession對(duì)象:相當(dāng)于Connection對(duì)象
session = factory.openSession();
//4.使用SqlSession創(chuàng)建Dao接口的代理對(duì)象
dao = session.getMapper(IUserDao.class);
}
//定義事務(wù)提交以及資源關(guān)閉方法。且設(shè)置@After:在測(cè)試方法執(zhí)行后執(zhí)行
@After
public void destory() throws IOException {
//提交事務(wù):Mybatis默認(rèn)是需要手動(dòng)提交事務(wù)的
session.commit();
//6.釋放資源
session.close();
in.close();
}
}
查詢所有用戶操作:findAll()
在接口中添加查詢所有用戶操作的方法
public interface IUserDao {
//查詢所有
public List<User> findAll();
}
在接口映射配置文件中配置findAll方法
<mapper namespace="itlearn.zhi.dao.IUserDao">
<select id="findAll" resultType="itlearn.zhi.domain.User">
SELECT * FROM USER;
</select>
</mapper>
在測(cè)試類MybatisTest中添加測(cè)試方法
@Test
public void testSelect() throws IOException {
List<User> users = dao.findAll();
for (User user : users) {
System.out.println(user);
}
}
添加用戶操作:saveUser()
在接口中添加saveUser方法
public interface IUserDao {
//保存用戶
public void saveUser(User user);
}
在接口映射配置文件中為saveUser方法添加配置
<mapper namespace="itlearn.zhi.dao.IUserDao">
<insert id="saveUser" parameterType="itlearn.zhi.domain.User">
INSERT INTO user(username,address,sex,birthday) VALUES (#{username},#{address},#{sex},#{birthday});
</insert>
</mapper>
<!--
parameterType="itlearn.zhi.domain.User":指定參數(shù)類型為User實(shí)體類
VALUES (#{username},#{address},#{sex},#{birthday});:指定參數(shù)#{username},格式為#{User類的字段名}
-->
在測(cè)試類中添加測(cè)試方法
@Test
public void testSave(){
User user = new User();
user.setUsername("光頭強(qiáng)");
user.setAddress("小森林");
user.setSex("男");
user.setBirthday(new Date());
dao.saveUser(user);
}
更新用戶操作:updateUser
在接口中添加updateUser方法
public void updateUser(User user);
在配置文件中的配置
<update id="updateUser" parameterType="itlearn.zhi.domain.User">
UPDATE user SET username = #{username},address = #{address},sex=#{sex},birthday=#{birthday} WHERE id = #{id} ;
</update>
刪除用戶操作:deleteUser
在接口中添加deleteUser方法
//根據(jù)id刪除用戶
public void deleteUser(Integer id);//也可以是int類型,建議使用包裝類型
在接口映射配置文件中配置deleteUser方法
<delete id="deleteUser" parameterType="Integer">
DELETE FROM user WHERE id = #{uid};
</delete>
<!--
如果參數(shù)類型是int/Integer類型,可以寫int/Integer/java.lang.Integer都可以
如果只有一個(gè)參數(shù),那么where條件中,只需要 #{任意字符}【重點(diǎn)】
-->
根據(jù)id查詢一個(gè)用戶信息:findById
在接口中添加findById方法
//根據(jù)id查詢用戶
public User findById(Integer id);
在接口映射配置文件中配置findById方法
<select id="findById" parameterType="Integer" resultType="itlearn.zhi.domain.User">
SELECT * FROM user WHERE id = #{uid};
</select>
模糊查詢操作:findAllByName
在接口中添加findAllByName方法
//根據(jù)username進(jìn)行模糊查詢
public List<User> findAllByName(String username);
在接口映射配置文件中配置findAllByName方法
<!-- 第一種配置 -->
<select id="findAllByName" parameterType="String" resultType="itlearn.zhi.domain.User">
SELECT * FROM user WHERE username LIKE '%${value}%';
</select>
<!--
在配置模糊查詢時(shí)候,需要使用 '%${value}%',其中${value}是固定不變的,只能是value,區(qū)分大小寫。
這種配置方式,在執(zhí)行的時(shí)候?qū)嶋H是執(zhí)行的: Preparing: SELECT * FROM user WHERE username LIKE '%王%'; 是字符串的拼接---【不推薦使用】
-->
<!-- 第二種配置 -->
<select id="findAllByName" parameterType="String" resultType="itlearn.zhi.domain.User">
SELECT * FROM user WHERE username LIKE #{name};
</select>
<!--
這種配置要在調(diào)用方法中使用dao.findAllByName("%王%");
這種配置在執(zhí)行時(shí):Preparing: SELECT * FROM user WHERE username LIKE ?;
Parameters: %王%(String)
實(shí)際上是使用的PrepareStatement預(yù)處理---【推薦使用】
-->
添加測(cè)試方法
@Test
public void testFindAllByName(){
List<User> users = dao.findAllByName("%王%"); //指定模糊查詢
for (User user : users) {
System.out.println(user);
}
}
查詢用戶總記錄條數(shù):findTotal
在接口中添加該方法
//查詢記錄總條數(shù)
public Integer findTotal();
在接口映射配置文件中配置該方法
<select id="findTotal" resultType="Integer">
SELECT COUNT(id) FROM user;
</select>
獲得插入用戶的id: getIdAfterInsert
在接口中添加該方法
public void getIdAfterInsert(User user);
在接口映射文件中配置該方法
<insert id="getIdAfterInsert" parameterType="itlearn.zhi.domain.User">
<selectKey keyProperty="id" keyColumn="id" resultType="Integer" order="AFTER">
SELECT last_insert_id();
</selectKey>
INSERT INTO user(username,address,sex,birthday) VALUES (#{username},#{address},#{sex},#{birthday});
</insert>
<!--
<selectKey></selectKey>標(biāo)簽中屬性:
keyProperty="id" :對(duì)應(yīng)實(shí)體類屬性名
keyColumn="id" :對(duì)應(yīng)數(shù)據(jù)庫中字段名稱
resultType="Integer" : 返回值類型
order="AFTER" : 表示在insert語句執(zhí)行之后執(zhí)行此語句。
SELECT last_insert_id(); :查詢插入最后一條記錄的id值
-->
定義測(cè)試方法
@Test
public void testGetId(){
User user = new User();
user.setUsername("邪惡小法師");
user.setAddress("邪惡森林");
user.setSex("男");
user.setBirthday(new Date());
dao.getIdAfterInsert(user);
System.out.println(user.getId()); //打印輸出:51
}
OGNL表達(dá)式
Object Graphic Navigation Language 對(duì)象圖導(dǎo)航語言
它是通過對(duì)象的取值方法來獲取數(shù)據(jù),只不過在寫法上把get給省略了
比如:我們獲取用戶的名稱:
? 類中的寫法:user.getUsername()
? OGNL表達(dá)式寫法:user.username
那么:Mybatis中為什么直接寫username,而不用user. 的方式呢?
? 因?yàn)樵赑arameterType中已經(jīng)指定了屬性所屬的類,所以此時(shí)不需要再寫對(duì)象名。
當(dāng)有多個(gè)參數(shù),且分屬不同類時(shí),創(chuàng)建QueryVo對(duì)象,封裝各個(gè)參數(shù),使參數(shù)只有QueryVo一個(gè)
參數(shù)深入(QueryVo類)概念理解
所謂的QueryVo類就是將所有的查詢條件進(jìn)一步封裝到一個(gè)對(duì)象中,這個(gè)對(duì)象就叫查詢條件對(duì)象(QueryVo),在傳遞參數(shù)的時(shí)候,統(tǒng)一傳遞此QueryVo對(duì)象,然后在指定參數(shù)#{}的時(shí)候,使用OGNL表達(dá)式,即使用"user.username"的形式。其中,user為QueryVo的屬性,username為user類的屬性。具體看代碼實(shí)現(xiàn)。
創(chuàng)建QueryVo類,封裝參數(shù)
package itlearn.zhi.domain;
public class QueryVo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
在接口中定義模糊查詢方法,參數(shù)為QueryVo
public List<User> queryUser(QueryVo vo);
在接口映射配置文件中配置方法
<select id="queryUser" parameterType="itlearn.zhi.domain.QueryVo" resultType="itlearn.zhi.domain.User">
SELECT * FROM user WHERE username LIKE #{user.username};
</select>
<!-- 指定的參數(shù)類型為QueryVo類型,在sql語句中使用#{user.username} ,即OGNL表達(dá)式-->
測(cè)試方法
@Test
public void testQueryUser(){
QueryVo vo = new QueryVo();
User user = new User();
user.setUsername("%王%");
vo.setUser(user);
List<User> users = dao.queryUser(vo);
for (User user1 : users) {
System.out.println(user1);
}
返回值深入(解決實(shí)體類與表字段命名不相同時(shí)候的返回值封裝失敗問題)
概念解析
1. 當(dāng)我們命名的實(shí)體類屬性值和數(shù)據(jù)表字段值相同的時(shí)候,執(zhí)行查詢,查詢到的結(jié)果會(huì)通過【反射】的方式自動(dòng)封裝成對(duì)應(yīng)的實(shí)體類對(duì)象。
2. 但是當(dāng)我們的實(shí)體類屬性命名和數(shù)據(jù)表字段值不相同的時(shí)候,則查詢結(jié)果不能通過反射自動(dòng)封裝成對(duì)應(yīng)的實(shí)體類對(duì)象,這時(shí)就需要通過別的方式來幫助查詢結(jié)果封裝到對(duì)應(yīng)的實(shí)體類對(duì)象中
3. 當(dāng)實(shí)體類屬性命名和數(shù)據(jù)表字段值不相同的時(shí)候通常有兩種方式來幫助查詢結(jié)果封裝到指定對(duì)象中。
一:在查詢的時(shí)候,給數(shù)據(jù)表的字段起一個(gè)與實(shí)體類中屬性一樣的別名。即在sql語句中使用 as 關(guān)鍵字
二:手動(dòng)在與dao層接口映射的配置文件中指定實(shí)體類屬性值與數(shù)據(jù)表字段的映射關(guān)系
兩種方法的解析
在查詢的時(shí)候,給數(shù)據(jù)表的字段起一個(gè)與實(shí)體類中屬性一樣的別名?!拘瘦^高】
<select id="findAll" resultType="itlearn.zhi.domain.User">
select (數(shù)據(jù)表中的字段值) AS (實(shí)體類中與數(shù)據(jù)表字段值對(duì)應(yīng)的屬性值),xxx AS xxx FROM (表名)
</select>
手動(dòng)在與dao層接口映射的配置文件中指定實(shí)體類屬性值與數(shù)據(jù)表字段的映射關(guān)系【開發(fā)效率較高】
<!-- 配置查詢結(jié)果的列名和實(shí)體類中屬性值對(duì)應(yīng)關(guān)系 -->
<resultMap id="userMap" type="cn.zhi.domain.User">
<!-- 主鍵的對(duì)應(yīng) -->
<id property="userId" column="id"></id>
<!-- 非主鍵的對(duì)應(yīng) -->
<result property="實(shí)體類屬性名" column="數(shù)據(jù)表字段名"></result>
<result property="實(shí)體類屬性名" column="數(shù)據(jù)表字段名"></result>
<result property="實(shí)體類屬性名" column="數(shù)據(jù)表字段名"></result>
<result property="實(shí)體類屬性名" column="數(shù)據(jù)表字段名"></result>
<result property="實(shí)體類屬性名" column="數(shù)據(jù)表字段名"></result>
</resultMap>
<!-- 在配置查詢時(shí)候,指定映射關(guān)系 -->
<select id="" resultMap="userMap">
select * from user
</select>
解析:
1. 所有的配置要寫在<resultMap>標(biāo)簽內(nèi)
2. 個(gè)<resultMap>指定一個(gè)標(biāo)識(shí)id:<resultMap id="userMap">
3. 給<resultMap>指定返回值封裝成的對(duì)象類型:type="cn.zhi.domain.User"
4. 主鍵的配置:<id property="userId" column="id"></id>
property:值為實(shí)體類中與數(shù)據(jù)表中主鍵對(duì)應(yīng)的屬性名
column: 值為數(shù)據(jù)表中的主鍵字段值
5. 非主鍵的對(duì)應(yīng)使用<result>標(biāo)簽
property:值為實(shí)體類中與數(shù)據(jù)表中非主鍵對(duì)應(yīng)的屬性名
column: 值為數(shù)據(jù)表中的非主鍵字段名
總結(jié)
以上是生活随笔為你收集整理的mybatis mysql crud_Mybatis实现CRUD操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在日常饮食中合理搭配营养?
- 下一篇: linux cmake编译源码,linu