基本写法
User.java
public class User implements Serializable{
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//省略getter/setter/toString
}
QueryVo.java
根据QueryVo中的条件查询用户时使用
public class QueryVo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
IUserDao.java
public interface IUserDao {
/*
* 查询所有操作
* */
List<User> findAll();
/*
* 保存用户
* */
void saveUser(User user);
/*
* 更新用户
* */
void updateUser(User user);
/*
* 根据id删除用户
* */
void deleteUser(Integer userId);
/*
* 根据id查询指定用户
* */
User findById(Integer userId);
/*
* 根据名称模糊查询用户信息
* */
List<User> findByName(String username);
/*
* 查询总用户数
* */
int findTotal();
/*
* 根据QueryVo中的条件查询用户*/
List<User> findUserByVo(QueryVo Vo);
}
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.liysh.dao.IUserDao">
<!--位置与IUserDao位置对应-->
<!--配置查询所有-->
<!--id=方法名-->
<select id="findAll" resultType="com.liysh.domain.User">
select * from user
</select>
<!--保存用户-->
<insert id="saveUser" parameterType="com.liysh.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="updateUser" parameterType="com.liysh.domain.User">
update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday}where id=#{id};
</update>
<!--删除用户 ,#{写成什么都可以并没有要求}-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id};
</delete>
<!--根据id查询用户-->
<select id="findById" parameterType="int" resultType="com.liysh.domain.User">
select *from user where id=#{id};
</select>
<!--根据名称模糊查询-->
<select id="findByName" parameterType="string" resultType="com.liysh.domain.User">
select *from user where username like #{name};
<!--select * from user where username like '%${value}%' 这里就必须写成value了-->
</select>
<!--获取用户的总记录条数-->
<select id="findTotal" resultType="int">
select count(id) from user;
</select>
<!--根据queryVo的条件查询用户-->
<select id="findUserByVo" parameterType="com.liysh.domain.QueryVo" resultType="com.liysh.domain.User">
select * from user where username like #{user.username};
</select>
</mapper>
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>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--配置连接数据库的四个基部信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--MySql 6以上的版本必须写成jdbc:mysql://localhost:3306/mydb1?serverTimezone=UTC-->
<property name="url" value="jdbc:mysql://localhost:3306/mydb1?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="8156v"/>
</dataSource>
</environment>
</environments>
<!--指定配置文件的位置。映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<mapper resource="com/liysh/dao/IUserDao.xml"/>
</mappers>
</configuration>
测试类
public class MybatisTest {
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();
//4.获取dao的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After
public void destroy() throws Exception{
//提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
@Test
public void testFindAll(){
//5.使用代理对象执行方法
List<User> users=userDao.findAll();
for(User user:users){
System.out.println(user);
}
}
@Test
public void testSave()throws Exception{
User user=new User();
user.setUsername("mybatis_insert");
user.setAddress("北京市顺义区");
user.setSex("男");
user.setBirthday(new Date());
System.out.println("保存操作之前"+user);
//5.执行保存方法
userDao.saveUser(user);
System.out.println("保存操作之后"+user);
}
@Test
public void testUpdate()throws Exception{
User user=new User();
user.setId(5);
user.setUsername("mybatis_update");
user.setAddress("北京市");
user.setSex("女");
user.setBirthday(new Date());
//5.执行保存方法
userDao.updateUser(user);
}
@Test
public void textDelete(){
userDao.deleteUser(5);
}
@Test
public void testFindOne(){
User user=userDao.findById(2);
System.out.println(user);
}
@Test
public void testFindByName(){
List<User> users=userDao.findByName("%王%");
for(User user:users){
System.out.println(user);
}
}
/*
* @Test
public void testFindByName(){
List<User> users=userDao.findByName("王");
for(User user:users){
System.out.println(user);
}
}
* */
@Test
public void testFindTotal(){
int count=userDao.findTotal();
System.out.println(count);
}
/*
* 测试使用QueryVo作为查询条件
* */
@Test
public void testFindByVo(){
QueryVo vo=new QueryVo();
User user=new User();
user.setUsername("%王%");
vo.setUser(user);
List<User> users=userDao.findUserByVo(vo);
for(User u:users){
System.out.println(u);
}
}
}
解决四大参数写死的问题
改动部分:
jdbcConfig.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb1?serverTimezone=UTC
jdbc.username=root
jdbc.password=8156v
SqlMapConfig.xml
引入外部配置文件
另一种写法:
配置别名:
<typeAlias type="com.liysh.domain.User" alias="user"></typeAlias>
<?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>
<properties url="file:///D:/Maven/WorkSpace/mybatis4/src/main/resources/jdbcConfig.properties">
</properties>
<!--使用typeAlias配置别名,它只能配置domain中的类的别名-->
<typeAliases>
<!--用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
<package name="com.liysh.domain"></package>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)包含 POOLED UNPOOLED JNDI-->
<dataSource type="POOLED">
<!--配置连接数据库的四个基部信息-->
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
</environment>
</environments>
<!--指定配置文件的位置。映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<!--package标签是用于指定dao接口所在的包,当指定了之后就不需求写mapper一级resource或者class-->
<package name="com.liysh.dao"></package>
</mappers>
</configuration>
注意
1 使用相对于类路径的资源
2 使用 mapper 接口类路径
此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
3 注册指定包下的所有 mapper 接口
此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
MyBatis中的数据源
1.UNPOOLED
2.POOLED
3.JNDI
MyBatis 在初始化时,根据的 type 属性来创建相应类型的的数据源 DataSource,即: type=”POOLED”:MyBatis 会创建 PooledDataSource 实例
type=”UNPOOLED” : MyBatis 会创建 UnpooledDataSource 实例
type=”JNDI”:MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用
事务提交方式
sqlSession=factory.openSession(true);设置为TRUE则变成了自动提交,不需要再commit了
@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{
//提交事务 openSession中的参数设置未true时就写commit了
// sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
动态sql语句
QueryVo.java
//用来实现由多个对象组成一个查询条件进行查询
public class QueryVo {
private User user;
private List<Integer> ids;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}
IUserDao.xml
if标签+where标签:拼接多个查询条件
@Test
public void testFindByCondition(){
User u=new User();
u.setUsername("王五");
u.setSex("女");
List<User> users=userDao.findUserByCondition(u);
for(User user:users){
System.out.println(user);
}
}
foreach标签:一个属性有多个值
@Test
public void testFindIds(){
QueryVo vo=new QueryVo();
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
vo.setIds(list);
List<User> users=userDao.findUserInIds(vo);
for(User user:users){
System.out.println(user);
}
}
<?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.liysh.dao.IUserDao">
<!--扣取重复的sql语句-->
<sql id="defaultUser">
select * from user
</sql>
<select id="findAll" resultType="user">
<include refid="defaultUser"></include>
<!--select * from user-->
</select>
<!--根据id查询用户-->
<select id="findById" parameterType="int" resultType="com.liysh.domain.User">
select *from user where id=#{id};
</select>
<!--根据名称模糊查询-->
<select id="findByName" parameterType="string" resultType="com.liysh.domain.User">
select *from user where username like #{name};
<!--select * from user where username like '%${value}%' 这里就必须写成value了-->
</select>
<!--根据queryVo的条件查询用户 必须是#{user.username}-->
<select id="findUserByVo" parameterType="com.liysh.domain.QueryVo" resultType="com.liysh.domain.User">
select * from user where username like #{user.username};
</select>
<!--根据条件查询必须是#{username}-->
<!--注意这里是不定的多个条件 所以每个后面不能加;号-->
<select id="findUserByCondition" resultType="com.liysh.domain.User" parameterType="com.liysh.domain.User">
select * from user where 1=1
<if test="username!=null">
and username=#{username}
</if>
<if test="sex!=null">
and sex=#{sex}
</if>
</select>
<!--当遇到多个查询条件,使用where 1=1 可以很方便的解决我们的问题,但是这样很可能会造成非常大的性能损失,因为添加了 “where 1=1 ”的过滤条件之后,数据库系统就无法使用索引等查询优化策略,数据库系统将会被迫对每行数据进行扫描(即全表扫描) 来比较此行是否满足过滤条件,当表中的数据量较大时查询速度会非常慢;此外,还会存在SQL 注入的风险。
-->
<select id="findUserByCondition" resultType="com.liysh.domain.User" parameterType="com.liysh.domain.User">
select * from user
<where>
<if test="username!=null">
and username=#{username}
</if>
<if test="sex!=null">
and sex=#{sex}
</if>
</where>
</select>
<!--<foreach>标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符-->
<!--根据queryvo中的Id集合实现查询用户列表 item="id"必须等于#{id}-->
<select id="findUserInIds" resultType="com.liysh.domain.User" parameterType="queryvo">
<include refid="defaultUser"></include>
<!--select * from user-->
<where>
<if test="ids!=null and ids.size()>0">
<foreach collection="ids" open="and id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
</mapper>
多表查询
多个账户查询一个用户(多对一/一对一)
**mybatis7:**立即加载
**mybatis10+mybatis11:**延时加载,实现只查账户信息,不查用户信息. /自查用户信息,不查账户信息
<!--配置参数 aggressiveLazyLoading在mybatis3.1.4版本后默认为false 可以不配置-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
Account.java
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
private User user; //一对一关系映射,从表中应该包含主表对象
}
IAccountDao.java
public interface IAccountDao {
/*
查询所有账户,同时还要获取到当前用户的所属用户信息
*/
List<Account> findAll();
/*
查询所有账户,并且带有用户名称和地址信息
*/
List<AccountUser> findAllAccount();
}
findAll()方法的结果集是Account+User。通过以下方法配置实现的是立即加载
findAllAccount()方法的结果集是Account+AccountUser。通过以下方法配置,由于AccountUser类继承了Account类并拓展了username和address属性所以结果集为Account+AccountUser
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.liysh.dao.IAccountDao">
<!--定义封装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的内容-->
<association property="user" column="uid" javaType="user">
<id property="id" column="id"></id>
<result column="username" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></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;
</select>
<select id="findAllAccount" resultType="accountuser">
select a.*,u.username,u.address from account a,user u where u.id=a.id;
</select>
</mapper>
findAll()方法的结果集是Account+User。通过以下方法配置实现的是延时加载
<?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.liysh.dao.IAccountDao">
<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--一对一的关系映射,配置封装user的内容
select属性指定的内容,查询用户的唯一标识-->
<association property="user" column="uid" javaType="user" select="com.liysh.dao.IUserDao.findById"></association>
</resultMap>
<select id="findAll" resultMap="accountUserMap">
select *from account
</select>
</mapper>
一个用户查询多个账户(一对多)
mybatis8
User.java
public class User implements Serializable{
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//一对多关系映射,主表实体应该包含从表实体的集合引用
private List<Account> accounts;
}
IUserDao.java
public interface IUserDao {
/**
* 查询所有操作,同时 获取账户信息*
* */
List<User> findAll();
}
findAll()方法的结果集为 User+Account。通过一下方法配置
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.liysh.dao.IUserDao">
<!--定义User的resultMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<!--配置user对象中的account集合的映射-->
<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
</select>
</mapper>
用户角色多对多查询
mybatis9
IRole.java
public class Role implements Serializable {
private Integer roleId;
private String roleName;
private String roleDesc;
//多对多的关系映射,一个角色可以赋予多个用户
private List<User> users;
}
IRoleDao.java
import com.liysh.domain.Role;
import java.util.List;
public interface IRoleDao {
/* 查询所有角色 */
List<Role> findAll();
}
IRoleDao.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.liysh.dao.IRoleDao">
<!--定义role表的ResultMap-->
<resultMap id="roleMap" type="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
<collection property="users" ofType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="birthday" property="birthday"></result>
<result column="sex" property="sex"></result>
<result column="address" property="address"></result>
</collection>
</resultMap>
<!--查询所有-->
<select id="findAll" resultMap="roleMap">
select u.*,r.id as rid,r.role_name,r.role_desc from role r
left outer join user_role ur on r.id=ur.rid
left outer join user u on u.id=ur.uid;
</select>
</mapper>
执行结果:
根据role表中的每一条数据查询对应的0个1个或多个用户信息
IUser.java
public class User implements Serializable{
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//多对多的关系映射 ,一个用户可以具备多个角色
private List<Role> roles;
}
IUserDao.java
public interface IUserDao {
/* * 查询所有操作,同时 获取账户信息 * */
List<User> findAll();
}
IUser.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.liysh.dao.IUserDao">
<!--定义User的resultMap-->
<resultMap id="userMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<!--配置角色集合的映射-->
<collection property="roles" ofType="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="userMap">
select u.*,r.id as rid,r.role_name,r.role_desc from user u
left outer join user_role ur on u.id=ur.uid
left outer join role r on r.id=ur.rid
</select>
</mapper>
执行结果:
根据User表中的每一条数据查询个一个或多个角色信息
MyBatis一级缓存
一级缓存是 SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就存在。
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.liysh.dao.IUserDao">
<!--根据id查询用户-->
<select id="findById" parameterType="int" resultType="com.liysh.domain.User" useCache="true">
select *from user where id=#{uid};
</select>
</mapper>
测试方法
1.一个SqlSession两次查询
@Test
public void testFirstLevelCache(){
User user1=userDao.findById(1); //第一次是查询
System.out.println(user1);
User user2=userDao.findById(1); //第二次是从缓存中取
System.out.println(user2);
System.out.println(user1==user2); //true
}
2.清空SqlSession后再查询一次,是两个对象
//清空session后重新查询,一个sqlsession但有两次查询
@Test
public void testFirstLevelCache1(){
User user1=userDao.findById(1);
System.out.println(user1);
sqlSession.clearCache(); //此方法可以清空缓存相当于sqlSession.close(); sqlSession=factory.openSession();
userDao=sqlSession.getMapper(IUserDao.class);
User user2=userDao.findById(1);
System.out.println(user2);
System.out.println(user1==user2); //false
}
MyBatis二级缓存
在SqlMapConfig.xml中
<!--配置二级缓存-->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
IIUserDao.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.liysh.dao.IUserDao">
<!--开启user支持二级缓存-->
<cache/>
<select id="findAll" resultType="user">
select * from user
</select>
<!--根据id查询用户-->
<select id="findById" parameterType="int" resultType="com.liysh.domain.User" useCache="true">
select *from user where id=#{uid};
</select>
</mapper>
基于注解的单表查询
mybatis13
IUserDao.java
public interface IUserDao {
/*
查询所有用户
*/
@Select("select *from user")
@Results(id="userMap",
value= {
@Result(id=true,column="id",property="userId"),
@Result(column="username",property="userName"),
@Result(column="sex",property="userSex"),
@Result(column="address",property="userAddress"),
@Result(column="birthday",property="userBirthday")
})
List<User> findAll();
/*
保存用户
*/
@Insert("insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})")
void saveUser(User user);
/*
更新用户
*/
@Update("update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}")
void updateUser(User user);
/*
删除用户
*/
@Delete("delete from user where id=#{id}")
void deleteUser(Integer userId);
/*
根据id查询用户
*/
@Select("select * from user where id=#{id}")
@ResultMap("userMap")
User findById(Integer userId);
/*
根据用户名称模糊查询
*/
// @Select("select * from user where username like #{username}") 两种方法
@Select("select * from user where username like '%${value}%'")
List<User> findUserByName(String username);
/*
查询总用户数量
*/
@Select("select count(*) from user")
int findTotalUser();
}
SqlMapConfig.xml
<!--指定带有注解的dao接口所在位置-->
<mappers>
<!--注解配置-->
<mapper class="com.liysh.dao.IUserDao"></mapper>
</mappers>
基于注解的多表查询
mybatis14
在Account中实现一对一 一个账户对应一个用户
在User中实现一对多,一个用户可以有多个账户
复杂关系映射的注解说明
@Results 注解
代替的是标签<resultMap>
该注解中可以使用单个@Result 注解,也可以使用@Result 集合
@Results({@Result(),@Result()})或@Results(@Result())
@Resutl 注解
代替了 <id>标签和<result>标签
@Result 中 属性介绍:
id 是否是主键字段
column 数据库的列名
property 需要装配的属性名
one 需要使用的@One 注解(@Result(one=@One)()))
many 需要使用的@Many 注解(@Result(many=@many)()))
@One 注解(一对一)
代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@One 注解属性介绍:
select 指定用来多表查询的 sqlmapper
fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。。
使用格式:
@Result(column=" ",property="",one=@One(select=""))
@Many 注解(多对一)
代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。
注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType
(一般为 ArrayList)但是注解中可以不定义;
使用格式:
@Result(property="",column="",many=@Many(select=""))
IAccount.java
public interface IAccountDao {
/* 查询所有账户,并获取每个账户所属的用户信息 */
@Select("select* from account")
@Results(id="accountMap",value = {
@Result(id=true,column = "id",property = "id"),
@Result(column = "uid",property = "uid"),
@Result(column = "money",property = "money"),
@Result(property = "user",column =
"uid",one=@One(select="com.liysh.dao.IUserDao.findById",fetchType= FetchType.EAGER))
})
List<Account> findAll();
/* 根据用户id查询账户信息 */
@Select("select * from account where uid=#{userId}")
List<Account> findAccountByUid(Integer userId);
}
IUser.java
@CacheNamespace(blocking=true)
public interface IUserDao {
/*
查询所有用户
*/
@Select("select *from user")
@Results(id="userMap", value={
@Result(id=true,column="id",property = "userId"),
@Result(column = "username",property = "userName"),
@Result(column = "birthday",property = "userBirthday"),
@Result(column = "sex",property = "userSex"),
@Result(column = "address",property = "userAddress"),
@Result(property = "accounts",column = "id",many =@Many(select = "com.liysh.dao.IAccountDao.findAccountByUid",fetchType= FetchType.LAZY))
})
List<User> findAll();
/*
根据id查询用户
*/
@Select("select * from user where id=#{id}")
@ResultMap(value={"userMap"}) //等同于@ResultMap("userMap")
User findById(Integer userId);
/*
根据用户名称模糊查询
*/
@Select("select * from user where username like #{username}")
@ResultMap("userMap")
List<User> findUserByName(String username);
}