文章目錄
一、環境搭建
1.創建maven工程
點擊finish即可
2.pom.xml文件導入座標
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.thinkcoder</groupId>
<artifactId>mybatis的CRUD操作</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--mybatis的依賴-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!--mysql的依賴-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--日誌依賴-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>2.12.1</version>
</dependency>
<!--單元測試依賴-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
3.項目結構總覽
從上到下依次實現代碼
IUserDao接口
- 作用:用戶的持久層接口,定義操作數據庫的方法
public interface IUserDao {
//查詢所有用戶
List<User> findAll();
// 增刪改查的方法寫到這裏
}
爲了看的清晰(好吧,我偷懶,哈哈哈),剩下的crud的操作,只寫當前的操作,就不帶之前的方法了
建表的sql腳本
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL COMMENT '用戶名稱',
`birthday` datetime DEFAULT NULL COMMENT '生日',
`sex` char(1) DEFAULT NULL COMMENT '性別',
`address` varchar(256) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=49 DEFAULT CHARSET=utf8;
User類
- 利用了ORM思想:Object Relational Mapping對象關係映射,把實體類的屬性和數據庫表對應起來,操作實體類就實現操作數據庫表
package com.thinkcoder.domain;
import java.io.Serializable;
import java.util.Date;
/**
* @ClassName User
* @Author ThinkCocer
*/
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//getter和setter方法
public Integer getId() {return id;}
public void setId(Integer id) {this.id = id;}
public String getUsername() {return username;}
public void setUsername(String username) {this.username = username;}
public Date getBirthday() {return birthday;}
public void setBirthday(Date birthday) {this.birthday = birthday;}
public String getSex() {return sex;}
public void setSex(String sex) {this.sex = sex;}
public String getAddress() {return address;}
public void setAddress(String address) {this.address = address}
//重寫tostring方法
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
IUserDao.xml映射配置文件
- 作用:和IUserDao接口方法映射,IUser接口方法對應的sql語句及返回類型
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thinkcoder.dao.IUserDao">
<!--查詢所有-->
<select id="findAll" resultType="com.thinkcoder.domain.User">
select * from user;
</select>
</mapper>
要求:因爲實現基於Dao代理對象實現,所以沒有IUserDao接口的實現類,要符合以下要求
- 1.持久層接口IUserDao接口和持久層接口的映射配置(IUserDao.xml)必須在相同包下
- 2.namespace屬性取值是IUserDao接口的全限定類名,如:com.thinkcoder.domain.User
- 3.SQL 語句配置標籤<select>,<insert>,<delete>,<update>的 id 屬性值和IUserDao接口的
方法名相同,如findAll
SqlMapConfig.xml文件
- 作用:配置數據庫環境及映射文件位置
<?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>
<!--配置環境-->
<environments default="mysql">
<!--配置mysql的環境-->
<environment id="mysql">
<!--配置事務-->
<transactionManager type="JDBC"></transactionManager>
<!--配置連接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/selfproj?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--配置映射文件的位置-->
<mappers>
<mapper resource="com/thinkcoder/dao/IUserDao.xml"></mapper>
</mappers>
</configuration>
MybatisTest類
- 作用:測試mybatis的crud操作
/**
* @ClassName MybatisTest
* @Author ThinkCoder
* 測試mybatis的crud操作
*/
public class MybatisTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao userDao;
@Before //用於測試方法執行之前執行
public void init()throws Exception{
//1.讀取配置文件,生成字節輸入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.獲取SqlSessionFactory
factory = new SqlSessionFactoryBuilder().build(in);
//3.獲取sqlsession對象
session = factory.openSession();
//4.獲取dao的代理對象
userDao = session.getMapper(IUserDao.class);
}
@After //用於測試之後執行
public void realese()throws Exception{
session.close();
in.close();
}
@Test //測試查詢所有方法
public void testFindAll() throws Exception {
//調用方法初始化
init();
//執行查詢所有方法
List<User> userList = userDao.findAll();
for(User user:userList){
System.out.println(user);
}
//調用方法釋放資源
realese();
}
}
上述代碼完成了開發環境搭建並實現了測試查詢所有用戶的信息的操作,環境搭建完後
完成crud其他操作,只需要在下面三個文件中寫代碼
- 1.IUserDao接口:增加方法
- 2.IUserDao.xml文件:配置與IUserDao接口方法對應的sql語句
- 3.MytatisTest類:寫測試接口方法的方法
二、添加用戶
IUserDao接口
public interface IUserDao{
//添加用戶
int insertUser(User user)
}
IUserDao.xml文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thinkcoder.dao.IUserDao">
<!--添加用戶-->
<insert id="insertUser" parameterType="com.thinkcoder.domain.User">
insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address});
</insert>
</mapper>
MybatisTest類
public class MybatisTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao userDao;
@Test//測試添加用戶的方法
public void testInsert() throws Exception{
User user = new User();
user.setUsername("渣男");
user.setBirthday(new Date());
user.setSex("男");
user.setAddress("天堂");
int res = userDao.insertUser(user);
System.out.Println(res);//1
//提交事務
session.commit();
}
//以下兩個方法分別在測試方法自動前後執行
@Before //用於測試方法執行之前執行
public void init()throws Exception{
//1.讀取配置文件,生成字節輸入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.獲取SqlSessionFactory
factory = new SqlSessionFactoryBuilder().build(in);
//3.獲取sqlsession對象
session = factory.openSession();
//4.獲取dao的代理對象
userDao = session.getMapper(IUserDao.class);
}
@After //用於測試之後執行
public void realese()throws Exception{
session.close();
in.close();
}
}
說明
- 注意下這行代碼:session.commit();
- 對於DML(增加、刪除、修改)語句,Mybatis需要手動提交事務,否則不會影響數據
- 因爲本質上Mybatis的事務是調用了JDBC的事務並將自動提交改手動提交
- 即Connection.setAutoCommit(false),這個下一篇博客分享,因此Mybatis需要手動提交事務
三、修改用戶
IUserDao接口
public interface IUserDao{
//修改用戶
int updateUser(User user);
}
IUserDao.xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thinkcoder.dao.IUserDao">
<!--修改用戶-->
<update id="updateUser" parameterType="com.thinkcoder.domain.User">
update user set username = #{username} where id=#{id}
</update>
</mapper>
MybatisTest類
public class MybatisTest {
//測試方法如上就省略了
@Test
public void testUpdate(){
User user = new User();
user.setUsername("天線寶寶");
user.setId(49);
int res = userDao.updateUser(user);
//提交事務
session.commit();
System.out.println(res);
}
}
四、刪除用戶
IUserDao接口
public interface IUserDao {
//刪除用戶
int deleteUser(Integer userId);
}
IUserDao.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thinkcoder.dao.IUserDao">
<!--刪除用戶-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete * from user where id=#{id}
</delete>
</mapper>
MybatisTest類
public class MybatisTest{
//兩個方法省略
@Test
public void testDelete(){
int res = userDao.deleteUser(49);
System.out.println("刪除成功");
//提交事務
session.commit();
}
}
五、查詢用戶
5.1根據id查詢信息
IUserDao接口
public interface IUserDao{
//根據id查詢
User findById(Integer userId);
}
IUserDao.xml文件
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thinkcoder.dao.IUserDao">
<!--根據id查詢用戶-->
<select id="findById" resultType="com.thinkcoder.domain.User" parameterType="int">
select * from user where id = #{uid}
</select>
</mapper>
MytatisTest類
public class MybatisTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao userDao;
@Test//測試根據Id查詢
public void testFindById(){
User user = userDao.findById(49);
System.out.println(user);
}
//以下兩個方法分別在測試方法自動前後執行
@Before //用於測試方法執行之前執行
public void init()throws Exception{
//1.讀取配置文件,生成字節輸入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.獲取SqlSessionFactory
factory = new SqlSessionFactoryBuilder().build(in);
//3.獲取sqlsession對象
session = factory.openSession();
//4.獲取dao的代理對象
userDao = session.getMapper(IUserDao.class);
}
@After //用於測試之後執行
public void realese()throws Exception{
session.close();
in.close();
}
}
運行結果
User{id=49, username='渣男', birthday=Sat May 23 23:00:06 CST 2020, sex='男', address='天堂'}
5.2模糊查詢
IUserDao接口
public interface IUserDao{
//根據名稱模糊查詢
List<User> findByName(String username);
}
IUserDao.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thinkcoder.dao.IUserDao">
<!--根據名字模糊查詢-->
<select id="findByName" resultType="com.thinkcoder.domain.User" parameterType="String">
select * from user where username like #{username}
</select>
</mapper>
MybatisTest類
public class MybatisTest {
//上面的兩個方法省略
@Test//測試模糊查詢
public void testFindByName()throws Exception{
List<User> users = userDao.findByName("%王%");
for(User user : users){
System.out.println(user);
}
}
}
運行結果
User{id=46, username='王五', birthday=Wed Mar 07 17:37:26 CST 2018, sex='男', address='南京'}
User{id=50, username='王七', birthday=Sat May 23 20:00:06 CST 2020, sex='女', address='上海'}
5.3查詢使用聚合函數
IUserDao接口
public interface IUserDao{
//查詢用戶總數
int findTotal();
}
IUserDao.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thinkcoder.dao.IUserDao">
<!--查詢總人數-->
<select id="findTotal" resultType="java.lang.Integer">
select COUNT(*) from user
</select>
</mapper>
MybatisTest類
public class MybatisTest {
//上面的兩個方法省略
@Test //用於測試查詢總人數方法
public void testTotal(){
int res = userDao.findTotal();
System.out.println(res);//7
}
}
5.4resultMap——解決數據庫字段和實體類屬性不一致
修改User實體類,使其屬性和數據庫字段不一致,即不符合ORM思想
public class User implements Serializable {
//屬性和數據庫字段不一致
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
//此處省略了getter和setter方法
在搭建Mybatis開發環境就實現了查詢所有的功能,因此就不寫了,哈哈
MybatisTest中類測試結果
User{userId=null, userName='張三', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='李四', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='王五', userBirthday=null, userSex='null', userAddress='null'}
User{userId=null, userName='週六', userBirthday=null, userSex='null', userAddress='null'}
Process finished with exit code 0
結果顯示除了userName有值(mysql在widows中不區分大小寫,即username和userName同效),其他值都爲null
解決辦法一:
在IUserDao.xml中,使用as別名
<mapper namespace="com.thinkcoder.dao.IUserDao">
<select id="findAll" resultType="com.thinkcoder.domain.User">
select id as userId,
username as userName,
birthday as userBirthday,
sex as userSex,
address as userAddress from user;
</select>
</mapper>
但是當數據庫字段多了之後,寫起來很費力
解決辦法二:
在IUserDao.xml中,使用resultMap封裝結果集
<mapper namespace="com.thinkcoder.dao.IUserDao">
<!--查詢所有-->
<select id="findAll" resultMap="userMap">
select * from user
</select>
<!--定義resultMap-->
<!--id屬性:給定表示用於select標籤引用--><!--type屬性:實體類全限定類名-->
<resultMap id="userMap" type="com.thinkcoder.domain.User">
<id column="id" property="userId"/>
<result column="username" property="userName"/>
<result column="sex" property="userSex"/>
<result column="address" property="userAddress"/>
<result column="birthday" property="userBirthday"/>
</resultMap>
</mapper>
resultMap子標籤的屬性說明
- id標籤:指定主鍵字段
- result標籤:指定非主鍵字段
- column屬性:指定數據庫列名
- property屬性:指定實體類屬性名稱
六、總結
IUser.Dao.xml中的屬性及字符
#{}內容格式是ognl表達式
- ognl表達式:Object Graphic Navigation Language 對象圖導航語言
- 語法格式:#{對象.對象},組成部分都看成對象,即User對象是對象,User中屬性也是對象
- 獲取數據舉例:如#{user.username},會先找user對象,然後找username屬性,調用getUsername()將值取出,因爲在parameterType屬性制定了User的全限定類名,可以省略user,即#{username}
增刪改查的操作,在實際應用中是最多的也是基礎,當然也不是特別難,但有所以咱們要好好掌握,後面博客繼續更新Mybatis事務及複雜查詢