一、自定义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 映射文件名称相同,且放在同一个目录中。