注解和xml配置的区别
注解
优点:编写简单,代码量少
缺点:写到源码中的,如果需要维护修改,必须修改源码
xml
优点:不用修改源码就可以修改配置,可以实时进行配置的更新
缺点:代码比较复杂,结构不如注解清晰。
注意:采用注解开发的时候,在同一个dao下不能有xml文件,就是说要么用注解要么就都用配置文件开发。
1. 同一个文件不能同时使用注解和配置文件开发。
2. 如果是不同的接口文件,可以使用不同的方法,但工作中不建议这样使用。
3. 在注解开发中,如何在插入新的用户后获取用户的自增长ID:
第一种:options,添加表的列名sid,指定成员变量的名id,关键的一步是设置useGeneratedKeys = true,直译过来就是要接代传递变量。
//@Options(useGeneratedKeys = true,keyColumn = "sid",keyProperty = "id")
第二种:selectkey,基本的思路和xml配置一样,代码编写如下:
@SelectKey(statement = "select last_insert_id()",keyProperty = "id",
keyColumn = "sid",resultType = int.class,before = false)
主配置文件:
<?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>
<!-- 引入外部配置文件-->
<properties resource="jdbcConfig.properties"></properties>
<!--配置开启二级缓存,默认为true,可以不写-->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!--配置别名-->
<typeAliases>
<package name="com.itheima.domain"></package>
</typeAliases>
<!-- 配置环境-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<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 name="com.itheima.dao"></package>
</mappers>
</configuration>
Dao包下的接口
package com.itheima.dao;
import com.itheima.domain.Account;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
/**
* @author 黑马程序员
* @Company http://www.ithiema.com
*/
public interface IAccountDao {
/**
* 查询所有账户,并且获取每个账户所属的用户信息
* @return
one代表多对一,many代表一对多
*/
@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.itheima.dao.IUserDao.findById",fetchType= FetchType.EAGER))
})
List<Account> findAll();
/**
* 根据用户id查询账户信息
* @param userId
* @return
*/
@Select("select * from account where uid = #{userId}")
List<Account> findAccountByUid(Integer userId);
}
package com.itheima.dao;
import com.itheima.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
/**
* @author 黑马程序员
* @Company http://www.ithiema.com
* 在mybatis中针对,CRUD一共有四个注解
* @Select @Insert @Update @Delete
*/
@CacheNamespace(blocking = true)
public interface IUserDao {
/**
* 查询所有用户
* @return
*/
@Select("select * from user")
@Results(id="userMap",value={
@Result(id=true,column = "id",property = "userId"),
@Result(column = "username",property = "userName"),
@Result(column = "address",property = "userAddress"),
@Result(column = "sex",property = "userSex"),
@Result(column = "birthday",property = "userBirthday"),
@Result(property = "accounts",column = "id",
many = @Many(select = "com.itheima.dao.IAccountDao.findAccountByUid",
fetchType = FetchType.LAZY))
})
//只需要配置一次,其他方法根据id进行引用即可,
List<User> findAll();
/**
* 根据id查询用户
* @param userId
* @return
*/
@Select("select * from user where id=#{id} ")
@ResultMap("userMap")
//@ResultMap里面是个数组,可以写多个map,标准写法为value={"userMap"},但只有value时可以省略value不写,且数组只有一个数据时。数组{}也可以不写
User findById(Integer userId);
/**
* 根据用户名称模糊查询
* @param username
* @return
*/
@Select("select * from user where username like #{username} ")
@ResultMap("userMap")
List<User> findUserByName(String username);
}
用注解配置多对多时,不可以直接写查询方法,必须用延迟加载的方法才可以查询。
package com.itheima.dao;
import com.itheima.domain.Role;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
@CacheNamespace(blocking = true)//二级缓存开启
public interface IRoleDao {
@Select("select * from role ")
@Results(id = "roleMap", value = {
@Result(id = true, property = "id", column = "id"),
@Result(property = "ROLE_NAME", column = "ROLE_NAME"),
@Result(property = "ROLE_DESC", column = "ROLE_DESC"),
@Result(property = "users", column = "id", javaType = List.class, many = @Many(select = "com.itheima.dao.IUserDao.findById", fetchType = FetchType.LAZY))
})
public List<Role> findAll();
@Select("select * from role where id in (select rid from user_role where uid = #{id})")
// @ResultMap("roleMap")
public List<Role> findByUid(Integer uid);
}
package com.itheima.dao;
import com.itheima.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
@CacheNamespace(blocking = true)//二级缓存开启
public interface IUserDao {
/**
* 查询所有
* @return
*/
@Select("select * from user")
@Results(id = "userMap",value = {
@Result(id = true,property = "id",column = "id"),
@Result(property = "username",column = "username"),
@Result(property = "birthday",column = "birthday"),
@Result(property = "sex",column = "sex"),
@Result(property = "address",column = "address"),
@Result(property = "roles",column = "id" (这个column指定的是给com.itheima.dao.IRoleDao.findByUid传的值),many = @Many(select = "com.itheima.dao.IRoleDao.findByUid",fetchType = FetchType.LAZY))
})
public List<User> findAll();
/**
* 根据id查询用户
* @param rid
* @return
*/
@Select("select * from user where id in (select uid from user_role where rid = #{id})")
// @ResultMap("userMap")
public List<User> findById(Integer rid);
}
延迟加载需要在主配置文件中配置,一级缓存是默认开启不用设置的,二级缓存可以直接在映射文件或dao包中设置,在主配置文件中是默认开启的