~目录~
-
- 简述
- 一. Mybatis框架实现CRUD操作
- 二. Mybatis 的参数深入
- 2.1 QuerryVo传递pojo包装对象
- 2.2 解决实体类属性和数据库列名不一致的问题
- 三. SqlMapConfig.xml配置文件
- 3.1 配置内容
- 3.1.1 SqlMapConfig.xml 中配置的内容和顺序
- 3.2 properties(属性)
- 3.3 typeAliases(类型别名)
- 四.
- 4.1 Mybat连接池与事务的深入
- 4.2 Mybatis映射文件的sql深入
- 1. 根据条件查询
- if标签
- if where标签 用法:多条件筛选
- 根据多个id 返回查询结果 foreach
- 五. 多表查询
- 5.1 一对一的查询
- 第一种 :
- 第二种:
- 5.2 一对多查询
简述
一. Mybatis框架实现CRUD操作
crud:增加(Create)、读取(Retrieve)、更新(Update)和删除(Delete)
这个log4j.properties是导入那个资料。
在main-java-com-itheima-dao-IUserDao(接口)
package com.itheima.dao;
import com.itheima.domain.User;
import java.util.List;
public interface IUserDao
{
//显示所有用户
List<User> findAll();
//增添
void saveUser(User user);
//更新
void updateUser(User user);
//删除操作
void deleteUser(int userId);
//查询单个用户
User findById(int userId);
//根据姓名模糊查询
List<User> findByName(String username);
//返回记录总数
int findTotal();
}
main-java-com-itheima-domain-User
package com.itheima.domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable
{
private int id;
private String username;
private String address;
private String sex;
private Date birthday;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", address='" + address + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
<?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>
<!-- String url="jdbc:mysql://localhost:3306/book?useSSL=false&serverTimezone=UTC";
String user="root";
String password="Ys04050016";
Class.forName("com.mysql.cj.jdbc.Driver")
-->
<!-- 配置环境-->
<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/eesy_mybatis?useSSL=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="Ys04050016"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/itheima/dao/IUserDao.xml"></mapper>
</mappers>
</configuration>
在resours的com-itheima.dao创建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.itheima.dao.IUserDao">
<!-- 查询所有-->
<select id="findAll" resultType="com.itheima.domain.User">
select *from user
</select>
<!-- 保存用户-->
<insert id="saveUser" parameterType="com.itheima.domain.User">
insert into user(username,address,sex,birthday)values(#{
username},#{
address},#{
sex},#{
birthday})
</insert>
<!-- 更新用户-->
<update id="updateUser" parameterType="com.itheima.domain.User">
update user set username=#{
username},address=#{
address},sex=#{
sex},birthday=#{
birthday} where id=#{
id}
</update>
<!-- 删除用户-->
<delete id="deleteUser" parameterType="int">
delete from user where id=#{
uid}
</delete>
<!-- 根据id查询一个用户-->
<select id="findById" parameterType="int" resultType="com.itheima.domain.User">
select *from user where id = #{
uid}
</select>
<!-- 根据名称模糊查询-->
<select id="findByName" parameterType="String" resultType="com.itheima.domain.User">
select *from user where username like #{
name}
</select>
<!-- 获取记录个数-->
<select id="findTotal" resultType="int">
select count(id) from user
</select>
</mapper>
在java-test-com-itheima-test-MybatisTest下测试
package com.itheima.test;
import com.itheima.dao.IUserDao;
import com.itheima.domain.User;
import jdk.internal.util.xml.impl.Input;
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.apache.ibatis.session.defaults.DefaultSqlSessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class MybatisTest
{
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before//用于测试开始前执行
public void init()throws Exception
{
//1.读取配置文件生成字节流
in= Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
factory=new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession=factory.openSession();
//4.获取dao的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After
public void destroy()throws Exception
{
//提交事务!!!!!
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
//测试查询所有操作
@Test
public void testFindAll() throws Exception
{
/*
//1.读取配置文件生成字节流
InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
SqlSession sqlSession=factory.openSession();
//4.获取dao的代理对象
IUserDao userDao=sqlSession.getMapper(IUserDao.class);
*/
//5.执行查询所有方法
List<User> users=userDao.findAll();
for(User user:users)
{
System.out.println(user);
}
/*
//6.释放资源
sqlSession.close();
in.close();
*/
}
//测试save操作
@Test
public void testSave()
{
User user=new User();
user.setUsername("小花花");
user.setAddress("泰安市");
user.setSex("男");
user.setBirthday(new Date());
//5.执行保存方法
userDao.saveUser(user);
/*
//提交事务!!!!!
sqlSession.commit();
*/
}
//测试更新操作
@Test
public void testUpdate()
{
User user=new User();
user.setId(2);
user.setUsername("邓紫棋");
user.setAddress("泰安市");
user.setSex("女");
user.setBirthday(new Date());
userDao.updateUser(user);
}
//测试删除操作!
@Test
public void testDelete()
{
userDao.deleteUser(3);
}
//查询一个
@Test
public void testFindOne()
{
User u=userDao.findById(1);
System.out.println(u);
}
//根据姓名模糊查询
@Test
public void testFindByName()
{
List<User>users=userDao.findByName("%小%");
for (User u:users)
{
System.out.println(u.toString());
}
}
//返回记录条数
@Test
public void TestfindTotal()
{
int count=userDao.findTotal();
System.out.println(count);
}
}
小知识:
@Before 在test前执行
@After 在test执行完之后执行!
执行步骤:
1.读取配置文件生成字节流
InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
SqlSession sqlSession=factory.openSession();
//4.获取dao的代理对象
IUserDao userDao=sqlSession.getMapper(IUserDao.class);
//5.执行xxxx方法
//6.释放资源
sqlSession.close();
in.close();
把重复的步骤1-4 ,6封装起来到方法中!
Mybatis与jdbc的比较
二. Mybatis 的参数深入
在写查询方法的时候,要把这个查询条件的对象,作为一个参数传递进去应该怎么用?
2.1 QuerryVo传递pojo包装对象
- 首先建立QuerryVo对象
package com.itheima.domain;
public class QuerryVo
{
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
- IUserDao编写QuerryByVo方法
3.在IUserDao.xml中编写配置
<!-- 根据QuerryVo中的条件查询用户-->
<select id="findUserByVo" parameterType="com.itheima.domain.QuerryVo" resultType="com.itheima.domain.User">
select *from user where username like #{
user.username}
</select>
- test
//测试使用QuerryVo
@Test
public void testFindByVo()
{
QuerryVo vo=new QuerryVo();
User user=new User();
user.setUsername("%小%");
vo.setUser(user);
List<User>users=userDao.findUserByVo(vo);
for (User u:users)
{
System.out.println(u);
}
}
2.2 解决实体类属性和数据库列名不一致的问题
在配置中写出关系映射。(userName →username userAddress→address********)
然后在配置方法的时候需要上边这个东西~
<!-- 查询所有-->
<select id="findAll" resultType="com.itheima.domain.User">
select *from user
</select>
改成
<!-- 查询所有-->
<select id="findAll" resultMap="userMap">
select *from user
</select>
三. SqlMapConfig.xml配置文件
3.1 配置内容
3.1.1 SqlMapConfig.xml 中配置的内容和顺序
3.2 properties(属性)
在使用 properties 标签配置时,我们可以采用两种方式指定属性配置。
第一种:
<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/eesy"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="*****"/>
</properties>
第二种
在 classpath 下定义 db.properties 文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=****
properties 标签配置此时我们的 dataSource 标签就变成了引用上面的配置
<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>
3.3 typeAliases(类型别名)
在 SqlMapConfig.xml 中配置:
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="user" type="com.itheima.domain.User"/>
<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
<package name="com.itheima.domain"/>
<package name="其它包"/>
</typeAliases>
那么配置标签的时候就可以这样:
四.
4.1 Mybat连接池与事务的深入
问题:
通俗的理解,事务是一组原子操作单元,从数据库角度说,就是一组SQL指令,要么全部执行成功,若因为某个原因其中一条指令执行有错误,则撤销先前执行过的所有指令。更简答的说就是:要么全部执行成功,要么撤销不执行。
事务必须服从ISO/IEC所制定的ACID原则。
原子性(atomicity)
一致性(consistency)
隔离性(isolation)
持久性(durability)
原子性表示事务执行过程中的任何失败都将导致事务所做的任何修改失效。
一致性表示当事务执行失败时,所有被该事务影响的数据都应该恢复到事务执行前的状态。
隔离性表示在事务执行过程中对数据的修改,在事务提交之前对其他事务不可见。
持久性表示已提交的数据在事务执行失败时,数据的状态都应该正确。
4.2 Mybatis映射文件的sql深入
1. 根据条件查询
if标签
***************************IUserDao.java
根据传入参数条件
List<User>findUserByCondition(User user);
***************************IUser.xml
<!-- 根据条件查询!!!!-->
<select id="findUserByCondition" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.User">
select *from user where 1=1
<if test="username!=null">
and username=#{
username}
</if>
</select>
***************************MybatisTest.java
通过条件查询
@Test
public void testFindByCondition()
{
User u=new User();
u.setUsername("邓紫棋");
List<User> users= userDao.findUserByCondition(u);
for (User uu:users) {
System.out.println(uu);
}
}
或者再加
<!-- 根据条件查询!!!!-->
<select id="findUserByCondition" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.User">
select *from user where 1=1
<if test="username!=null">
and username=#{
username}
</if>
<if test="username!=null">
and username=#{
username}
</if>
</select>
if where标签 用法:多条件筛选
<select id="findUserByCondition" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.User">
select *from user
<where>
<if test="username!=null">
and username=#{
username}
</if>
<if test="sex!=null">
and sex=#{
sex}
</if>
</where>
</select>
根据多个id 返回查询结果 foreach
QuerryVo.java
在QuerryVo中加上一个list属性并设置getset方法!
private List<Integer>ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
IUserDao 接口中加上方法
List<User>findUserInids(QuerryVo vo);
IUserDao.xml
<!-- 根据vo的id集合查询-->
<select id="findUserInids" resultType="com.itheima.domain.User" parameterType="com.itheima.domain.QuerryVo">
select *from user
<where>
<if test="ids!=null and ids.size()>0">
<foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
#{
uid}
-- 和item对应
</foreach>
</if>
</where>
</select>
五. 多表查询
5.1 一对一的查询
从表实体应该包含一个主表实体的对象引用
第一种 :
定义账户实体类 Account ,AccountUser封装查询结果,
定义持久层IAccountDao,方法: List< AccountUser >findAll();
定义 AccountDao.xml 文件中的查询配置信息
<!-- 查询所有-->
<select id="findAll" resultMap="accountUserMap">
select a.*,u.username,u.address from account a, user u where u.id=a.uid
</select>
最后test!
第二种:
在 Account 类中加入 User 类的对象作为 Account 类的一个属性。
修改 AccountDao 接口中的方法 List< Account >findAll();
修改xml
<!-- 定义封装account和user的resultMap 可以解决属性名和字段名不一致-->
<resultMap id="accountUserMap" type="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!-- 一对一的关系映射,配置封装user内容-->
<!-- 可以用别名 javatype-->
<association property="user" column="uid" javaType="user">
<id property="id" column="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
</association>
</resultMap>
<!-- 查询所有-->
<select id="findAll" resultMap="accountUserMap">
select a.*,u.username,u.address from account a, user u where u.id=a.uid
</select>
然后test
@Test
public void testFindAll()
{
List<Account> list=accountDao.findAll();
for (Account a:list)
{
System.out.println(a);
System.out.println(a.getUser());
}
}
5.2 一对多查询
一对多关系映射,主表实体应该包含从表实体的集合引用
User 类加入 List< Account >
用户持久层 Dao 接口中加入查询方法 List< User > findAll();
用户持久层 Dao 映射文件配置
<!-- 定义user的resultmap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="adress" column="adress"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!-- 配置user对象中accounts集合的映射-->
<collection property="accounts" ofType="account">
<id column="aid" property="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
</collection>
<!-- column是对对应的列名-->
</resultMap>
<!-- 查询所有-->
<select id="findAll" resultMap="userAccountMap">
select * from user u left outer join account a on u.id=a.uid
</select>
测试
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before//用于测试开始前执行
public void init()throws Exception
{
//1.读取配置文件生成字节流
in= Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
factory=new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession=factory.openSession();
//4.获取dao的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After
public void destroy()throws Exception
{
//提交事务!!!!!
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
//查询账户切带有用户信息
@Test
public void testFindAllAccount()
{
List<User> users=userDao.findAll();
for(User u:users)
{
System.out.println(u);
System.out.println(u.getAccounts());
}
}