框架阶段:mybatis
1. mybatis简介
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
2. 通过入门案例了解mybatis
2.1 mybatis环境
- 新建maven项目,导入mybatis相关的依赖
<!-- mybaits-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- log4j-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
- 数据库环境
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` date DEFAULT NULL COMMENT '生日',
`sex` char(1) DEFAULT NULL COMMENT '性别',
`address` varchar(256) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8;
- log4j配置文件(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
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
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
# LOGFILE is set to be a File appender using a PatternLayout.
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
- mybaits主配置文件(SqlSessionFactory.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>
<!-- 配置环境-->
<environments default="mysql">
<!-- 配置MySQL的环境-->
<environment id="mysql">
<!-- 配置事务类型-->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接池-->
<dataSource type="POOLED">
<!-- 配置数据库的基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource
</environment>
</environments>
<!-- 指定映射配置文件-->
<mappers>
<mapper resource="com/itzpx/dao/IUserDao.xml"/>
</mappers>
</configuration>
- dao(mapper)的映射文件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.itzpx.dao.IUserDao">
<!-- 配置查询所有-->
<select id="findAll" resultType="com.itzpx.domain.User">
select * from user
</select>
</mapper>
- dao(mapper)IUserDao.java
public interface IUserDao {
//查询所有
List<User> findAll();
}
- 实体类domain
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
注意:
- log4j.properties、SqlMapConfig.xml文件放在resource目录下
- IUserDao.java文件必须与IUserDao.xml文件目录名相同
2.2 有了以上环境就可以实现入门案例
@Test
public void TestFindAll() throws Exception {
//1.读取配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(is);
//3.使用工厂生成SQLSession对象
SqlSession sqlSession = factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
IUserDao dao = sqlSession.getMapper(IUserDao.class);
//5.使用代理对象执行方法
List<User> all = dao.findAll();
for (User user : all) {
System.out.println(user);
}
//6.释放资源
sqlSession.close();
is.close();
}
2.3 通过入门案例简单分析里面的对象
- SqlSessionFactory (SqlSession工厂对象)
功能:
一,加载SqlMapConfig.xml配置文件,连接数据库
二,读取SqlMapConfig.xml配置文件下配置的映射文件信息
三,生产Session
方法:
一,openSession();产生session对象 - SqlSession (数据库操作对象)
功能:
一,产生动态代理对象(该对象取代实现类)
二,执行sql查询
方法:
一,getMapper(Class);产生动态代理对象
二,**commit();**提交事务
三,里面定义了增删改查的所有方法来执行sql语句 - SqlSessionFactoryBuilder 创建工厂的对象
功能:
一,创建SqlSessionFactory 对象,SqlSessionFactory 是个接口,无法new
方法:
一,build(InputStream);加载配置文件,创建工厂对象
3. mybaits的crud
3.1 简单的crud
一. 添加User
<!-- 添加User-->
<insert id="saveUser" parameterType="com.itzpx.domain.User">
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address});
</insert>
其中
- id=“saveUser” 表示IUserDao中定义的添加方法名字为saveUser
- parameterType="com.itzpx.domain.User"表示传递的参数类型为User对象
- selectKey标签为获取插入后的id
- keyProperty实体类的id
- keyColumn表中的id
- resultType返回值类型
- #{username}代表获取传递过来的User对象中的username属性值,如果属性值与该属性的getUsername方法的Username不同,以Username为准。
二、删除User
<!-- 删除User-->
<delete id="deletUser" parameterType="Integer">
delete from user where id = #{id}
</delete>
三、修改User
<!-- 修改User-->
<update id="updateUser" parameterType="com.itzpx.domain.User">
update user set username = #{username},birthday = #{birthday},sex = #{sex},address = #{address} where id = #{id}
</update>
四、查询
<!-- 根据用户名查询-->
<select id="findUserbyUserName" parameterType="String" resultType="com.itzpx.domain.User">
select * from user where username = #{username}
</select>
五、模糊查询两种方式给%%
第一种方式在调用方法的时候需要传递%参数%
也就是List users = dao.findUserByUsernameLike("%王%");
<!-- 模糊查询-->
<select id="findUserByUsernameLike" parameterType="String" resultType="com.itzpx.domain.User">
select * from user where username like #{username}
</select>
第二种方式使用’%${value}%'的书写格式给百分号
<select id="findUserByUsernameLike2" parameterType="String" resultType="com.itzpx.domain.User">
select * from user where username like '%${value}%'
</select>
注意${value}中的value是固定的,不能修改
第一种方式sql语句参数的赋值为占位符方式,也就是%?%,用paramters去赋值
第二种方式sql语句参数为拼接字符串的方式,也就是%王%
提问,为什么可以使用属性直接获取值呢?
- mybaits使用了OGNL表达式,对象图导航语言,也就是省略了user.getXXX()。
直接使用user.XXX的方式,而在parpameterType中已经提供了user,所以在取值的时候,可以直接使用XXX。
XXX代表属性名称,getXXX().
3.2 深入复杂的crud
一、条件类型的封装
将多个对象封装为一个对象作为查询条件进行查询
public class QueryVo {
public User getUser() {
return user;
}
<!-- 条件类型的封装-->
<select id="findUserByQueryVo" parameterType="com.itzpx.domain.QueryVo" resultType="com.itzpx.domain.User">
select * from user where username like #{user.userName}
</select>
注意:在开发过程中,可能需要将一个或多个对象,封装为一个对象进行查询,所以在取值的时候需要用点来获取对象中的属性值
二、当数据库列名与实体类中的属性名不一致,怎么办?
解决方法:
- 查询语句取别名
<select id="findAll" resultType="com.itzpx.domain.User">
select id as userId,username as userName,birthday as userBirthday,sex as userSex,address as userAddress from user
</select>
- resultMap方式
<resultMap id="userMap" type="com.itzpx.domain.User">
<id property="userId" column="id"/>
<result property="userName" column="username"/>
<result property="userBirthday" column="birthday"/>
<result property="userSex" column="sex"/>
<result property="userAddress" column="address"/>
</resultMap>
<!-- 配置查询所有-->
<select id="findAll" resultMap="userMap">
select * from user
</select>
注意:resultMap=“userMap”
4. properties标签的使用
第一种
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</properties>
<!-- 配置环境-->
<environments default="mysql">
<!-- 配置MySQL的环境-->
<environment id="mysql">
<!-- 配置事务类型-->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接池-->
<dataSource type="POOLED">
<!-- 配置数据库的基本信息-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
第二种、将配置信息定义到jdbcConfig.properties文件中
<properties resource="jdbcConfig.properties">
</properties>
<!-- 配置环境-->
<environments default="mysql">
<!-- 配置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>
注意:里面还有个属性是url,是统一资源定位符
写法为:协议,主机名,端口号,uri
支持http协议
也支持file协议
5. typeAliases标签的使用
主配置文件下的标签
主要功能,给domain下的实体类其别名
<typeAliases>
<typeAlias type="com.itzpx.domain.User" alias="user"></typeAlias>
</typeAliases>
起完别名后不再区分大小写
也就是说在mapper.xml文件中就就不用写全限定类名了,直接写别名
当然,一个一个的起别名,很麻烦,不如一起起别名
<typeAliases>
<!-- <typeAlias type="com.itzpx.domain.User" alias="user"></typeAlias>-->
<package name="com.itzpx.domain"/>
</typeAliases>
这种方式以domain包下面的实体类,类名为别名
package标签还有一种使用
<!-- 指定映射配置文件-->
<mappers>
<!-- <mapper resource="com/itzpx/dao/IUserDao.xml"/>-->
<!-- <mapper class="com.itzpx.dao.IUserDao"/>-->
<package name="com.itzpx.dao"/>
</mappers>
在指定加载映射配置文件的时候,一个一个加太麻烦,一股脑的加
注意:不管是mapper.xml方式,还是注解方式都不用写了,也就是不用写resource,和class
6. 连接池
6.1 连接池的使用
mybatis连接池提供了3种方式的配置
配置的位置:
主配置文件SqlMapConfig.xml中的dataSource标签,type属性就是表示采用何种连接池方式。
type属性的取值:
POOLED 采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现
UNPOOLED 采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。
JNDI 采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。
注意:如果不是web或者maven的war工程,是不能使用的。
我们使用的是tomcat服务器,采用连接池就是dbcp连接池。
6.2 连接池分析
UNPOOLED:
在mybatis中的实现类是UnpooledDataSource
其通过分析getConnection()方法可以看出
其获取Connection的方式是直接加载驱动,获取连接后返回连接
由此可以看出其并未使用连接池
POOLED
在mybatis中的实现类是PooledDataSource
getConnection()方法调用了popConnection()
步骤
- while(conn == null) {//如果没有连接
- synchronized(this.state) {//同步代码块,说明连接池必须是线程安全的
- if (!this.state.idleConnections.isEmpty()) {//如果没有空闲的连接
- idleConnections代表的就是一个ArrayList集合
按照此步骤推理下去
POOLED是使用了自定义的连接池技术
在PooledDataSource类中定义了连接池的默认属性,这些属性可以在主配置文件中修改
protected int poolMaximumActiveConnections = 10;
protected int poolMaximumIdleConnections = 5;
protected int poolMaximumCheckoutTime = 20000;
protected int poolTimeToWait = 20000;
protected int poolMaximumLocalBadConnectionTolerance = 3;
7. 事务
7.1 事务的使用
主要是通过两个方法
commit();
rollback();
7.2 事务分析
mybaits中事务是默认不提交的
需要手动提交事务
也可以设置为自动提交事务
在factory.openSession(true);
创建sqlsession的时候
8. 动态sql语句
8.1 if
判断是否由条件
<select id="findUserByEv" parameterType="user" resultMap="userMap">
select * from user where 1 = 1
<if test="userName != null">
and username = #{userName}
</if>
<if test="userBirthday != null">
and birthday = #{userBirthday}
</if>
</select>
注意:其中不能使用&& || 的符号,只能用and or作为条件连接
8.2 where
where主要是去除where 1 = 1这一端,他会根据是否由条件进行拼接字符串
<select id="findUserByEv" parameterType="user" resultMap="userMap">
select * from user
<where>
<if test="userName != null">
and username = #{userName}
</if>
<if test="userSex != null">
and sex = #{userSex}
</if>
</where>
</select>
8.3 foreach
主要是对集合的遍历
<!-- 查询条件中有集合,如何去遍历集合-->
<select id="findUserOnIds" parameterType="com.itzpx.domain.QueryVo" resultMap="userMap">
select * from user
<where>
<if test="ids != null and ids.size()>0">
<foreach collection="ids" open="and id in(" close=")" separator="," item="uid">
#{uid}
</foreach>
</if>
</where>
</select>
其中collection=“ids”//表示需要被遍历的集合
open=“and id in(”//表示拼接的开始
close=")"//表示拼接的结束
separator=","//表示分割的符号
item=“uid”//表示从集合中遍历出来的数据
#{uid}//代表取出数据
结果是
select * from user WHERE id in( ? , ? , ? )
提问:为什么要加and id in(
可能是如果where后面如果有条件的话
select * from user WHERE 其他条件 and id in( ? , ? , ? )
如果没有其他条件,mybaits会把and去掉
8.4 sql标签
公共代码片段的抽取
<sql id="selectId">
select * from user
</sql>
<include refid="selectId"/>
9. 多表操作
9.1 一对多
描述:一个用户,有多个账户
在查询多表时
select * from user,account
这样的语句返回的结果集,关系到多个实体类,所以需要定义
resultMap,来封装结果集
注意:在user实体类中定义account的集合,set\get
<resultMap id="userAccountMap" type="user">
<!-- 定义user表字段的封装-->
<id property="id" column="id"/>
<result property="userName" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<!-- 定义user表关联的account表的数据封装-->
<collection property="accounts" column="uid" ofType="account">
<id property="id" column="aid"/>
<result property="uid" column="uid"/>
<result property="money" column="money"/>
</collection>
</resultMap>
<!-- 配置查询所有-->
<select id="findAll" resultMap="userAccountMap">
SELECT
*
FROM
user AS u
LEFT JOIN
account AS a
ON
u.id = a.uid
</select>
9.2 一对一
描述:一对一其实是多对一,在mybaits中认为一个账户只能对应一个用户,这就是一对一,其实多个账户能对应一个用户,但在mybaits中没有这种说法,所以统一为一对一
查询所有账户的用户信息
<resultMap id="accountUserMap" type="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--和一对多不同,使用的是association 标签-->
<association property="user" column="uid" javaType="user">
<id property="id" column="id"></id>
<result column="username" property="userName"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
</association>
</resultMap>
<!-- 配置查询所有账户的用户信息-->
<select id="findAll" resultMap="accountUserMap">
SELECT
u.*,a.id as aid,a.uid,a.money
FROM
account as a,
user as u
WHERE
u.id = a.uid
</select>
注意:account实体类中,有user对象定义 get/set
9.3 多对多
描述:一个用户可以拥有多个角色,一个角色赋予多个用户,
这种表关系就需要中间表进行连接,中间表主要字段uid,rid,
多对多,写法和一对多写法类似
1.查询用户所拥有的角色信息
<resultMap id="userMap" type="user">
<id property="id" column="id"></id>
<result property="userName" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<collection property="roles" column="rid" ofType="role">
<id property="roleId" column="rid"/>
<result property="roleName" column="ROLE_NAME"/>
<result property="roleDesc" column="ROLE_DESC"/>
</collection>
</resultMap>
<!-- 配置查询所有-->
<select id="findAll" resultMap="userMap">
SELECT
u.*,r.id AS rid,r.ROLE_NAME,r.ROLE_DESC
FROM
user AS u
LEFT JOIN
user_role AS ur
ON
u.id=ur.uid
LEFT JOIN
role AS r
ON
r.id=ur.rid
</select>
2.反过来查询角色赋予的用户信息
<resultMap id="roleMap" type="role">
<id property="roleId" column="id"></id>
<result property="roleName" column="ROLE_NAME"></result>
<result property="roleDesc" column="ROLE_DESC"></result>
<collection property="users" column="uid" ofType="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>
</resultMap>
<!-- 配置查询所有-->
<select id="findAll" resultMap="roleMap">
SELECT
r.*,u.id AS uid,u.username,u.birthday,u.sex,u.address
FROM
role r
LEFT JOIN
user_role ur
ON
r.id=ur.rid
LEFT JOIN
user u
ON
u.id = ur.uid
</select>
注意:user实体类中有role集合,role实体类中有user集合
10. 延迟加载
10.1 一对一的延迟加载
查询用户信息时,用户所关联的账户信息在需要的时候加载。
这就是延迟加载
需要在主配置文件中开启延迟加载
<!-- 配置开启延迟加载-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
查询所有账户
<resultMap id="accountUserMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<association property="user" column="uid" javaType="user" select="com.itzpx.dao.IUserDao.findAllById"></association>
</resultMap>
<!-- 配置查询所有账户的用户信息-->
<select id="findAll" resultMap="accountUserMap">
SELECT
*
FROM
account
</select>
select=“com.itzpx.dao.IUserDao.findAllById”
表示的时,调用findAllById方法,根据column="uid"去查询account表
该方法在com.itzpx.dao.IUserDao中
<!-- 根据id查询-->
<select id="findAllById" resultType="user" parameterType="int">
SELECT
*
FROM
user u
WHERE
u.id = #{uid}
</select>
当查询出来的account列表被使用到的时候,就会调用findAllById,查出用户信息
10.2 一对多的延迟加载
查询user表,
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"/>
<result property="userName" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<collection property="accounts" column="id" ofType="account" select="com.itzpx.dao.IAccountDao.findAccountById"></collection>
</resultMap>
<!-- 配置查询所有-->
<select id="findAll" resultMap="userAccountMap">
SELECT
*
FROM
user
</select>
<select id="findAccountById" resultType="account" parameterType="int">
select * from account where uid = #{uid}
</select>
11. 缓存
11.1 一级缓存
一、如何使用一级缓存
一级缓存,与sqlSession相关,当重复调用查询方法时,且参数相同,就会到sqlSession中查询一级缓存
User user1 = userDao.findUserById(45);
system.out.prinl(user1);
User user2 = userDao.findUserById(45);
system.out.prinl(user2);
system.out.prinl(user1 == user2);
此时,user1与user2为同一个对象,地址都一样,比较结果为true
二、如何关闭一级缓存
一级缓存关闭,或消失
- sqlSession对象消失
- sqlSession.clearCache();调用该方法,清空一级缓存
- 执行update、insert、delete、commit、等方法
11.2 二级缓存
一、二级缓存的描述
该缓存,由sqlSessionFactory提供,同一个sqlSessionFactory,创建的所有sqlSession共享其缓存。
二、如何开启二级缓存
三步
- sqlMapConfig配置文件中开启二级缓存
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
- Mapper配置文件中开启二级缓存
<cache/>
- select标签中开启二级缓存,useCache=“true”
<select id="findAll" .... useCache="true">
三、验证二级缓存
在同一个sqlSessionFactory下创建的不同sqlSession,执行同一个方法,比如说执行findAll();
结果:mybaits,只查询一次,其他相同查询都在缓存中拿数据
12. 注解开发
12.1 环境搭建
12.2 单表crud
//查询所有
@Select(value="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")
})
List<User> findAll();
//根据ID查询用户
@Select("select * from user where id = #{id}")
@ResultMap(value="userMap")
User findUserById(Integer id);
//根据ID修改用户
@Update(value="update user set username = #{userName}," +
"birthday = #{userBirthday}," +
"sex = #{userSex}," +
"address = #{userAddress} " +
"where id = #{userId}")
void updateUser(User user);
//添加一条数据
@Insert("insert into user (id,username,birthday,sex,address) values (null,#{userName},#{userBirthday},#{userSex},#{userAddress})")
Integer interUser(User user);
12.3 多表查询
一对一
//查询账户信息,与账户相关的用户信息
@Select("select * from account")
@Results(id="accountMap",value={
@Result(id=true,column="id",property="accountId"),
@Result(column="uid",property="accountUid"),
@Result(column="money",property="accountMoney"),
@Result(one = @One(select = "com.itzpx.dao.IUserDao.findUserById"),column = "uid",property = "user")
})
List<Account> findAll();
//根据uid查询account
@Select("select * from account where uid = #{uid}")
@ResultMap(value="accountMap")
Account findAccountByUid(Integer uid);
//查询所有
@Select(value="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")
})
List<User> findAll();
//根据ID查询用户
@Select("select * from user where id = #{id}")
@ResultMap(value="userMap")
User findUserById(Integer id);
一对多
//查询用户,及关联的账户
@Select("select * from user")
@Results(id="userAccountMap",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(many = @Many(select = "com.itzpx.dao.IAccountDao.findAccountByUid"),column = "id",property = "accounts")
})
List<User> findUserAndAccount();
//查询账户信息,与账户相关的用户信息
@Select("select * from account")
@Results(id="accountMap",value={
@Result(id=true,column="id",property="accountId"),
@Result(column="uid",property="accountUid"),
@Result(column="money",property="accountMoney"),
@Result(one = @One(select = "com.itzpx.dao.IUserDao.findUserById"),column = "uid",property = "user")
})
List<Account> findAll();
//根据uid查询account
@Select("select * from account where uid = #{uid}")
@ResultMap(value="accountMap")
Account findAccountByUid(Integer uid);
多对多
注意:多对多在sql中需要使用一些技巧,不能使用left join一路连接过去,应该
这样写:id(column = “id”)传递过去,然后根据id查询
@Select(“select * from user where id in (select uid from user_role where rid = #{id})”)
//查询所有
@Select("select * from role")
@Results(id="roleMap",value={
@Result(id=true,column = "id",property="roleId"),
@Result(column = "ROLE_NAME",property="roleName"),
@Result(column = "ROLE_DESC",property="roleDesc"),
@Result(many = @Many(select = "com.itzpx.dao.IUserDao.findUserById2"),column = "id",property = "users")
})
List<Role> findAll();
//根据ID查询用户
@Select("select * from user where id in (select uid from user_role where rid = #{id})")
@ResultMap(value="userMap")
List<User> findUserById2(Integer id);
12.4 缓存配置
在dao接口上添加
@CacheNamespace(blocking = true)
13 mybaits留下的知识点
- 自定义mybaits
- JDNI数据源(基本使用已了解)