mybatis的注解开发是对于映射配置文件这个层面来说的,所以仍然需要定义主配置文件,和前文基于xml配置方法和细节,和注意事项完全一致
SqlMapConfig.xml
<configuration>
<properties resource="jdbcConfig.properties">
properties>
<typeAliases>
<package name="com.xpt.domain"/>
typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="UNPOOLED">
<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>
environment>
environments>
<mappers>
<package name="com.xpt.dao"/>
mappers>
configuration>
// @Select(value = "select * from user")
//只有一个参数时,value可以省略
@Select("select * from user")
List<User> findAll();
public static void main(String[] args) throws Exception {
//1.获取字节输入流
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.根据字节输入流构建 SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.利用factory生产一个SqlSession
SqlSession sqlSession = factory.openSession();
//4.利用sqlSession获取代理对象
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();
}
理解了前面的查询的过程,后面的内容都基本一致。
IUserDao
的配置代码 @Select("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
void saveUser(User user);
@Select("update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address} where id=#{id}")
void updateUser(User user);
@Select("delete from user where id=#{id}")
void deleteUser(Integer userId);
public class AnnotationCRUDTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before
public void init() throws Exception{
in = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
sqlSession = factory.openSession();
userDao = sqlSession.getMapper(IUserDao.class);
}
@After
public void destroy() throws Exception{
sqlSession.commit();
sqlSession.close();
in.close();
}
@Test
public void testSave(){
User user = new User();
user.setUsername("mybatis annotation");
user.setAddress("唐人街");
userDao.saveUser(user);
}
@Test
public void testUpdate(){
User user = new User();
user.setId(63);
user.setUsername("update mybatis annotation");
user.setAddress("唐人街 50号");
userDao.updateUser(user);
}
@Test
public void testDelete(){
userDao.deleteUser(63);
}
}
IUserDao
的配置代码
@Select("select * from user where id = #{id}")
User findById(Integer userId);
@Select("select * from user where username like '%${value}%' ")
List<User> findUserByName(String username);
@Select("select count(*) from user ")
int findTotalUser();
@Test
public void testFindById(){
User user = userDao.findById(57);
System.out.println(user);
}
@Test
public void testFindByName(){
// List users = userDao.findUserByName("%mybatis%");
List<User> users = userDao.findUserByName("mybatis");
for(User user : users){
System.out.println(user);
}
}
@Test
public void testFindTotal(){
int total = userDao.findTotalUser();
System.out.println(total);
}
在基于xml的配置开发的时候,二者不一致的时候,使用的是一个map来解决,注解开发如何解决这个问题呢?
@Select("select * from user")
@Results(value = {
//id默认为false 这里指定为true是因为id为主键 column 数据表字段名 property 实体类属性名
@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")
})
List<User> findAll();
testFindAll()
方法 @Test
public void testFindAll(){
List<User> users = userDao.findAll();
for(User user : users){
System.out.println(user);
}
}
@Test
public void testFindById(){
User user = userDao.findById(57);
System.out.println(user);
}
这里同样使用用户和账户的实例来说明
//建立多对一(mybatis中称为 一对一)的映射 一个账户只能属于一个用户
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
/**
* 查询account的信息 并同时查询所属的用户信息
* @return
*/
@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"),
//下面把user的信息也封装进来
@Result(
property = "user",
column = "uid",//在user表中当然是使用uid进行查询
//使用注解 @one 来指定一对一的关系 select是在user表中查询的全限定名加方法名
//后面 fetchType指定加载类型 LAZY延迟加载 EAGER立即加载
one = @One(select = "com.xpt.dao.IUserDao.findById",fetchType = FetchType.EAGER)
)}
)
List<Account> findAll();
查询用户,并查询出用户下所有的账户信息
//一对多关系映射 一个用户下 有多个账户
List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
/**
* 查询所有用户 并同时查询对应的账户信息
* @return
*/
// @Select(value = "select * from user")
//只有一个参数时,value可以省略
@Select("select * from user")
@Results(id = "userMap",value = {
//id默认为false 这里指定为true是因为id为主键 column 数据表字段名 property 实体类属性名
@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",//查询结果 封装到accounts属性
column = "id",//这里的id就是用户id
many = @Many(select = "com.xpt.dao.IAccountDao.findAccountByUid",
fetchType = FetchType.LAZY)
)
})
List<User> findAll();
@Test
public void testFindAll(){
List<User> users = userDao.findAll();
for(User user : users){
System.out.println("---用户查询信息---");
System.out.println(user);
System.out.println(user.getAccounts());
}
}
@Test
public void testFindById(){
User user1 = userDao.findById(42);
System.out.println(user1);
User user2 = userDao.findById(42);
System.out.println(user2);
System.out.println(user1 == user2);
}
<settings>
<setting name="cacheEnabled" value="true"/>
settings>
public class SecondLevelCacheTest {
private InputStream in;
private SqlSessionFactory factory;
// private SqlSession sqlSession;
// private IUserDao userDao;
@Before
public void init() throws Exception{
in = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = new SqlSessionFactoryBuilder().build(in);
// sqlSession = factory.openSession();
// userDao = sqlSession.getMapper(IUserDao.class);
}
@After
public void destroy() throws Exception{
// sqlSession.commit();
// sqlSession.close();
in.close();
}
@Test
public void testFindById(){
SqlSession sqlSession = factory.openSession();
IUserDao userDao = sqlSession.getMapper(IUserDao.class);
User user1 = userDao.findById(42);
System.out.println(user1);
//释放一级缓存
sqlSession.close();
//再次打开缓存
SqlSession sqlSession1 = factory.openSession();
IUserDao userDao1 = sqlSession1.getMapper(IUserDao.class);
User user2 = userDao1.findById(42);
System.out.println(user2);
sqlSession1.close();
System.out.println(user1 == user2);
}