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">
<!--mybatis的主配置文件-->
<configuration>
<!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
<typeAliases>
<!--typeAlias用于配置别名。type属性指定的是实体类全限定类名。alias属性指定别名,当指定了别名就再区分大小写
<typeAlias type="com.jh.domain.User" alias="user"></typeAlias>-->
<!-- 用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
<package name="com.jh.domain"></package>
</typeAliases>
<!--配置环境-->
<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/mybatis?serverTimezone=GMT%2B8"/>
<property name="username" value="root"/>
<property name="password" value="jh7851192"/>
</dataSource>
</environment>
</environments>
<!--指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<!--<mapper resource="com/jh/dao/IUserDao.xml"/>-->
<!-- package标签是用于指定dao接口所在的包,当指定了之后就不需要在写mapper以及resource或者class了 -->
<package name="com.jh.dao"></package>
</mappers>
</configuration>
1. 一对一映射:一个用户(user)对一个账户(account)
(1)要在IAccountDao.xml中配置account和user的resultMap,还有属性名和查询列名对应关系,如下:
注意:如果属性名与查询字段名一致,可以不用配置对应关系(User类不用配置也行)
(2)sql内连接查询语句如下(返回类型是Account实体类)
resultMap=“accountUserMap”–>type=“account”
<!--配置查询所有-->
<select id="findAll" resultMap="accountUserMap">
select u.*,a.id as aid,a.uid,a.money from account a,user u where u.id=a.uid;<!--内连接:account a,user u逗号是join,where是on-->
</select>
(3)代码:(User,Account,IAccountDao,AccountTest,IAccountDao.xml)
Account.java主体类
- 属性名与account表字段名相关;
- 从表(account)实体应该包含一个主表(user)实体的对象引用: private User user
- 省略了set和get,toString方法
package com.jh.domain;
import java.io.Serializable;
/**
* 账户信息:一对一映射:一个用户(user)对一个账户(account)
* */
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//一对一映射要求:从表(account)实体应该包含一个主表(user)实体的对象引用
private User user;
}
IAccountDao接口
package com.jh.dao;
import com.jh.domain.Account;
import com.jh.domain.AccountUser;
import java.util.List;
/**
* 查询所有账户,同时还要获取到当前账户的所属用户信息
* 一对一映射:一个用户(user)对一个账户(account)
* */
public interface IAccountDao {
//1.查询所有账户
List<Account> findAll();
//2.查询所有账户,并且带有用户名称和地址信息
List<AccountUser> findAllAccount();
}
一对一测试AccountTest.java
package com.jh.test;
/**一对一映射:一个用户(user)对一个账户(account)*/
import com.jh.dao.IAccountDao;
import com.jh.domain.Account;
import com.jh.domain.AccountUser;
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.InputStream;
import java.util.List;
public class AccountTest {
private InputStream in;
private SqlSession sqlSession;
private IAccountDao accountDao;
@Before//用于在测试方法执行之前执行
public void init() throws Exception {
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory工厂模式
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession(true);//手动提交事务
//4.获取dao的代理对象
accountDao = sqlSession.getMapper(IAccountDao.class);
}
@After//用于在测试方法执行之后执行
public void destroy() throws Exception {
/*//提交事务
sqlSession.commit();*/
//6.释放资源
sqlSession.close();
in.close();
}
//一对一映射:一个用户(user)对一个账户(account)如下:
public void testfindAll() {
List<Account> accounts = accountDao.findAll();
for (Account account : accounts) {
System.out.println("---每个account的信息:包括account和user");
System.out.println(account);
System.out.println(account.getUser());
}
}
}
结果:
一对一映射:一个用户(user)对一个账户(account):
---每个account的信息:包括account和user
Account{id=1, uid=46, money=1000.0}
User{id=46, username='老王', address='北京', sex='男', birthday=Wed Mar 07 17:37:26 CST 2018}
---每个account的信息:包括account和user
Account{id=2, uid=45, money=1000.0}
User{id=45, username='传智播客', address='北京金燕龙', sex='男', birthday=Sun Mar 04 12:04:06 CST 2018}
---每个account的信息:包括account和user
Account{id=3, uid=46, money=2000.0}
User{id=46, username='老王', address='北京', sex='男', birthday=Wed Mar 07 17:37:26 CST 2018}
2. 一对多映射:一个用户(user)对多个账户(account)
(1)在IUserDao.xml中配置二者关系
注意:如果属性名与查询字段名一致,可以不用配置对应关系(User类不用配置也行)
(2)sql外连接查询语句(返回类型User)
这个查询语句没有将account查询的a.id as aid,所以上述xml配置的column=aid将查询不到id信息,即为null.
<!--配置查询所有-->
<select id="findAll" resultMap="userAccountMap">
select * from user u left outer join account a on u.id = a.uid<!--左外连接,左边user作主表-->
</select>
(3)代码:(Account,User,IUserDao,UserTest,IUserDao.xml)
User.java
- User属性名与user表字段名相关
- 主表实体应该包含从表实体的集合引用
private List< Account>accounts; - 省略set和get,toString()方法
package com.jh.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**一对多关系映射:一个用户(user)对多个账户(account)*/
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
//一对多关系映射:主表实体应该包含从表实体的集合引用
private List<Account>accounts;
}
IUserDao.java接口
package com.jh.dao;
import com.jh.domain.User;
import java.util.List;
/**
* 用户的持久层接口:
* 一对多关系映射:一个用户(user)对多个账户(account)
* */
public interface IUserDao {
//1.查询所有用户,同时获取到用户下所有账户的信息
List<User>findAll();
//2.根据id查询用户信息
User findById(Integer userId);
}
UserTest.java一对多测试类
package com.jh.test;
/**一对多关系映射:一个用户(user)对多个账户(account)*/
import com.jh.dao.IUserDao;
import com.jh.domain.Account;
import com.jh.domain.AccountUser;
import com.jh.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.InputStream;
import java.util.List;
public class UserTest {
private InputStream in;
private SqlSession sqlSession;
private IUserDao userDao;
@Before//用于在测试方法执行之前执行
public void init() throws Exception {
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory工厂模式
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession(true);//手动提交事务
//4.获取dao的代理对象
userDao = sqlSession.getMapper(IUserDao.class);
}
@After//用于在测试方法执行之后执行
public void destroy() throws Exception {
/*//提交事务
sqlSession.commit();*/
//6.释放资源
sqlSession.close();
in.close();
}
@Test
public void testfindAll() {
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println("---每个用户的信息:包括account和user");
System.out.println(user);
System.out.println(user.getAccounts());
}
}
}
结果:
测试查询所有(一对多关系映射结果):抽取一个一对多的,"一个老王对2个账户"
User{id=46, username='老王', address='北京', sex='男', birthday=Wed Mar 07 17:37:26 CST 2018}
[Account{id=null, uid=46, money=1000.0}, Account{id=null, uid=46, money=2000.0}]
3. 2个完整的xml文件
IAccountDao.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.jh.dao.IAccountDao">
<!--一对一映射:一个用户(user)对一个账户(account)-->
<!--定义封装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的内容:以uid这个字段来获取关系映射-->
<association property="user" column="uid" javaType="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
</association>
</resultMap>
<!--配置查询所有-->
<select id="findAll" resultMap="accountUserMap">
select u.*,a.id as aid,a.uid,a.money from account a,user u where u.id=a.uid;<!--内连接:account a,user u逗号是join,where是on-->
</select>
<!--查询账户和用户信息-->
<select id="findAllAccount" resultType="accountuser">
select a.*,u.username,u.address from account a,user u where u.id=a.uid;
</select>
<!--根据id查询用户-->
<select id="findById" parameterType="INT" resultType="com.jh.domain.Account">
select * from account where id=#{Uid}<!--这里id命名无所谓-->
</select>
</mapper>
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.jh.dao.IUserDao">
<!--一对多关系映射:一个用户(user)对多个账户(account)-->
<!-- 定义User的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></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>
</resultMap>
<!--配置查询所有-->
<select id="findAll" resultMap="userAccountMap">
select * from user u left outer join account a on u.id = a.uid<!--左外连接,左边user作主表-->
</select>
<!--根据id查询用户-->
<select id="findById" parameterType="INT" resultType="com.jh.domain.User">
select * from user where id=#{Uid}<!--这里id命名无所谓-->
</select>
<!--了解的内容:抽取重复的sql语句-->
<sql id="defaultUser">
select * from user
</sql>
</mapper>