一、自定義mybatis開發流程圖(回顧)
二、mybatis增刪改查
代碼:
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>org.example</groupId>
<artifactId>mybatis_crud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13-beta-3</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
IUserDao:
package com.zibo.mybatis_crud.dao;
import com.zibo.mybatis_crud.domain.User;
import java.util.List;
public interface IUserDao {
//查詢所有
List<User> findAll();
//保存一條數據
void save(User user);
//更新一條數據
void update(User user);
//刪除一條數據
void delete(Integer userId);
//根據id查詢一條數據
User findById(Integer userId);
//通過名字模糊查詢
List<User> findByName(String username);
//查詢用戶數量
int findTotal();
}
User:
package com.zibo.mybatis_crud.domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
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;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
IUserDao.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">
<mapper namespace="com.zibo.mybatis_crud.dao.IUserDao">
<!--配置查詢所有-->
<select id="findAll" resultType="com.zibo.mybatis_crud.domain.User">
select * from user;
</select>
<!--保存-->
<insert id="save" parameterType="com.zibo.mybatis_crud.domain.User">
# 配置保存數據後獲取所保存數據的id
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,address,sex,birthday) values(#{username},#{address},#{sex},#{birthday});
</insert>
<!--更新-->
<update id="update" parameterType="com.zibo.mybatis_crud.domain.User">
update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id};
</update>
<!--刪除-->
<delete id="delete" parameterType="Integer">
delete from user where id = #{只有一個屬性可以隨便寫僅作爲佔位符};
</delete>
<!--查詢一條數據-->
<select id="findById" parameterType="Integer" resultType="com.zibo.mybatis_crud.domain.User">
select * from user where id = #{隨便寫};
</select>
<!--模糊查詢-->
<select id="findByName" parameterType="String" resultType="com.zibo.mybatis_crud.domain.User">
select * from user where username like #{隨便寫};
# 提前指定%的固定寫法,必須是value,不能隨便寫,此法不常用
# select * from user where username like '%${value}%';
</select>
<!--查詢用戶數-->
<select id="findTotal" resultType="Integer">
select count(id) from user;
</select>
</mapper>
log4j.properties:
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
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">
<!-- 配置數據庫的4個基本信息-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/zibo?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="zibo15239417242"/>
</dataSource>
</environment>
</environments>
<!-- 指定映射配置文件的位置-->
<mappers>
<mapper resource="com/zibo/mybatis_crud/dao/IUserDao.xml"/>
</mappers>
</configuration>
Main:
package com.zibo.mybatis_crud;
import com.zibo.mybatis_crud.dao.IUserDao;
import com.zibo.mybatis_crud.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 Main {
private InputStream in;
private SqlSession sqlSession;
private IUserDao iUserDao;
/**
* 初始化
*/
@Before
public void init() throws IOException {
//1、讀取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2、創建SqlSessionFactory工廠
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//3、使用工廠生產SqlSession對象,true表示自動提交事務
sqlSession = factory.openSession(true);
//4、使用SqlSession創建Dao接口的代理對象
iUserDao = sqlSession.getMapper(IUserDao.class);
}
@After
public void end() throws IOException {
//6、釋放資源
sqlSession.close();
in.close();
}
/**
* 測試查詢所有
*/
@Test
public void testFindAll(){
//5、使用代理對象執行方法
List<User> users = iUserDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
@Test
public void testSave(){
//構建一條數據
User user = new User();
user.setUsername("大哥");
user.setSex("男");
user.setAddress("河南周口");
user.setBirthday(new Date());
System.out.println("保存前"+user);
//執行操作
//5、使用代理對象執行方法
iUserDao.save(user);
System.out.println("保存後"+user);
}
@Test
public void testUpdate(){
//構建一條數據
User user = new User();
user.setId(49);
user.setUsername("大哥PRO");
user.setSex("男");
user.setAddress("河南周口商水舒莊");
user.setBirthday(new Date());
//5、使用代理對象執行方法
iUserDao.update(user);
}
@Test
public void testDelete(){
//5、使用代理對象執行方法
iUserDao.delete(49);
}
@Test
public void testFindById(){
//5、使用代理對象執行方法
User user = iUserDao.findById(45);
System.out.println(user);
}
@Test
public void testFindByName(){
//5、使用代理對象執行方法
List<User> users = iUserDao.findByName("%王%");
for (User user : users) {
System.out.println(user);
}
}
@Test
public void testFindTotal(){
//5、使用代理對象執行方法
int total = iUserDao.findTotal();
System.out.println(total);
}
}
三、Mybatis參數深入
1、Mybatis的參數
傳遞簡單類型;
如int,String等
傳遞pojo對象;
(Java Bean(實體類對象),Mybatis使用ognl表達式解析對象字段的值,#{}或者${}括號中的值爲pojo屬性名稱)
ognl表達式:Object Graphic Navigation Language對象圖導航語言,它是通過對象的祛痣方法來獲取數據,在寫法上把get給省略了
例如:我們獲取用戶名的寫法,類中的寫法:user.getUsername();OGNL表達式的寫法:user.username;
而在Mybatis爲什麼只需要username不需要user.?因爲parameType中已經提供了屬性所述的類,所以不需要對象名了;
傳遞pojo包裝對象;
開發中通過pojo傳遞查詢條件,查詢條件是綜合的查詢條件,不僅包括用戶查詢條件還包括其他的查詢條件(比如將用戶購買商品信息也作爲查詢條件),這時可以使用包裝對象傳遞輸入參數,Pojo類中包含pojo。
需求:根據用戶名查詢用戶信息,則可將查詢條件放到QueryVo的user屬性中;
IUserDao代碼補充:
//根據queryVo查詢條件查詢用戶
List<User> findByQueryVo(QueryVo queryVo);
IUserDao.XML代碼補充:
<!--根據queryVo查詢條件查詢用戶-->
<select id="findByQueryVo" parameterType="com.zibo.mybatis_crud.domain.QueryVo" resultType="com.zibo.mybatis_crud.domain.User">
select * from user where username like #{user.username};
</select>
Main代碼補充:
@Test
public void testFindByQueryVo(){
User user = new User();
user.setId(49);
user.setUsername("%哥%");
user.setSex("男");
user.setAddress("河南周口商水舒莊");
user.setBirthday(new Date());
QueryVo queryVo = new QueryVo();
queryVo.setUser(user);
//5、使用代理對象執行方法
List<User> users = iUserDao.findByQueryVo(queryVo);
System.out.println("===============查詢到的數據條數爲:"+users.size());
for (User user0 : users) {
System.out.println(user0);
}
}
2、Mybatis輸出結果封裝
resultType 屬性可以指定結果集的類型,它支持基本類型和實體類(pojo)類型(或實體類列表)。
MySQL數據庫在Windows系統下不區分大小寫,在Linux系統下嚴格區分大小寫;
解決實體類屬性和數據庫列名不對應的兩種方式:
方式一:起別名
select id as userId,username as usernName,address as userAddress,sex as userSex,birthday as userBirthday from user;
方式二:配置查詢結果的列名和實體類的屬性名的對應關係
<!--配置查詢結果的列名和實體類的屬性名的對應關係-->
<resultMap id="user" type="com.zibo.mybatis_crud.domain.User">
<!--主鍵字段的對應-->
<id property="userId" column="id"/>
<!--非主鍵字段的對應-->
<result property="userName" column="username"/>
<result property="userAddress" column="address"/>
<result property="userSex" column="sex"/>
<result property="userBirthday" column="birthday"/>
</resultMap>、
使用的時候使用resultMap="user",第二種方式沒有第一種方式執行效率高,但是開發效率高了;
四、通過編寫Dao實現類的方式實現增刪改查(僅查詢,其他類似)
變動代碼,其他代碼與上面一致:
IUserDaoImpl:
package com.zibo.mybatis_crud.dao;
import com.zibo.mybatis_crud.domain.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
public class IUserDaoImpl implements IUserDao {
private SqlSessionFactory factory;
public IUserDaoImpl(SqlSessionFactory factory) {
this.factory = factory;
}
@Override
public List<User> findAll() {
//1、根據factory獲取SqlSession對象,true表示自動提交事務
SqlSession sqlSession = factory.openSession(true);
//2、調用sqlSession中的方法實現查詢方法
List<User> users = sqlSession.selectList("com.zibo.mybatis_crud.dao.IUserDao.findAll");
//3、釋放資源
sqlSession.close();
return users;
}
@Override
public void save(User user) {
}
@Override
public void update(User user) {
}
@Override
public void delete(Integer userId) {
}
@Override
public User findById(Integer userId) {
return null;
}
@Override
public List<User> findByName(String username) {
return null;
}
@Override
public int findTotal() {
return 0;
}
}
Main:
package com.zibo.mybatis_crud;
import com.zibo.mybatis_crud.dao.IUserDao;
import com.zibo.mybatis_crud.dao.IUserDaoImpl;
import com.zibo.mybatis_crud.domain.User;
import org.apache.ibatis.io.Resources;
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 Main {
private InputStream in;
private IUserDao iUserDao;
/**
* 初始化
*/
@Before
public void init() throws IOException {
//1、讀取配置文件
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2、創建SqlSessionFactory工廠
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//4、使用SqlSession創建Dao接口的代理對象
iUserDao = new IUserDaoImpl(factory);
}
@After
public void end() throws IOException {
//6、釋放資源
in.close();
}
/**
* 測試查詢所有
*/
@Test
public void testFindAll(){
//5、使用代理對象執行方法
List<User> users = iUserDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
@Test
public void testSave(){
//構建一條數據
User user = new User();
user.setUsername("大哥");
user.setSex("男");
user.setAddress("河南周口");
user.setBirthday(new Date());
System.out.println("保存前"+user);
//執行操作
//5、使用代理對象執行方法
iUserDao.save(user);
System.out.println("保存後"+user);
}
@Test
public void testUpdate(){
//構建一條數據
User user = new User();
user.setId(49);
user.setUsername("大哥PRO");
user.setSex("男");
user.setAddress("河南周口商水舒莊");
user.setBirthday(new Date());
//5、使用代理對象執行方法
iUserDao.update(user);
}
@Test
public void testDelete(){
//5、使用代理對象執行方法
iUserDao.delete(49);
}
@Test
public void testFindById(){
//5、使用代理對象執行方法
User user = iUserDao.findById(45);
System.out.println(user);
}
@Test
public void testFindByName(){
//5、使用代理對象執行方法
List<User> users = iUserDao.findByName("%王%");
for (User user : users) {
System.out.println(user);
}
}
@Test
public void testFindTotal(){
//5、使用代理對象執行方法
int total = iUserDao.findTotal();
System.out.println(total);
}
}
五、properties(屬性)
在使用 properties 標籤配置時,我們可以採用兩種方式指定屬性配置:
第一種:
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/zibo?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="zibo15239417242"/>
第二種:
1、在 classpath 下定義 jdbc.properties 文件
代碼:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=1234
位置:
2、 properties 標籤配置
<!-- 配置連接數據庫的信息:
resource 屬性:用於指定 properties 配置文件的位置,要求配置文件必須在類路徑下
resource="jdbcConfig.properties"
url 屬性:
URL: Uniform Resource Locator 統一資源定位符
http://localhost:8080/mystroe/CategoryServlet URL
協議 主機 端口 URI
URI:Uniform Resource Identifier 統一資源標識符
/mystroe/CategoryServlet
它是可以在 web 應用中唯一定位一個資源的路徑
-->
<!-- url內填寫配置文件的絕對路徑-->
<properties resource="jdbc.properties">
</properties>
<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(類型別名)
自定義別名:
<!-- 在 SqlMapConfig.xml 中配置: -->
<typeAliases>
<!-- 單個別名定義 -->
<typeAlias alias="user" type="com.itheima.domain.User"/>
<!-- 批量別名定義,掃描整個包下的類,別名爲類名(首字母大寫或小寫都可以) -->
<package name="com.itheima.domain"/>
<package name="其它包"/>
</typeAliases>
七、mappers(映射器)
1、<mapper resource=" " />
使用相對於類路徑的資源
如:<mapper resource="com/itheima/dao/IUserDao.xml" />
2、<mapper class=" " />
使用 mapper 接口類路徑
如:<mapper class="com.itheima.dao.UserDao"/>
注意:此種方法要求 mapper 接口名稱和 mapper 映射文件名稱相同,且放在同一個目錄中。
3、<package name=""/>
註冊指定包下的所有 mapper 接口
如:<package name="cn.itcast.mybatis.mapper"/>
注意:此種方法要求 mapper 接口名稱和 mapper 映射文件名稱相同,且放在同一個目錄中。