框架
定义:
即:是软件开发中的一套解决方案,不同的框架解决的是不同的问题;
ORG思想
定义:Object Relational Mapping 对象关系映射
即:实体类和数据库表中的属性一一对应;让我们操作实体类就可以操作数据库表
MVC思想
Mybatis
学习之前的注意事项:
-
在 Windows 系统下,Mybatis 不区分大小写。Mac 系统下,Mybatis 区分大小写
-
mybatis的入门
环境搭建
1.第一步:创建 Maven 工程并导入坐标
2.第二步:创建实体类和 dao 接口
3.第三步:创建Mybatis的主配置文件
SqlMapConfig.xml
4.第四步:创建映射配置文件
IUserDao.xml
环境搭建的注意事项:
第一个:创建 IUserDao.xml 和 IUserDao.java 时名称是为了和我们之前的知识保持一致。
在Mybatis中它把持久层的操作接口名称和映射文件也叫做:Mapper
所以: IUserDao 和 IUserMapper 是一样的
第二个:在IDEA中创建目录的时候,它和包是不一样的
包在创建时:com.itheima.mybatis 是三级目录
目录在创建时:com.itheima.mybatis是一级目录
第三个: Mybatis 的映射配置文件位置必须和 dao 接口的包结构相同
第四个:映射配置文件的 mapper 标签 namespace 属性的取值必须是 dao 接口的全限定类名
第五个:映射配置文件的操作配置(select),id 属性的取值必须是 dao 接口的方法名
当我们遵从了第三,四,五点之后,开发中便无需编写 dao 的实现类
mybatis 的入门案例
第一步:读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
第二步:创建 SqlSessionFactory 工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
第三步:创建 SqlSession
SqlSession session = factory.openSession();
第四步:创建 Dao 接口的代理对象
UserDao userdao = session.getMapper(UserDao.class);
第五步:执行 dao 中的方法
List<User> list = userdao.findAll();
第六步:释放资源
sesssion.close();
io.close();
注意事项:不要忘记在映射配置中告知mybatis要封装到那个实体类;
配置的方式:指定实体类的全限定类名
mybatis 基于注解的入门案例:
把 IUserDao.xml 移除,在 dao 接口苦的方法上使用 @Select 注解,并且指定 SQL 语句
同时需要在 SqlMapConfig.xml 中的 Mapper 配置时,使用 class 属性指定 dao 接口苦的全限定类名
入门案例解析
配置文件(resources下)
log4j.properties
# Set root category priority to INFO and its only appender to CONSOLE.
# log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug,CONSOLE, LOGFILE
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
以上文件无需修改,拷贝到 resources 下即可
mybatis 的主配置文件(SqlMapConfig.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.dream.dao.UserDao"> <!-- 配置查询所有--> <select id="findAll" resultType="com.dream.domain.User"> select * from user </select> <!-- 配置插入新数据--> <insert id="saveUser" parameterType="com.dream.domain.User"> insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) </insert> </mapper>
在 mapper 内添加需要用到的 SQL 语句
模糊查询
有两种方式
一、在查询语句中添加 “%”
接口内
实体配置文件
测试类
注意:
若使用第一种方式,则与其他语句相似操作即可
若采用第二种方式,即在配置文件中添加 “%” ,需要注意的是:必须使用 ‘%%’,源码中此处采用了 map 的方式,键值为 value,所以此处必须为 value
入门案例中设计模式的分析
mybatis 使用了哪些模式
优点:
构建者模式:把对象的创建细节隐藏,使用者直接调用方法即可拿到对象
工厂模式:解耦(降低类之间的依赖关系)
代理模式:不修改源码的基础上,对已有方法增强
读取XML配置文件
XML文件的解析有多种方法
1、DOM解析(java官方提供)
2、SAX解析(java官方提供)
3、JDOM解析(第三方提供)
4、DOM4J提供(第三方提供)
mybatis 使用的是 DOM4J 方式来解析 XML 配置文件
文件的读取路径
读取文件的路径方法有:
1、相对路径
2、绝对路径
3、类加载器
4、Select
-
在本地使用相对路径和绝对路径
-
在项目中使用类加载器和 Select
在 mybatis 中,XML 文件的读取使用 SelectContext 对象的 getReadPath();
自定义 Mybatis 的分析:
Mybatis 在使用代理 dao 的方式实现增删改查时做什么事呢?
只有两件事:
第一:创建代理对象
第二:在代理对象中调用 selectList
Mybatis 的 CRUD
Mybatis 中的参数深入及结果集的深入
Mybatis 中基于传统 dao 的方式(编写 dao 的实现类)
Mybatis 中的配置(主配置文件:SqlMapConfig.xml)
OGNL 表达式
Object Graphic Navigation Language
对象 图 导航 语言
使用
它是通过对象的取值方法来获取数据,在写法上把 get 省略了
eg:
我们获取用户的名称
类中的写法: user.getUsername();
OGNL表达式的写法:user.username;
mybatis 中为什么能直接写 username,而不用 user. 呢?
因为在 parameterType 中已经提供了属性所属的类,所以此时不需要写对象名
SqlMapConfig.xml 配置文件
配置内容
配置 properties
可以在标签内部配置连接数据库的信息,也可以通过属性应用外部配置文件信息
一、
resource 属性: 常用
用于指定配置文件的位置,是按照类路径的写法来写,并且必须存于类路径下
二、
url 属性:
是要求按照 url 的写法来写地址
URL:Uniform Resoures Locator 统一资源定位符。它是可以唯一标识一个资源的位置
它的写法:
http://localhost:8080/mybatisserver/demo1Servlet
协议 主机 端口 URI
URI:Uniform Resource Identifier 统一资源标识符。他是在应用中可以唯一定位一个资源的。
配置 typeAliases
typeAliases 配置别名,他只能配置 domain 中类的别名
一、
typeAlias 用于配置别名,type属性指定的是实体类全限定类名;alias 属性指定别名,当指定别名就不在区分大小写
二、
package 用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写
配置 Mappers
package 标签用于指定 dao 接口所在的包,当指定之后就不需要在写 mapper以及 resource 或者 class 这里没有运行出来
连接池
优点
在实际开发中都会使用连接池
因为他可以减少我们获取连接所消耗的时间
Mybatis 中的连接池
Mybatis 中连接池的配置
配置的位置:
主配置文件 SqlMapConfig.xml 中 dataSource 标签,type 属性就是表示采用何种连接池方式
type 属性的取值:
##### POOLED
采用传统的 javax.sql.DataSource 规范中的连接池,mybatis中有针对规范的实现
##### UNPOOLED
采用传统的获取连接的方式,虽然也实现了 javax.sql.DataSource 接口,但是并没有使用池的思想
##### JNDI
采用服务为其提供的JNDI 技术实现,来获取 DataSource 对象,不同的服务器所能拿到的 DataSource 是不一样的
注意:如果不是web或者maven工程,是不能使用的
事务
定义:
事务的特性
原子性(Atomocity)
隔离性(Consistency)
一致性(Isolation)
持久性(Durability)
不考虑隔离性会产生的3个问题
读未提交 (Read Uncommited)
读已提交 (Read Committed)
可重复读 (Repeatable Read)
串行化 (Serialization)
解决办法:
四种隔离级别
它是通过 sqlsession 对象的 commit 方法和 rollback 方法实现事务的提交和回滚
Mybatis 中映射文件的深入
if 标签
根据实体类的不同取值,使用不同的 SQL 语句来进行查询,比如在 id 如果不为空时可以根据 id 查询,如果 username 不同空时还要加入用户名作为条件。这种情况在多条件组合查询中经常碰到
注意:多条件查询时,并列条件组合必须用 and ,而不能用 &&
where 标签
根据实体类的不同取值,使用不同的 SQL 语句来进行查询,但是查询条件不确定。而查询条件又多的时候,我们可以通过 where 标签来实现多条件,且不确定条件查询
foreach 标签
根据实际开发要求,应对需要查询多 ID 时,此时需要将 ID 包装到集合中,通过包装类来实现映射
Result 标签
配置文件中:
result 标签中
property 表示 实体类中 get 和 set 方法后面的属性
colum 表示 SQL 语句查询结果中的结果列
抽取重复的 SQL 语句
抽取重复的 SQL 语句为其添加别名
注意:若在 if 标签或 where 标签中引用,不能在 SQL 标签中的 SQL 语句中添加分号
mybatis 中的多表查询
表之间的关系
一对多
多对一
一对一
多对多
mybatis 中的多表查询
示例:用户和账户
一个用户有多个账户
一个账户只能属于一个用户(多个账户也可以属于同一个用户)
步骤
1、建立两张表
让用户表和账户表之间具备一对多的关系:需要使用外键在账户表中添加
2、建立两个实体类:用户表,账户表
让用户和账户的实体类能体现出一对多的关系
3、建立两个配置文件
用户的配置文件
账户的配置文件
4、实现配置
当我们查询用户时,可以同时得到用户下包含的账户信息
当我们查询账户时,可以同时得到账户下的所属用户信息
一对一
第一种方式:(较古老)
添加第三张表信息,在第三张表中加入需要的字段信息。使用及应用于之前类似
第二种方式
一、在从表中添加主表的实体属性
二、然后在从表的映射配置文件中添加映射信息
一对多
一、在主表中添加从表的集合引用
二、主表映射配置文件的参数设置
三、 SQL 语句查询结果
注意:mybatis是很智能且强大的,它会在查询结果中将重复的数据删除,只保留一条
多对多
示例:用户和角色
一个用户有多个角色
一个角色可以赋予多个用户
步骤
1、建立两张表
用户表
角色表
用户表和角色表具有多对多的关系,需要使用中间表,中间表包含各自的主键,在中间表中是外键
2、建立两个实体类:
用户实体类
角色实体类
让用户和角色能体现多对多的关系,各自包含对方一个集合引用
3、建立两个配置文件
用户的配置文件
角色的配置文件
配置文件中:
result 标签中
property 表示 实体类中 get 和 set 方法后面的属性
colum 表示 SQL 语句查询结果中的结果列
开发注意:
实际开发中,在SQL语句很长,很复杂的情况下,必须在每行尾或者行头添加空格,以防止字符串拼接操作,导致的错误
4、实现配置
当我们查询用户时,可以同时得到用户下包含的角色信息
当我们查询角色时,可以同时得到角色所赋予的用户信息
JNDI
JNDI
Java Naming And Directory Interface
是 SUN 公司推出的一套规范,属于 JavaEE 技术之一 。目的是模仿 Windows 系统中的注册表。
。。。。。。。。。。。
Mybatis 的延迟加载
问题:
在一对多中,当我们有一个用户,他有100个账户。
在查询用户的时候,要不要把关联的账户查出来?
在查询账户的时候,要不要把关联的用户查出来?
解决:
在查询用户是,用户下的账户信息,什么时候用,什么时候查询
在查询账户时,账户所属用户信息,随着账户查询时一起查询出来
延迟加载和立即加载
延迟加载
在真正使用数据是才发起查询,不用的时候不查询,按需加载(懒加载)
立即加载
不管用不用,只要一调用方法,马上发起查询
在对应四中表关系中:一对一;一对多;多对一;多对多
一对多;多对多:通常情况下都是采用延迟加载;
多对一;一对一:通常情况下都是采用立即加载;
Mybatis 中的缓存
什么是缓存
存在于内存中的临时数据
为什么使用缓存
减少和数据库的交互次数,提高执行效率
什么样的数据能使用缓存,什么样的数据不适合用缓存
适用于缓存:
经常查询并且不经常改变的
数据的正确与否对最后结果影响不大的
不适用于缓存
经常改变的数据
数据的正确与否对最终结果影响很大的
例如:商品的库存,银行的汇率,股市的牌价
Mybatis 中的一级缓存和二级缓存
一级缓存(默认无需设置)
它指的是Mybatis中SqlSession对象的缓存
当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供的一块区域中。
该区域的结构是一个Map。当我们在此查询到同样的数据,mybatis会先去sqlSession中查询是否有,有的话直接拿出来用。
当SqlSession对象消失时,Mybatis的一级缓存也就消失了
SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit() , close() 等方法时,就会清空一级缓存
二级缓存(需设置)
它指的是 Mybatis 中 SqlSessionFactory 对象的缓存。由同一个 SqlSessionFactory 对象创建的 SqlSession 共享其缓存
二级缓存的使用步骤:
第一步:让 Mybatis 框架支持二级缓存(在 SqlMapConfig.xml) 中配置
<settings> <setting name="cacheEnabled" value="true"/> </settings>
第二步:让当前的映射文件支持二级缓存(在 IUserDao.xml) 中配置
<cache/>
第三步:让当前的操作支持二级缓存(在 Select 标签中配置)
<select id="findById" parameterType="int" resultTyp="user" useCache="true"> select * ferm user where id=#{uid} </select>
主配置文件
实体类配置文件
测试类
注意:
再次强调:二级缓存内存放的是数据,而不是对象。当每次从二级缓存中拿取数据时,会重新进行封装对象操作,所以从二级缓存内取到的对象不是同一个
Mybatis 中的注解开发
在 Mybatis 框架中,只能存在一种解析方式,即要么使用配置文件方式,要么使用注解方式,不能两者同时存在
前期准备
pom.xml
<?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.itheima.mybatis</groupId> <artifactId>day05_mybatis_annotation02</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>5.4.2</version> <scope>test</scope> </dependency> </dependencies> </project>
Mybatis 所需要的配置文件
jdbcConfig.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/exercise?useSSL=false jdbc.username=root jdbc.password=root
log4j.properties
log4j.rootCategory = debug,CONSOLE,LOGFILE log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE log.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x -%m\n log4j.appender.LOGFILE=org.apache.log4j.FileAppender log4j.appender.LOGFILE.File=d:\axis.log log4j.appender.LOGFILE.Append=true log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x -%m\n
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> <!-- 引入外部配置文件--> <properties resource="jdbcConfig.properties"></properties> <!-- 配置别名 --> <typeAliases> <package name="com.lgl.mybatis.domain.User"/> </typeAliases> <!-- 配置环境 --> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <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> <!-- 指定带有注解的 dao 接口所在位置--> <mappers> <package name="com.lgl.mybatis.dao"/> </mappers> </configuration>
CRUD 操作
实体类
package com.lgl.mybatis.Test; import java.io.Serializable; import java.util.Date; public class User implements Serializable { private int id; private String username; private String address; private Date birthday; 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 String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", address='" + address + '\'' + ", birthday=" + birthday + '}'; } }
实体类 dao 接口
package com.lgl.mybatis.dao; import com.lgl.mybatis.Test.User; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import java.util.List; public interface IUserDao { /** * 查询所有用户方法 * @return */ @Select("select * from user") List<User> findAll(); /** * 通过主键 id 查询该用户所有信息 * @param id * @return */ @Select("select * from user where id=#{id}") User findOne(int id); /** * 添加新用户信息 * @param user */ @Insert("insert into user(username,address,birthday) values (#{username},#{address},#{birthday})") Boolean saveUser(User user); @Delete("delete from user where id=#{id}") /** 通过主键删除用户信息 */ Boolean deleteUser(int id); @Update("update user set username=#{username},address=#{address},birthday=#{birthday} where id=#{id}") Boolean updateUser(User user); /** * 查询用户数据条数 * @return */ @Select("select count(*) from user ") int findTotal(); /** * 查询用户名相似的用户集合 * @param name * @return */ // @Select("select * from user where username like #{name}") @Select("select * from user where username like '%${value}%' ") List<User> findByName(String name); }
测试类
package com.lgl.mybatis.Test; import com.lgl.mybatis.dao.IUserDao; 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.Date; import java.util.List; public class MybatisAnoTest { private InputStream in; private SqlSessionFactory factory; private SqlSession session; private IUserDao dao; @Before public void before() throws Exception{ in = Resources.getResourceAsStream("SqlMapConfig.xml"); factory = new SqlSessionFactoryBuilder().build(in); session = factory.openSession(); dao = session.getMapper(IUserDao.class); } @After public void after() throws Exception{ session.commit(); session.close(); in.close(); } @Test public void TestFind(){ List<User> all = dao.findAll(); for(User a : all){ System.out.println(a); } } @Test public void TestFindOne(){ User one = dao.findOne(1); System.out.println(one); } @Test public void TestUpdate(){ User u = new User(); u = dao.findOne(56); System.out.println(u); u.setUsername("cnm"); u.setBirthday(new Date()); u.setAddress("YN"); System.out.println(u); System.out.println(dao.updateUser(u)); } @Test public void TestSave(){ User u = new User(); u.setAddress("aa"); u.setBirthday(new Date()); u.setUsername("bb"); System.out.println(dao.saveUser(u)); } @Test public void TestDelete(){ System.out.println(dao.deleteUser(65)); } @Test public void TestTotal(){ System.out.println(dao.findTotal()); } @Test public void TestFindByName(){ // List<User> byName = dao.findByName("%王%"); List<User> byName = dao.findByName("王"); for(User u:byName){ System.out.println(u); } } }
别名的 CRUD 操作
说明
-
配置文件与上同
-
此开发方法存在于数据库的列名与实体类的属性名不相同时
实体类
package com.lgl.mybatis.domain; import java.io.Serializable; import java.util.Date; public class User implements Serializable { private int userId; private String userName; private String userAddress; private Date userBirthday; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserAddress() { return userAddress; } public void setUserAddress(String userAddress) { this.userAddress = userAddress; } public Date getUserBirthday() { return userBirthday; } public void setUserBirthday(Date userBirthday) { this.userBirthday = userBirthday; } @Override public String toString() { return "User{" + "userId=" + userId + ", userName='" + userName + '\'' + ", userAddress='" + userAddress + '\'' + ", userBirthday=" + userBirthday + '}'; } }
实体类 dao 接口
package com.lgl.mybatis.dao; import com.lgl.mybatis.domain.User; import org.apache.ibatis.annotations.*; import java.util.List; 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 = "birthday",property = "userBirthday") }) List<User> findAll(); /** * 通过主键 id 查询该用户所有信息 * @param id * @return */ @Select("select * from user where id=#{id}") @ResultMap(value={"userMap"}) User findOne(int id); /** * 添加新用户信息 * @param user */ @Insert("insert into user(username,address,birthday) values (#{userName},#{userAddress},#{userBirthday})") @ResultMap(value={"userMap"}) Boolean saveUser(User user); @ResultMap(value={"userMap"}) @Delete("delete from user where id=#{id}") /** 通过主键删除用户信息 */ Boolean deleteUser(int id); @ResultMap(value={"userMap"}) @Update("update user set username=#{userName},address=#{userAddress},birthday=#{userBirthday} where id=#{userId}") Boolean updateUser(User user); /** * 查询用户数据条数 * @return */ @Select("select count(*) from user ") int findTotal(); /** * 查询用户名相似的用户集合 * @param name * @return */ @ResultMap("userMap") // @Select("select * from user where username like #{name}") @Select("select * from user where username like '%${value}%' ") List<User> findByName(String name); }
测试类
package com.lgl.mybatis.domain; import com.lgl.mybatis.dao.IUserDao; 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.Date; import java.util.List; public class MybatisAnoTest { private InputStream in; private SqlSessionFactory factory; private SqlSession session; private IUserDao dao; @Before public void before() throws Exception{ in = Resources.getResourceAsStream("SqlMapConfig.xml"); factory = new SqlSessionFactoryBuilder().build(in); session = factory.openSession(); dao = session.getMapper(IUserDao.class); } @After public void after() throws Exception{ session.commit(); session.close(); in.close(); } @Test public void TestFind(){ List<User> all = dao.findAll(); for(User a : all){ System.out.println(a); } } @Test public void TestFindOne(){ User one = dao.findOne(1); System.out.println(one); } @Test public void TestSaveUser(){ User u = new User(); u.setUserName("aa"); u.setUserAddress("云南"); u.setUserBirthday(new Date()); System.out.println(dao.saveUser(u)); } @Test public void TestDelete(){ Boolean aBoolean = dao.deleteUser(67); System.out.println(aBoolean); } @Test public void TestUpdate(){ User u = new User(); u.setUserId(66); u.setUserName("bb"); u.setUserBirthday(new Date()); u.setUserAddress("贵州"); System.out.println(dao.updateUser(u)); } @Test public void TestFindTotal(){ System.out.println(dao.findTotal()); } @Test public void TestFindName(){ System.out.println(dao.findByName("王")); } }
注解开发一对一(一对多)
前期准备
-
添加实体类 Account
实体类:
package com.lgl.mybatis.domain; import java.io.Serializable; public class Account implements Serializable { private int id; private int aid; private double money; // 多对一(mybatis中称之为一对一的映射);一个账户只能属于一个用户 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 getAid() { return aid; } public void setAid(int aid) { this.aid = aid; } public double getMoney() { return money; } public void setMoney(double money) { this.money = money; } @Override public String toString() { return "account{" + "id=" + id + ", aid=" + aid + ", money=" + money + '}'; } }
package com.lgl.mybatis.domain; import java.io.Serializable; import java.util.Date; public class User implements Serializable { private int userId; private String userName; private String userAddress; private Date userBirthday; public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserAddress() { return userAddress; } public void setUserAddress(String userAddress) { this.userAddress = userAddress; } public Date getUserBirthday() { return userBirthday; } public void setUserBirthday(Date userBirthday) { this.userBirthday = userBirthday; } @Override public String toString() { return "User{" + "userId=" + userId + ", userName='" + userName + '\'' + ", userAddress='" + userAddress + '\'' + ", userBirthday=" + userBirthday + '}'; } }
实体类 dao 接口
IAccountDao.java
package com.lgl.mybatis.dao; import com.lgl.mybatis.domain.Account; import org.apache.ibatis.annotations.*; import org.apache.ibatis.mapping.FetchType; import java.util.List; public interface IAccountDao { /** * 查询所有账户,并且获取每个账户下用户的所属信息 * @return */ @Select("select * from account") @Results(id = "accountMap",value = { @Result(id = true,column = "id",property = "id"), @Result(column = "aid",property = "aid"), @Result(column = "money",property = "money"), @Result(property = "user",column = "aid", one = @One(select = "com.lgl.mybatis.dao.IUserDao.findOne", fetchType = FetchType.EAGER)) }) List<Account> findAll(); }
IUserDao.java
package com.lgl.mybatis.dao; import com.lgl.mybatis.domain.User; import org.apache.ibatis.annotations.*; import java.util.List; 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 = "birthday",property = "userBirthday") }) List<User> findAll(); /** * 通过主键 id 查询该用户所有信息 * @param id * @return */ @Select("select * from user where id=#{id}") @ResultMap(value={"userMap"}) User findOne(int id); /** * 添加新用户信息 * @param user */ @Insert("insert into user(username,address,birthday) values (#{userName},#{userAddress},#{userBirthday})") @ResultMap(value={"userMap"}) Boolean saveUser(User user); @ResultMap(value={"userMap"}) @Delete("delete from user where id=#{id}") /** 通过主键删除用户信息 */ Boolean deleteUser(int id); @ResultMap(value={"userMap"}) @Update("update user set username=#{userName},address=#{userAddress},birthday=#{userBirthday} where id=#{userId}") Boolean updateUser(User user); /** * 查询用户数据条数 * @return */ @Select("select count(*) from user ") int findTotal(); /** * 查询用户名相似的用户集合 * @param name * @return */ @ResultMap("userMap") // @Select("select * from user where username like #{name}") @Select("select * from user where username like '%${value}%' ") List<User> findByName(String name); }
测试类
AccountTest.java
package com.lgl.mybatis.domain; import com.lgl.mybatis.dao.IAccountDao; 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 SqlSessionFactory factory; private SqlSession session; private IAccountDao dao; @Before public void before() throws Exception{ in = Resources.getResourceAsStream("SqlMapConfig.xml"); factory = new SqlSessionFactoryBuilder().build(in); session = factory.openSession(); dao = session.getMapper(IAccountDao.class); } @After public void after() throws Exception{ session.commit(); session.close(); in.close(); } @Test public void TestFind(){ List<Account> all = dao.findAll(); for (Account a:all){ System.out.println("-------------每个账户信息---------------"); System.out.println(a); System.out.println(a.getUser()); } } }
注解开发一对多(多对多)
实体类
User.java
package com.lgl.mybatis.domain; import java.io.Serializable; import java.util.Date; import java.util.List; public class User implements Serializable { private int userId; private String userName; private String userAddress; private Date userBirthday; // 一对多:一个用户有多个账户信息 private List<Account> accounts; public List<Account> getAccounts() { return accounts; } public void setAccounts(List<Account> accounts) { this.accounts = accounts; } public int getUserId() { return userId; } public void setUserId(int userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserAddress() { return userAddress; } public void setUserAddress(String userAddress) { this.userAddress = userAddress; } public Date getUserBirthday() { return userBirthday; } public void setUserBirthday(Date userBirthday) { this.userBirthday = userBirthday; } @Override public String toString() { return "User{" + "userId=" + userId + ", userName='" + userName + '\'' + ", userAddress='" + userAddress + '\'' + ", userBirthday=" + userBirthday + '}'; } }
实体类 dao 接口
IAccountDao.java
package com.lgl.mybatis.dao; import com.lgl.mybatis.domain.Account; import org.apache.ibatis.annotations.*; import java.util.List; public interface IAccountDao { /** * 查询所有账户,并且获取每个账户下用户的所属信息 * @return */ @Select("select * from account") @Results(id = "accountMap",value = { @Result(id = true,column = "id",property = "id"), @Result(column = "aid",property = "aid"), @Result(column = "money",property = "money") }) List<Account> findAll(); /** * 根据用户主键查询账户信息 * @param id * @return */ @Select("select * from account where aid=#{aid}") Account findByAid(int id); }
IUserDao.java
package com.lgl.mybatis.dao; import com.lgl.mybatis.domain.User; import org.apache.ibatis.annotations.*; import org.apache.ibatis.mapping.FetchType; import java.util.List; 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 = "birthday",property = "userBirthday"), @Result(property = "accounts",column = "id", many = @Many(select = "com.lgl.mybatis.dao.IAccountDao.findByAid", fetchType=FetchType.LAZY)) }) List<User> findAll(); /** * 通过主键 id 查询该用户所有信息 * @param id * @return */ @Select("select * from user where id=#{id}") @ResultMap(value={"userMap"}) User findOne(int id); /** * 添加新用户信息 * @param user */ @Insert("insert into user(username,address,birthday) values (#{userName},#{userAddress},#{userBirthday})") @ResultMap(value={"userMap"}) Boolean saveUser(User user); @ResultMap(value={"userMap"}) @Delete("delete from user where id=#{id}") /** 通过主键删除用户信息 */ Boolean deleteUser(int id); @ResultMap(value={"userMap"}) @Update("update user set username=#{userName},address=#{userAddress},birthday=#{userBirthday} where id=#{userId}") Boolean updateUser(User user); /** * 查询用户数据条数 * @return */ @Select("select count(*) from user ") int findTotal(); /** * 查询用户名相似的用户集合 * @param name * @return */ @ResultMap("userMap") // @Select("select * from user where username like #{name}") @Select("select * from user where username like '%${value}%' ") List<User> findByName(String name); }
测试类
package com.lgl.mybatis.domain; import com.lgl.mybatis.dao.IUserDao; 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.Date; import java.util.List; public class UserTest { private InputStream in; private SqlSessionFactory factory; private SqlSession session; private IUserDao dao; @Before public void before() throws Exception{ in = Resources.getResourceAsStream("SqlMapConfig.xml"); factory = new SqlSessionFactoryBuilder().build(in); session = factory.openSession(); dao = session.getMapper(IUserDao.class); } @After public void after() throws Exception{ session.commit(); session.close(); in.close(); } @Test public void TestFind(){ List<User> all = dao.findAll(); for(User a : all){ System.out.println("----------每个用户的信息---------------"); System.out.println(a); System.out.println(a.getAccounts()); } } }
效果图
注解开发二级缓存
@CacheNamespace(blocking=true)
package com.lgl.mybatis.dao;
import com.lgl.mybatis.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
/*
开启二级缓存
*/