mybatis框架学习-注解方式的crud,缓存,一对一,一对多
前期mysql准备
create database rainbow; use rainbow; CREATE TABLE `user` ( `uid` int(11) NOT NULL auto_increment, `name` varchar(32) NOT NULL COMMENT '用户名称', `sex` char(1) default NULL COMMENT '性别', `address` varchar(256) default NULL COMMENT '地址', PRIMARY KEY (`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `account` ( `aid` int(11) NOT NULL auto_increment, `uid` int(11) default NULL COMMENT '用户编号', `money` double default NULL COMMENT '金额', PRIMARY KEY (`aid`), KEY `FK_Reference_8` (`uid`), CONSTRAINT `FK_Reference_8` FOREIGN KEY (`uid`) REFERENCES `user` (`uid`)
1.创建maven项目,导入依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.cong</groupId> <artifactId>mybatis_annotation</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <dependency> <groupId></groupId> <artifactId></artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies> </project>
2.创建实体类
package com.cong.pojo; import java.io.Serializable; public class Account implements Serializable{ private int id; private int uid; private double money; //多对一(Mybatis中称为一对一)的映射,一个account只能属于一个user private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } public int getId() { return id; } public void setId(int id) { this.id = id; } public int getUid() { return uid; } public void setUid(int uid) { this.uid = uid; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money=" + money + '}'; } } package com.cong.pojo; import java.io.Serializable; import java.util.List; public class User implements Serializable{ private int id; private String username; private char sex; private String addr; private List<Account> accounts; public List<Account> getAccounts() { return accounts; } public void setAccounts(List<Account> accounts) { this.accounts = accounts; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", sex=" + sex + ", addr='" + addr + '\'' + '}'; } 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 char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } }
3.创建mapper代理接口,因为是注解方式,crud全部在这里配置的
accountMpper接口
package com.cong.mapper; /** * 这里演示一对一的查询 * 以及基于注解的二级缓存配置 */ import com.cong.pojo.Account; import org.apache.ibatis.annotations.*; import org.apache.ibatis.mapping.FetchType; import java.util.List; @CacheNamespace(blocking=true)//mybatis 基于注解方式实现配置二级缓存 public interface AccountMapper { //查询所有 @Select("select * from account") @Results(id = "accountMap",value = { @Result(id = true, property = "id", column = "aid") }) List<Account> findAll(); //根据uid查询account @ResultMap(value = "accountMap") @Select("select * from account where uid = #{uid}") List<Account> findByUid(int i); //根据aid查询account @ResultMap(value = "accountMap") @Select("select * from account where aid = #{aid}") Account findById(int id); /** * 多对一(Mybatis中称为一对一)的映射,一个account只能属于一个user * @return */ @Select("select * from account") @Results(id = "accountUserMap",value = { @Result(id = true,property = "id",column = "aid"), @Result(property = "money",column = "money"), @Result(property = "uid",column = "uid"), @Result(property = "user",column = "uid", one = @One(select = "com.cong.mapper.UserMapper.findById",fetchType = FetchType.EAGER) ), }) List<Account> findAcountAndUser(); }
usermapper接口
package com.cong.mapper; import com.cong.pojo.User; import org.apache.ibatis.annotations.*; import org.apache.ibatis.mapping.FetchType; import java.util.List; /** * 这里演示crud的注解配置 * 以及一对多的查询配置 */ public interface UserMapper { /** 注解@Results中提供了id属性这就跟xml文件中的id作用一样,下面引用的话可以用@ResultMap来引用。 首先说明一下@Results各个属性的含义, id为当前结果集声明唯一标识,value值为结果集映射关系, @Result代表一个字段的映射关系, column指定数据库字段的名称,property指定实体类属性的名称, jdbcType数据库字段类型,@Result里的id值为true表明主键,默认false; 使用@ResultMap来引用映射结果集,其中value可省略。 */ //查询所有 @Results(id = "userMap",value = { @Result(property = "id", column = "uid",id = true), @Result(property = "username", column = "name") }) @Select("select * from user") List<User> findAll(); //根据id查询 @Select("select * from user where uid = #{id}") @ResultMap(value = "userMap") User findById(int id); //根据名字模糊查询 @Select("select * from user where name like #{name}") @ResultMap(value = "userMap") List<User> findByName(String name); //查询数量 @Select("select count(*) from user") int findTotal(); //插入 @Insert("insert into user(name,sex,addr) values(#{username},#{sex},#{addr})") @Options(useGeneratedKeys = true,keyColumn = "uid",keyProperty = "id")//返回自增字段的id void saveUser(User user); //更新,在这name=#{username},name是数据库的字段,username是实体类的属性 @Update("update user set name=#{username},sex = #{sex},addr = #{addr} where uid = #{id}") void updateUser(User user); //删除 @Delete("delete from user where uid = #{uid}") void deleteUser(int id); /** * 以上单表操作 * ----------------分界线----------------- * 以下多表操作 */ @Select("select * from user") @Results(id = "userAccountMap",value = { @Result(id = true,property = "id",column = "uid"), @Result(property = "username",column = "name"), @Result(property = "sex",column = "sex"), @Result(property = "addr",column = "addr"), @Result(property = "accounts",column = "uid", many = @Many(select = "com.cong.mapper.AccountMapper.findByUid",fetchType = FetchType.LAZY)) }) List<User> findUserAndAccount(); }
4.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"> <configuration> <settings> <!-- 开启二级缓存的支持,默认是开启的 --> <setting name="cacheEnabled" value="true"/> </settings> <typeAliases> <package name="com.cong.pojo"></package> </typeAliases> <environments default="mysql"> <environment id="mysql"> <!-- 使用JDBC事物管理 --> <transactionManager type="JDBC"></transactionManager> <!-- 数据库连接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/rainbow?useUnicode=true&characterEncoding=UTF-8"></property> <property name="username" value="root"></property> <property name="password" value="123456"></property> </dataSource> </environment> </environments> <!-- 指定映射配置文件的位置,映射配置文件指的是每个mapper独立的配置文件 如果是用注解来配置的话,此处应该使用class属性指定被注解的mapper全限定类名--> <mappers> <package name="com.cong.mapper"></package> </mappers> </configuration>
5.测试类
TestAccount
import com.cong.mapper.AccountMapper; import com.cong.pojo.Account; 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 TestAccount { private InputStream inputStream; private SqlSession sqlSession; private AccountMapper accountMapper; @Test public void findAllAccount(){ List<Account> accounts = accountMapper.findAll(); for (Account account : accounts) { System.out.println(account.toString()); } } @Test public void findAccountAndUser(){ List<Account> accounts = accountMapper.findAcountAndUser(); for (Account account : accounts) { System.out.println("----------------------------------"); System.out.println(account.toString()); System.out.println(account.getUser().toString()); } } @Test public void findAccountByUid(){ List<Account> accounts = accountMapper.findByUid(1); for (Account account : accounts) { System.out.println(account.toString()); } } @Before public void init() throws Exception{ inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); sqlSession = factory.openSession(); accountMapper = sqlSession.getMapper(AccountMapper.class); } @After public void destroy() throws Exception{ sqlSession.commit(); sqlSession.close(); inputStream.close(); } }
TestUser
import com.cong.mapper.UserMapper; import com.cong.pojo.Account; import com.cong.pojo.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 TestUser { private InputStream inputStream; private SqlSession sqlSession; private UserMapper userMapper; @Test public void findAllUser(){ List<User> users = userMapper.findAll(); for (User user : users) { System.out.println(user.toString()); } } @Test public void findById(){ User user = userMapper.findById(1); System.out.println(user.toString()); } @Test public void findByName(){ List<User> users = userMapper.findByName("%RAIN%"); for (User user : users) { System.out.println(user.toString()); } } @Test public void findTotal(){ int total = userMapper.findTotal(); System.out.println("total: " + total); } @Test public void saveUser(){ User rain = new User(); rain.setUsername("rain"); rain.setSex('女'); rain.setAddr("25号"); userMapper.saveUser(rain); System.out.println(rain.toString()); } @Test public void updateUser(){ //User rainbow = userMapper.findById(5); User rainbow = new User(); rainbow.setId(12); rainbow.setUsername("菜菜"); rainbow.setSex('女'); rainbow.setAddr("北街25号"); userMapper.updateUser(rainbow); } @Test public void deleteUser(){ userMapper.deleteUser(6); } @Test public void findAllUserAndAccount(){ List<User> users = userMapper.findUserAndAccount(); for (User user : users) { System.out.println(user.toString()); if(!user.getAccounts().isEmpty()){ for (Account account : user.getAccounts()) { System.out.println("\t"+account.toString()); } } } } @Before public void init() throws Exception{ inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream); sqlSession = factory.openSession(); userMapper = sqlSession.getMapper(UserMapper.class); } @After public void destroy() throws Exception{ sqlSession.commit(); sqlSession.close(); inputStream.close(); } }
TestCache
import com.cong.mapper.AccountMapper; import com.cong.pojo.Account; 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; public class TestCache { private InputStream inputStream; //private SqlSession sqlSession; //private AccountMapper mapper; private SqlSessionFactory factory; @Test public void testFirstLevelCache(){ SqlSession sqlSession = factory.openSession(); AccountMapper mapper = sqlSession.getMapper(AccountMapper.class); Account account = mapper.findById(1); Account account1 = mapper.findById(1); System.out.println(account == account1);//true } @Test public void testSecondLevelCache(){ SqlSession sqlSession = factory.openSession(); AccountMapper mapper = sqlSession.getMapper(AccountMapper.class); Account account = mapper.findById(1); sqlSession.close();//一级缓存消失 SqlSession sqlSession1 = factory.openSession(); AccountMapper mapper1 = sqlSession1.getMapper(AccountMapper.class); Account account1 = mapper1.findById(1); System.out.println(account); System.out.println(account1); System.out.println(account == account1);//false } @Before public void init() throws Exception{ inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); factory = new SqlSessionFactoryBuilder().build(inputStream); // sqlSession = factory.openSession(); // mapper = sqlSession.getMapper(AccountMapper.class); } @After public void destroy() throws Exception{ // sqlSession.commit(); // sqlSession.commit(); inputStream.close(); } }
爱生活,爱码字
我是匆匆、我曾喂自己半年酒。
好好生活吧,有缘或许相见。