写的不好,勿喷
封装了jdbc操作的很多细节,使开发者只需要关注sql本身
使用了orm思想实现了结果集的封装
orm:就是把数据库表和实体类及实体类的属性对应起来,让我们可以操作实体类就实现操作数据库表
第一步:创建maven工程并导入坐标
第二步:创建实体类和dao的接口
第三步:创建Mybatis的主配置文件
zpcad.xml
第四步:创建映射配置文件
ZDao.xml
注:其需要数据库(我用的是mysql)
创建一个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>org.example</groupId>
<artifactId>springboot-01-helloword</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
再给其内添加,使其可以打包成jar包
<packaging>jar</packaging>
添加mybatis,mysql,单元测试,其可自动导入这些包,注:最好改成阿里云
详情可见我的笔记Z6
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
再创建一个类,其内所定义的都是数据库中所有的(如id…)
package com.zpc;
import java.io.Serializable;
import java.util.Date;
public class user implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
}
在对其进行生成Getter and Setter和toString()方法,其所有定义的都需要生成
即:右键->Generate…->Getter and Setter
右键->Generate…->toString()
@Override
public String toString() {
return "user{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
其都是基于Dao操作,故再创建一个接口,即用户的持久层接口
package com.zpc.Dao;
import com.zpc.user;
import java.util.List;
public interface ZDao {
/**
* 查询所有操作
* @return
*/
List<user> findAll();
}
在resources下建一个xml文件(zpcad.xml),此乃基本配置
导入mybatis的约束
<?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">
开始给其配置环境,加入这些…
<!--mybatis的主配置文件-->
<configuration>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境,上下二者必须相同(myaql)-->
<environment id="mysql">
<!--配置事务类型(JDBC)-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)(POOLED)-->
<dataSource type="POOLED">
<!--配置连接数据库的四个基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--指定映射配置文件的位置(resource),映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<mapper resource="com/zpc/Dao/ZDao.xml"/>
</mappers>
</configuration>
注:其内并没有com/zpc/Dao/ZDao.xml,所以,开始在resources->Directory一次创立一个文件,在File创立ZDao.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">
开始给其配置环境
必须通过id和namespace合起来才能定位到
<mapper namespace="com.zpc.Dao.ZDao">
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll">
select * from user
</select>
</mapper>
第一:在idea中创建目录的时候,和包是不同的,包在创建时:com.zpc.Dao是三级结构。目录在创建时,com.zpc.Dao是一级目录
第二:mybatis的映射配置文件位置必须和dao接口的包结构相同
第三:映射配置文件的mapper标签和namespace属性的取值必须是dao接口的全限定类名
第四:映射配置文件的操作配置(select),id属性的取值必须是dao接口的方法名
# 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{IS08601} %-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{IS08601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
测试类
package com.zpc.test;
public class MybatisTest {
public static void main(String[] args) {
//1:读取配置文件
//2:创建SqlSessionFactory工厂
//3:使用工厂生产SqlSession对象
//4:使用SqlSession创建Dao接口的代理对象
//5:使用代理对象执行方法
//6:释放资源
}
}
//1:读取配置文件
InputStream in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactoryBuilder bulider=new SqlSessionFactoryBuilder();
SqlSessionFactory factory=bulider.build(in);
//3:使用工厂生产SqlSession对象
SqlSession session=factory.openSession();
//4:使用SqlSession创建Dao接口的代理对象
ZDao userDao=session.getMapper(ZDao.class);
//5:使用代理对象执行方法
List<user> users=userDao.findAll();
for(user usernew:users){
System.out.println(usernew);
}
//6:释放资源
session.close();
in.close();
在ZDao.xml中添加,使之指向user(全称)
其意思很简单,就是名字是"findAll",resultType是返回结果对象信息,来源于"com.zpc.user"
<select id="findAll" resultType="com.zpc.user">
完成,已经封装!
注:绝对路径(计算机差异)和相对路径(web项目一旦发布就没有src目录了)都不可用
所以:第一:使用类加载器,可以读取类路径的配置文件
第二:使用ServletContext的对象的getRealPath(),这样即便发布了项目也可用,他是指程序里的绝对路径,发布不发布无影响
builder就是构建者,相当于一个承包了项目的包工头,把对象的创建细节隐藏,使使用者直接调用方法即可拿到对象
这样可以降低类之间的关系(解耦)
创建Dao接口实现类使用了代理模式,可以在不修改源码的基础上对已有方法增强
//1:读取配置文件
InputStream in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactoryBuilder bulider=new SqlSessionFactoryBuilder();
SqlSessionFactory factory=bulider.build(in);
//3:使用工厂生产SqlSession对象
SqlSession session=factory.openSession();
//4:使用SqlSession创建Dao接口的代理对象
ZDao userDao=session.getMapper(ZDao.class);
//5:使用代理对象执行方法
List<user> users=userDao.findAll();
for(user usernew:users){
System.out.println(usernew);
}
//6:释放资源
session.close();
in.close();
就上个案例而言,将ZDao.xml移除,在dao接口的方法上使用@Select注解(这个注解就是查询),并且指定SQL语句
@Select("select * from user")
List<user> findAll();
同时需要在zpcad.xml中的mapper配置时,使用class属性指定dao接口的全限定类名
<mappers>
<mapper class="com.zpc.Dao.ZDao"/>
</mappers>
注:在实际开发中,不采用写dao实现类的方式,但mybatis还是支持写dao实现类的,但为了简便,不写
看看就行
连接数据库的信息,有其便可创建Connection对象
<!--配置连接数据库的四个基本信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
有其就有了映射配置信息
<mappers>
<mapper resource="com/zpc/Dao/ZDao.xml"/>
</mappers>
有其就有了可执行的sql语句,就可以获取PreparedSatement
<mapper namespace="com.zpc.Dao.ZDao">
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="com.zpc.user">
select * from user
</select>
读取配置文件:用到的就是解析XML的技术,此处用的就是dom4j解析xml技术
自定义mybatis能通过入门案例看到类
class Resources
class SqlSessionFactoryBuilder
interface SqlSessionFactory
interface SqlSession
将其删除,后而自己进行定义
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
故而,MybatisTest.java其内所有类和接口都需要进行定义
首先给其创建个类,即可实现第一个方法
package com.zpc.mybatis.io;
//使用类加载器读取配置文件的类
import sun.security.util.Resources;
import java.io.InputStream;
public class Resource {
//根据传入的参数,获取一个字节输入流
public static InputStream getResourceAsStream(String filePath){
return Resources.class.getClassLoader().getResourceAsStream(filePath);
//获取字节码,获取类加载器,读取配置
}
}
再创建个类SqlSessionFactoryBuilder
package com.zpc.mybatis.sqlsession;
//用于创建SqlSessionFactory对象
import java.io.InputStream;
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(InputStream config){
return null;
}
}
其内又需要定义一个接口SqlSessionFactory
package com.zpc.mybatis.sqlsession;
public interface SqlSessionFactory {
//用于打开一个新的SqlSession对象
SqlSession openSession();
}
SqlSessionFactory中还需继续定义一个接口SqlSession
package com.zpc.mybatis.sqlsession;
//自定义mybatis中和数据库交互的核心类,其里面可创建dao接口的代理对象
public interface SqlSession {
//根据参数创建一代理对象
<T> T getMapper(Class<T> daoInterfaceClass);
//释放资源
void close();
}
接下来就可删除那些报错的约束
算了,自己慢慢理解,这玩意没意思
在ZDao.java添加
/**
* 保存方法
* @param usernewf
*/
void saveUser(user usernewf);
再给ZDao.xml添加一个配置 (在配置文件中添加的都在中)
<!--保存用户-->
<insert id="saveUser" parameterType="com.zpc.user">
insert into user (username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
</insert>
先将原测试类MybatisTest.java更改,可以避免多次重复编写
private InputStream in;
private SqlSession sqlSession;
private ZDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession();
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(ZDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务,可保证每次提交都有事务的支持
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void TestfindAll(){
//5:使用代理对象执行方法
List<user> users= userDao.findAll();
for(user usernew:users){
System.out.println(usernew);
}
}
再给测试类MybatisTest.java添加一个新的测试方法
即给数据库中添加了如下那几个数据
/**
* 测试保存操作
*/
@Test
public void testSave(){
user usernew =new user();
usernew.setUsername("mybatis saveuser");
usernew.setAddress("北京市朝阳区");
usernew.setSex("男");
usernew.setBirthday(new Date());
//执行保存方法
userDao.saveUser(usernew);
}
运行后,即可保存
首先在ZDao.java中添加
/**
* 更新操作
* @param usernewf
*/
void updateUser(user usernewf);
在ZDao.xml中配置文件 parameterType是返回参数类型
<!--更新用户-->
<update id="updateUser" parameterType="com.zpc.user">
update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}
</update>
在MybatisTest.java中添加
/**
* 测试更新
*/
@Test
public void testUpdate(){
user usernew =new user();
usernew.setId(50);
usernew.setUsername("mybatis saveuser");
usernew.setAddress("北京市朝阳区");
usernew.setSex("女");
usernew.setBirthday(new Date());
//执行保存方法
userDao.saveUser(usernew);
}
由此即可完成更新(修改)操作
首先在ZDao.java中添加
/**
* 根据ID删除用户
* @param userId
*/
void deleteUser(Integer userId);
在ZDao.xml中配置文件
注:这块不再指向user,后面会解释
id=#{uid}随便起
<!--删除用户-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{uid}
</delete>
在MybatisTest.java中添加
/**
* 测试删除
*/
@Test
public void testDelete() {
//执行删除方法 删除id为48的
userDao.deleteUser(48);
}
即可完成删除操作
首先在ZDao.java中添加
/**
* 根据id查询
* @param userId
* @return
*/
user findById(Integer userId);
在ZDao.xml中配置文件
parameterType="TNT"随便,只要能表示出来他是个int(在ZDao.java中定义其为int)
resultType="com.zpc.user结果类型,因为返回值是user对象,需要告诉他封到哪里去
<!--根据id查询用户-->
<select id="findById" parameterType="TNT" resultType="com.zpc.user">
select * from user where id=#{uid}
</select>
在MybatisTest.java中添加
注:其返回值是user
/**
* 测试查找一个
*/
@Test
public void testFindOne() {
//执行删除方法 删除id为48的
user usernew=userDao.findById(50);
System.out.println(usernew);
}
接下来是模糊查询
首先在ZDao.java中添加
/**
* 根据名字模糊查询
* @param username
* @return
*/
List<user> findByName(String username);
在ZDao.xml中配置文件
<!--根据名称模糊查询-->
<select id="findByName" parameterType="string" resultType="com.zpc.user">
select * from user where username like #{name}
</select>
在MybatisTest.java中添加
注意添加%,不然凉凉,还有,为什么遍历你们大概都懂
当然,还可以将%加入到xml那里,不过那块就只能value了,所以不建议,那块了解下就行
/**
* 模糊查询
*/
@Test
public void testFindByName() {
//执行删除方法 删除id为48的
List<user> users=userDao.findByName("%王%");
for(user usersnew:users){
System.out.println(usersnew);
}
}
首先在ZDao.java中添加
/**
* 查询总用户数
* @return
*/
int findTotal();
在ZDao.xml中配置文件
<!--获取用户总记录条数-->
<select id="findTotal" resultType="int">
select count(id) from user;
</select>
在MybatisTest.java中添加
/**
* 测试查询总记录条数
*/
@Test
public void testFindTotal() {
//执行删除方法 删除id为48的
int count=userDao.findTotal();
System.out.println(count);
}
5:保存操作的细节,获取保存操作的id
配置插入操作后,获得插入数据的id
在ZDao.xml中的 配置文件
分别为id的属性名称,对应实体类,id的列名,对应表;结果集类型;什么时候执行
<!--保存用户-->
<insert id="saveUser" parameterType="com.zpc.user">
<!--配置插入操作后,获取插入数据的id-->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user (username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
</insert>
在MybatisTest.java中的 添加,更改的地方已经加上了/
public void testSave(){
user usernew =new user();
/usernew.setUsername("mybatis last insertid");
usernew.setAddress("北京市朝阳区");
usernew.setSex("男");
usernew.setBirthday(new Date());
//执行保存方法
userDao.saveUser(usernew);
/System.out.println(usernew);
}
mybatis使用ognl表达式解析对象字段的值,#{}或者¥{}括号中的值为pojo属性名称。
开发中通过pojo传递查询条件,查询条件是综合的查询条件,不仅包括用户查询条件还包括其他的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。pojo类中也包含了pojo。注:根据用户查询用户信息,查询条件放到QueryVo的user属性中
在ZDao.java中添加
/**
* 根据QueryVo中的条件查询用户
* @param vo
* @return
*/
List<user> findUserByVo(QueryVo vo);
并建立QueryVo类,且写入方法,取得Getter and Setter方法
package com.zpc;
public class QueryVo {
private user uservo;
public user getUservo() {
return uservo;
}
public void setUservo(user uservo) {
this.uservo = uservo;
}
}
在ZDao.xml写配置,注,那个uservo是前面类存在的,.username是获取名称
<!--根据queryVo条件查询用户-->
<select id="findUserByVo" parameterType="com.zpc.QueryVo" resultType="com.zpc.user">
select * from user where username like #{uservo.username}
</select>
在MybatisTest.java中
/**
* 测试使用QueryVo作为查询条件
*/
@Test
public void testFindByVo() {
//执行删除方法 删除id为48的
QueryVo vo=new QueryVo();
user userv=new user();
userv.setUsername("%王%");
vo.setUservo(userv); //setUservo方法位于QueryVo中
List<user> users=userDao.findUserByVo(vo);
for(user u:users){
System.out.println(u);
}
}
如果实体类和数据库的列名不一致:文件出错;配置文件也会发生错误;都需修改
改造完成后,增删改都可继续用,而查询,则是除了name之外全出错(mysql数据库在Windows下不区分大小写)。当然,如果大小写不对应,或没在windows下,是都会出错的
起个别名,在ZDao.xml的每个配置中添加
如:现文件
<select id="findAll" resultType="com.zpc.user">
select id as userId,username as userName,address as userAddress,sex as userSex,birthday as userBirthday from user;
</select>
原文件
select * from user:实体类名User
<select id="findAll" resultType="com.zpc.user">
select * from user;
</select>
将*换成了那些
另一种方法,即给ZDao.xml其加入一个配置即可
注:这个id值,自己起;type是表示对应的查询实体类
<resultMap id="userMap" type="com.zpc.user">
<!--主键-->
<id property="userId" column="id"></id>
<!--非主键-->
<result property="userName" column="username"></result>
<result property="userAddress" column="address"></result>
<result property="userSex" column="sex"></result>
<result property="userBirthday" column="birth"></result>
</resultMap>
但需将下面所有的resultType换成resultMap,resultMap指向上面的那个id(userMap)值
故而:第二种方法快捷,可增加开发效率
在zpcad.xml中的中添加
<!--配置properties-->
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>
将原来的配置信息中的value全部修改,使之引用上面的内容
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
即可执行成功
第二中方法(主要使用):上面的定义也可放在外部,如,先给resources导入一个文件jdbcConfig.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis
jdbc.username=root
jdbc.password=123456
同时将zpcad.xml中的如下,部分注释掉
<!--<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>-->
且在中添加,resource,用于指定外部信息的位置
<!--配置properties
可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件信息
resource:
用于指定配置文件的位置,是按照类路径的写法来写,且必须存在于类路经下
-->
<properties resource="jdbcConfig.properties">
且需要给那个value加前缀,用于和外部配置文件保持一直,如配置文件前都加有jdbc.
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
这样可运行成功
接下来是url方法:
url属性:是按照url的写法来写地址 统一资源定位符,他是唯一标识一个资源的位置
其写法:http://zoda:8080/mybatis/demol
协议 主机 端口 uri
uri:统一资源标识符,他是在应用中可以唯一定位一个资源的
将此方法之前的上一个方法做一点改变即可,将换成
<properties url="file:///D:/ideagongcheng/aoliig/src/main/resources">
注意:必须用file:///加上其路径
但该方法不灵活
6.1:使用typeAliases配置别名,他只能配置domain中类的别名
在zpcad.xml中的中添加
<typeAliases>
<!--typeAlias用于配置别名,type属性指定的是实体类全限定类名,alias属性指定别名,当指定了别名就不再区分大小写-->
<typeAlias type="com.zpc.user" alias="User"></typeAlias>
</typeAliases>
故而在其他文件,指定名字时就不区分大小写了,如user和User和uSer都是一样的
6.2:同时也可以将其更改,使用package,也可不区分大小写
package:用于指定要配置别名的包,当指定之后,该包下实体类都会注册别名,并且类名就是别名,不区分大小写,比上个方法简单很多
<typeAliases>
<!--删除了上个方法写的-->
<package name="com.zpc"></package>
</typeAliases>
6.2.1:package也可用到mappers
package标签是用于指定dao接口所在的包,当制定了之后就不需要再写mapper以及resource或者class了
如:在中,先删除
在添加,就成了
<mappers>
<package name="com.zpc.Dao"/>
</mappers>
连接池就是用于存储连接的一个容器
使用其可以减少获取连接的时间
容器其实就是一个集合对象,该集合必须是线程安全的,不能两个线程拿到统一连接
该集合还必须实现队列的特性:先进先出
Mybatis连接池提供了三种方式的配置:
配置的位置:主配置文件zpcad.xml中的dataSource标签,type属性就是表示才哟个何种连接池方式。
type属性的取值:POOLED,UNPOOLED,JNDI
POOLED:采用传统的javax.sql.DataSource规范中的连接池, mybatis中有针对规范的实现
UNPOOLED:采用传统的获取连接方式,虽然也实现Javax.sql.DataScource接口,但是并没有使用池的思想
JNDI:采用服务器提供的JNDI技术实现,来获取DataSource对象,不同服务器所能拿到的DataSource是不一样的。 同时:如果不是web或者maven的war工程,是不能使用的。
我现在所用的是tomcat服务器,采用连接池就是dbcp连接池。
没有那个过程(从池里拿出来,又扔回去)。也就是说,unpooled每次都会创建一个新的连接.再原有代码上稍作修改type=“UNPOOLED”
每次使用unpooled的时候,都会注册驱动,获取连接,并且把连接返回回去
<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>
开发中就用这个!!!
从池里拿出来,又扔回去。也就是说,它是从池中获取一个连接来用type=“POOLED”
<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>
有关于mybatis中的事务的几个问题见—我的笔记M11
什么是事务:它是通过sqlsession对象的commit方法和rollback方法实现事务的提交和回滚
自动提交设置:
注:只有执行一个对数据库的crud操作,才可以用这个。在转战操作中,如果每个连接处于独立的自动提交中,事务控制不住
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
在ZDao.java中添加
/**
* 根据传入参数条件查询
* @param userif 查询的条件,有可能是用户名,有可能是性别,有可能是地址,还有可能都有,也有可能都没有
* @return
*/
List<user> findUserByCondition(user userif);
注:如果条件有好几个,用and关联起来,不能用&& if test="username != NULL"后面加and再跟条件
这块的parameterType="user"也可以大写,因为之前已经设定不区分大小写
在ZDao.xml中
<!--根据条件查询-->
<select id="findUserByCondition" resultMap="uuserMap" parameterType="user">
select * from user where 1=1
<if test="username != NULL">
and username=#{username}
</if>
</select>
在MybatisTest.java中
/**
* 测试查询所有
*/
@Test
public void testFindByCondition() {
user u=new user();
u.setUsername("老王"); //查询老王的
//执行查询所有方法
List<user> users=userDao.findUserByCondition(u);
for(user us:users){
System.out.println(us);
}
}
即条件过多时
在配置文件中,使用
<select id="findUserByCondition" resultMap="uuserMap" parameterType="user">
select * from user where
<where>
<if test="username != NULL">
and username=#{username}
</if>
<if test="sex!=NULL">
and sexnew=#{sex}
</if>
</where>
</select>
在MybatisTest.java中
public void testFindByCondition() {
user u=new user();
u.setUsername("老王");//查询老王的
u.setSex("女"); //查询女
//执行查询所有方法
List<user> users=userDao.findUserByCondition(u);
for(user us:users){
System.out.println(us);
}
}
在QueryVo.java中添加,并弄出其的Getter and Setter方法
private List<Integer> ids;
随后加一个新的方法,肯定还在ZDao.java中 //根据QueryVo中提供的id集合查询用户信息
List<user> findUserInIds(QueryVo vo);
书写配置文件:
foreach标签用于遍历集合,他的属性:
collection:代表要遍历的集合元素
open:代表语句的开始部分
close:代表语句的结束部分
item:代表遍历集合的每个元素生成的变量名
separator:代表分隔符
<!--根据queryvo中的id集合实现查询用户列表-->
<select id="findUserInIds" resultMap="userMap" parameterType="queryvo">
select * from user
<where>
<if test="ids != null and ids.size()>0">
<foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
#{uid} //#后面写什么是由item决定
</foreach>
</if>
</where>
</select>
//其内foreach标签的意思:遍历ids这个集合,每一项加上and id in (和),把遍历出来的每一个放在()之间,并用,将其分割。
在MybatisTest.java中
public void testFindInIds(){
QueryVo vo=new QueryVo();
List<Integer> list=new ArrayList<Integer>();
list.add(41);
list.add(42);
list.add(77); //查询id为41,42,77的
vo.setIds(list);
//执行查询所有方法
List<user> us=userDao.findUserInIds(vo);
for(user usw:us){
System.out.println(usw);
}
}
这样即可运行成功
注:如果在配置文件中,有着大量的重复sql语句,那么就可以
<sql id="defaultUser">
select * from user
</sql>
其它需要这个的可直接引用,如:
<select id="findAll" resultType="com.zpc.user">
<include refid="defaultUser"></include>
<!--select * from user-->
</select>
一对一
一对多
多对多
多对一
mybatis 中的多表查询:
示例:用户和账户 一个用户可以有多个账户,一个账户只能被一个用户拥有
步骤:1:建立两张表,用户表和账户表
让用户表和账户表具有一对多的关系,需要使用外键在账户表中添加
2:建立两个实体类,用户实体类和账户实体类
让用户和账户实体类能体现出来一对多的关系
3:建立两个配置文件
用户的配置文件和账户的配置文件
4:实现配置
当我们查询用户时,同时得到用户下所包含的账户信息
当我们查询账户时,同时得到账户所对应的用户信息
创建一个类Account,其内的定义都是第二个数据库中的,且Getter and Setter和toString()方法
package com.zpc;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
创建一个IAccountDao接口
package com.zpc.Dao;
import com.zpc.Account;
import java.util.List;
public interface IAccountDao {
/**
* 查询所有用户
* @return
*/
List<Account> findAll();
}
再创建一个IAccountDao.xml,注:resultType=“account” select * from account都是定义的那个类,不过没分大小写
<?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.zpc.Dao.IAccountDao">
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="account">
select * from account
</select>
</mapper>
当然了,还需要定义一个测试类AccountTest
//这是该类中其余的
public class AccountTest {
private InputStream in;
private SqlSession sqlSession;
private IAccountDao accountDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
accountDao=sqlSession.getMapper(IAccountDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
@Test
public void testFindAll(){
List<Account> accounts=accountDao.findAll();
for(Account a:accounts){
System.out.println(a);
}
}
这玩意不常用
预要查询两个表中的东西,即这个表中的这一类,和另一个表中的这一类。首先,关注一下sql语句 给他们起个别名,account为a,user为u,且让u.id=a.uid。注:id和uid其实是一个意思,不过分属不同表
a.*,u.username,u.address为a所属的不用变,给u的那两个起别名
a.*:意思是,查询结果只会出现a表中的
也就是查询结果包含a内的三个类,u内的那两个类,如下一个查询结果:
Account{id=1, uid=46, money=1000.0} AccountUser{username=“老王”, address=“北京”}
他的意思就是在通过Account查出来那三个,通过AccountUser查出来那两个
select a.*,u.username,u.address from account a , user u where u.id=a.uid;
在IAccountDao.java中新加一个方法,用以实现 查询所有账户,并且带有账户名称和地址信息:
/**
* 查询所有账户,并且带有账户名称和地址信息
* @return
*/
List<AccountUser> findAllAccount();
单凭上一次建立的那个Account类,完全不够,因为那个类只能查询那一个表中的东西,而现在是两个表,故而,需建立一个继承Account的类AccountUser,这样既可以将那个表中的信息筛选出来,还可以在该类中定义一些内容,来筛选这一个表,以此来筛选出来所有
并在该类中,声明两个String对象,添加其Getter and Setter和toString()方法
注意:该类继承自Account,所以toString()结果需包含Account类中的toString()结果,故而在该类的toString中添加super.toString()+,此用来调用父类的toString() ,这样他就可以将Account的属性也给执行,从而得到我们所有想要的信息。空格(可以将两个表中查到的结果给中间加几个空格) 下面的是其内的toString()方法
package com.zpc;
public class AccountUser extends Account{
private String username;
private String address;
@Override
public String toString() {
return super.toString()+ " AccountUser{" +
"username='" + username + '\'' +
", address='" + address + '\'' +
'}';
}
接下来在IAccountDao.xml对其配置
<!--查询所有账户同时包含用户名和地址信息-->
<select id="findAllAccount" resultType="accountuser">
select a.*,u.username,u.address from account a , user u where u.id=a.uid;
</select>
最后,在测试类AccountTest.java中测事是否成功
@Test
public void testFindAllAccountUser(){
List<AccountUser> accounts=accountDao.findAllAccount();
for(AccountUser a:accounts){
System.out.println(a);
}
}
从账户获取到用户的信息。一对一----------配置文件中的映射配置是
这玩意常用,直接将其封装进去的意思,,,这是返回account表中的东西,进而返回user中对应的东西,或者说是返回两个表中共同的东西,不过还是第一中种说法靠谱
type是他的类型,应该是account类型
在Account.java中,添加这个,并添加其Getter and Setter
//从表实体应该包含的主表实体的对象引用
private user users;
在配置文件中IAccountDao.xml:
resultMap id=“accountUserMap” type=“account” 。定义一个accountUserMap,且是account类型。定义后,就可在下面使用,如下第二个代码。
property:属性。column:哪个字段获取的。
id property=“id” column=“aid” :实体类中名为id,数据库表中名为aid,二者相对应,下同
result property=“uid” column=“uid”
result property=“money” column=“money” 是因为a.id as aid,a.uid.a.money。id有别名aid,而其他两个和原来一样
property=“user” column=“uid” javaType=“user” 。通过uid来进入user获取东西,两个表靠id(uid)联系。javaType用于提示封装到哪个对象,因为使用了别名,故而可以直接user。不然zom.zpc…user
<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--account的数据封装已完成-->
<!--一对一的关系映射,配置user内容-->
<association property="user" column="uid" javaType="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
</association>
</resultMap>
且继续使用那个查询所有的,不过需要对其修改
a.id as aid,a.uid.a.money。id有别名aid,而其他两个的和原来一样
resultMap=“accountUserMap”。accountUserMap是前面定义的,故而使用resultMap,来弄向accountUserMap
这个sql语句是内连接 where
<select id="findAll" resultMap="accountUserMap">
select u.*,a.id as aid,a.uid.a.money from account a , user u where u.id=a.uid;
</select>
在测试类AccountTest.java中
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<Account> accounts=accountDao.findAll();
for(Account a:accounts){
System.out.println("---每个account的信息---");
System.out.println(a);
System.out.println(a.getUsers());
}
}
这样,即可完成。
执行后的一个结果
Account{id=1, uid=46, money=1000.0} AccountUser{username=“老王”, address=“北京”}
一对多----------配置文件中的映射是
从用户获取到账户的信息,,,即返回user表中的东西,进而获取到Account表中对应的所有东西,故而定义user的userMap
在IAccountDao.java中
/**
* 查询所有用户,同时希望获取到用户下所有账户的信息
* @return
*/
List<Account> findAll();
在user.java中,创建 accounts,并构建其的Getter and Setter
//一对多关系映射,主表实体应包含从表实体的关系引用
private List<Account> accounts;
//其方法可以获取本表所对应的那个表的信息,在这里也就是账户,这玩意我是这样理解的,不过还真有点这方面的意思。你看啊,findAll();获得用户的信息。再加上这个List users=userDao.findAll();
//for(user u:users){
// System.out.println("---每个用户的信息---");
// System.out.println(u);
//System.out.println(u.getAccounts());
//刚好也可以和输出结果对的上
//不过,这玩意我也不知道对不对,暂时就这样理解
将AccountTest.xml复制黏贴至UserTest.xml,同时在里面添加配置文件,并稍作更改
System.out.println(u.getAccounts());:最后一行,都是输出所映射的表的信息
package com.zpc.test;
import com.zpc.Account;
import com.zpc.AccountUser;
import com.zpc.Dao.IAccountDao;
import com.zpc.Dao.ZDao;
import com.zpc.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 UserTest {
private InputStream in;
private SqlSession sqlSession;
private ZDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(ZDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<user> users=userDao.findAll();
for(user u:users){
System.out.println("---每个用户的信息---");
System.out.println(u);
System.out.println(u.getAccounts());
}
}
}
定义user的userMap,在ZDao.xml
ofType指的是集合中元素的类型
property=“aid” column=“id” :为啥先是aid后是id?因为这个和上个第四章那个刚好相反,这个是有user表来引出account表 也就是说:现在的实体类是对user表的,所以实体类中名为aid,表中名为id 注:这是别名,上面有定义
property=“id” column=“id” :在实体类中的id,在表中的名字是id,二者相对应,当然名字可不同
:映射于accout表,命名accouts
<!--定义user的userMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!--配置user对象中的accounts集合的映射-->
<collection property="accounts" ofType="account">
<id property="aid" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
</collection>
</resultMap>
并更改sql语句
user u:user别名为u。account a:别名为a。
left outer join:左外连接,返回左边所有数据,也就是u的所有数据
on u.id=a.id:条件是 u.id=a.id
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="userAccountMap">
select * from user u left outer join account a on u.id=a.id
</select>
执行即可成
使用aoliignew项目
示例:用户和角色 一个用户可以有多个角色,一个角色可以有多个用户
步骤:1:建立两张表,用户表和角色表
让用户表和账户表具有多对多的关系,需要使用中间键,中间键包含各自的主键
2:建立两个实体类,用户实体类和角色实体类
让用户和账户实体类能体现出来多对多的关系
各自包含对方一个集合引用
3:建立两个配置文件
用户的配置文件和角色的配置文件
4:实现配置
当我们查询用户时,同时得到用户下所包含的角色信息
当我们查询角色时,同时得到角色所赋予的用户信息
ZDao.java
package com.zpc.Dao;
import com.zpc.user;
import java.util.List;
public interface ZDao {
/**
* 查询所有操作
* @return
*/
// @Select("select * from user")
List<user> findAll();
/**
* 根据id查询
* @param userId
* @return
*/
user findById(Integer userId);
}
user.java
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "user{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
ZDao.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.zpc.Dao.ZDao">
<!--定义user的userMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
</resultMap>
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="userAccountMap">
select * from user
</select>
<!--根据id查询用户-->
<select id="findById" parameterType="TNT" resultType="com.zpc.user">
select * from user where id=#{uid}
</select>
</mapper>
jdbcConfig.properties
loglj.properties
zpcad.xml
这三个玩意就没变
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis
jdbc.username=root
jdbc.password=123456
# 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{IS08601} %-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{IS08601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
<?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">
<!--mybatis的主配置文件-->
<configuration>
<!--配置properties
可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件信息
resource:
用于指定配置文件的位置,是按照类路径的写法来写,且必须存在于类路经下
url属性:是按照url的写法来写地址
统一资源定位符,他是唯一标识一个资源的位置
其写法:http://zoda:8080/mybatis/demol
协议 主机 端口 uri
uri:统一资源标识符,他是在应用中可以唯一定位一个资源的
-->
<properties url="file:///D:/ideagongcheng/aoliig/src/main/resources">
<!--<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>-->
</properties>
<!--使用typeAliases配置别名,他只能配置domain中类的别名-->
<typeAliases>
<!--typeAlias用于配置别名,type属性指定的是实体类全限定类名,alias属性指定别名,当指定了别名就不再区分大小写-->
<!--<typeAlias type="com.zpc.user" alias="User"></typeAlias>-->
<package name="com.zpc"></package>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境,上下二者必须相同(myaql)-->
<environment id="mysql">
<!--配置事务类型(JDBC)-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)(POOLED)-->
<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>
<!--指定映射配置文件的位置(resource),映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<package name="com.zpc.Dao"/>
</mappers>
</configuration>
UserTest.java
package com.zpc.test;
import com.zpc.Dao.ZDao;
import com.zpc.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 UserTest {
private InputStream in;
private SqlSession sqlSession;
private ZDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(ZDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<user> users=userDao.findAll();
for(user u:users){
System.out.println("---每个用户的信息---");
System.out.println(u);
}
}
}
首先创建一个实体类Role.java,并弄出Getter and Setter和toString()
package com.zpc;
import java.io.Serializable;
public class Role implements Serializable {
private Integer roleId;
private String roleName;
private String roleDesc;
实体类有了,接下来创建dao接口 IRoleDao
package com.zpc.Dao;
import com.zpc.Role;
import java.util.List;
public interface IRoleDao {
/**
* 查询所有角色
* @return
*/
List<Role> findAll();
}
写完这个后,还需要准备一个xml文件 IRoleDao.xml的映射配置
由这个配置便可知道,这玩意现在只查role这一个表
property=“roleName” column=“role_name”: 实体类中定义的为roleName,数据库表中的是role_name;
property=“roleId” column=“rid” 因为其被sql语句重命名,故而不用id,用rid,sql语句在下一节
<?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.zpc.Dao.IRoleDao">
<resultMap id="roleMap" type="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</resultMap>
<select id="findAll" resultMap="roleMap">
select * from role;
</select>
</mapper>
弄一个RoleTest.java,来测试(测试都在test的那个java下)
package com.zpc.test;
import com.zpc.Dao.IRoleDao;
import com.zpc.Dao.ZDao;
import com.zpc.Role;
import com.zpc.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 RoleTest {
private InputStream in;
private SqlSession sqlSession;
private IRoleDao roleDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
roleDao=sqlSession.getMapper(IRoleDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<Role> roles=roleDao.findAll();
for(Role role:roles){
System.out.println("---每个角色的信息---");
System.out.println(role);
}
}
}
这是数据库的那两张表:第一张,角色表role
ID ROLE_NAME ROLE_DESC
1 院长 管理整个学院
2 总裁 管理整个公司
3 校长 管理整个学校
第二张,中间表
UID RID
41 1
45 1
41 1
中间表意思是,由角色的只有41和45
执行结果其一:
—每个角色的信息—
Role{roleId=1, roleName=‘院长’,roleDesc=‘管理整个学院’}
当然,这只是查询角色得到了角色的信息,还需要下一步
在Role.java中,添加多对多的关系映射,一个角色可以赋予多个用户,并弄出其Getter and Setter方法
/**
* 多对多的关系映射,一个角色可以赋予多个用户
*/
private List<user> users;
接下来研究sql语句,看如何获得想要的
role r:role表的别名r
left outer join:左外连接,返回左边所有数据,也就是r表的所有数据
user_role ur:user_role是两个表合起来的,的别名是ur
on r.id=ur.id:条件是r.id=ur.id
left outer join user u on u.id=ur.uid:获取上面那些步骤后的所有表,且加一个条件,进行再次筛选,u.id=ur.uid
u.*:是结果中只需要包含u表中有的
r.id as rid,r.role_name,r.role_desc:是给r.id取别名rid,其余两个不变
小细节注:当sql语句过长时,注下面几行用一个空格,这样拼接起来后,就不会出错
u.id=ur.uid:u中的id等于u,r和集中u的id(uid)
select u.*,r.id as rid,r.role_name,r.role_desc from role r
left outer join user_role ur on r.id=ur.id
left outer join user u on u.id=ur.uid
将配置IRoleDao.xml中的其内sql语句替换,且添加映射
<mapper namespace="com.zpc.Dao.IRoleDao">
<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" ofType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="roleMap">
select u.*,r.id as rid,r.role_name,r.role_desc from role r
left outer join user_role ur on r.id=ur.id
left outer join user u on u.id=ur.uid
</select>
</mapper>
在测试类RoleTest,java中,添加System.out.println(role.getUsers());
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<Role> roles=roleDao.findAll();
for(Role role:roles){
System.out.println("---每个角色的信息---");
System.out.println(role);
System.out.println(role.getUsers());
}
}
接下来就会得到想要的信息
其中之一:
—每个角色的信息—
Role{roleId=1, roleName=‘院长’,roleDesc=‘管理整个学院’}
[User{id=41,username=‘老王’,address=‘北京’,sex=‘男’,birthday=Tue Fed 27 17:47:08 CST 2018}]
从用户到角色,故一切主要的都在user所属进行操作
sql语句改变
select u.*,r.id as rid,r.role_name,r.role_desc from user u
left outer join user_role ur on u.id=ur.uid
left outer join role r on r.id=ur.rid
在user.java中,添加多对多的关系映射,一个用户可以具备多个角色,并弄出Getter and Setter
/**
* 多对多的关系映射,一个用户可以具备多个角色
*/
private List<Role> roles;
在ZDao.xml中,也就是在user所对应建立的那个中.更改
<!--定义user的userMap-->
<resultMap id="userMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!--配置角色集合的映射-->
<collection property="roles" ofType="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</collection>
</resultMap>
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="userMap">
select u.*,r.id as rid,r.role_name,r.role_desc from user u
left outer join user_role ur on u.id=ur.uid
left outer join role r on r.id=ur.rid
</select>
最后,在UserTest.java中,添加测试(更改)
System.out.println(u.getRoles()); 这最后一行都是输出映射的表的
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<user> users=userDao.findAll();
for(user u:users){
System.out.println("---每个用户的信息---");
System.out.println(u);
System.out.println(u.getRoles());
}
}
完成!
这玩意了解了解就行
JNDI其目的:模仿Windows系统中的注册表
tomcat一启动:
key:是一个字符串 dicectory是固定的,name是可以自己指定的
value:是一个object 要存放什么对象是可以指定的,指定的方式是通过配置文件的方式
还是创建maven的开始步骤,只不过需勾上那个Greate from archetype,选择里面的org.apache.maven.archetypes:maven-erchetype-webapp
创建好以后,在src下创建一个tset(右键点Directory),再在main下创建java,继续在main下创建resources,在test下创建java。
右键src下的java,选择Mak Directory as下的Sources Root让其真正的成为我们的源码。继续在src下的resources,右键选择Mak Directory as下的Resources Root,让其真正意义上的成为resource。右键test下的Java,选择Mak Directory as下的Test Sources Root。
接下来将上一个工程的main下的java和resources和test下的复制。在复制pom.xml的内容(不要那个打包),同时还需再在pom.xml中导入servlet-api和jsp-api依赖
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
</dependency>
注:就算其闪红,继续导入即可
在webapp下新建一文件夹META-INF,后在META-INF下创建context.xml文件
name=“jdbc/eesy_mybatis”。上面已经说过,其可自己定义
Container:容器的意思。
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<!--
<Resource
name="jdbc/eesy_mybatis" 数据源的名称
type="javax.sql.DataSource" 数据源类型
auth="Container" 数据源提供者
maxActive="20" 最大活动数
maxWait="10000" 最大等待时间
maxIdle="5" 最大空闲时
username="root" 用户名
password="123456" 密码
driverClassName="com.mysql.jdbc.Driver" 驱动类
url="jdbc:mysql://localhost:3306/eesy_mybatis" 连接url字符串
/>
-->
<Resource
name="jdbc/eesy_mybatis"
type="javax.sql.DataSource"
auth="Container"
maxActive="20"
maxWait="10000"
maxIdle="5"
username="root"
password="123456"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/eesy_mybatis"
/>
</Context>
接下来将zpcad.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>
<typeAliases>
<package name="com.zpc"></package>
</typeAliases>
<!--配置mybatis环境-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--配置事务控制方式-->
<transactionManager type="JDBC"></transactionManager>
<!--配置连接数据库的必备信息 type属性表示是否使用数据源(连接池)-->
<dataSource type="JNDI">
<property name="data_source" value="java:comp/env/jdbc/eesy_mybatis"/>
</dataSource>
</environment>
</environments>
<!--指定mapper配置文件的位置-->
<mappers>
<mapper resource="com/itheima/dao/IUserDao.xml"/>
</mappers>
</configuration>
name=“data_source” :指定一个名字
value=“java:comp/env/jdbc/eesy_mybatis” :jdbc/eesy_mybatis这玩意是在配置文件中定义的路径。java:comp/env :这是固定的。
接下来把应用部署到服务器tomcat
问题:在一对多中,当我们有一个用户,他有一百个账户
在查询用户时,用户下的账户信息应该是,什么时候用,什么时候查询。
在查询账户时,账户的所属用户信息应该是随着账户查询的时候一起查询出来。
什么时延迟加载:在真正使用数据时才发起查询,不用的时候不查询。按需加载(懒加载)
什么时立即加载:不管用不用,只要一调用方法,马上发起查询
在对应的四种表关系中:一对多,多对一,一对一,多对多
一对多,多对多:通常使用延迟加载
多对一,一对一:通常使用延迟加载
就是在一对一查询上稍作更改
IAccountDao.xml中
sql语句首先应改为:select * from account
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultMap="accountUserMap">
select * from account
</select>
这个中的aid也改成id,因为sql语句已经变化,不再有其别名
同时删除其内映射
<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--account的数据封装已完成-->
</resultMap>
接下来开始配置延迟加载
<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--account的数据封装已完成-->
<!--一对一关系映射,配置封装user的内容
select属性指定的:查询用户的唯一标识
column属性指定的:用户根据id查询时,所需要的参数的值,uid:是根据账户的uid查的
-->
<association property="user" column="uid" javaType="user" select="com.zpc.Dao.ZDao.findById">
</association>
</resultMap>
property=“user” column=“uid” javaType=“user” select="com.zpc.Dao.ZDao.findById"就将用户的信息给提供过来
com.zpc.Dao.ZDao.findById:是在user所对应的xml文件ZDao.xml中的那个mapper namespace="com.zpc.Dao.ZDao"后面的,以及其内的select id=“findById”,也就是根据id查询的那个方法。
接下来将其弄得延迟,在zpcad.xml中,添加:
<!--配置延迟加载参数-->
<settings>
<!--开启延迟-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--允许触发方法进行立即加载-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
注:其要位于下
properties resource="jdbcConfig.properties">
</properties>
一对多是根据用户查账户
在ZDao.xml中
更改sql语句:
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="userAccountMap">
select * from user
</select>
更改连接映射:
<!--定义user的userMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!--配置user对象中的accounts集合的映射-->
<collection property="accouts" ofType="accout" select="com.apc.Dao.IAccountDao.findaccountByUid" column="id"></collection>
</resultMap>
collection中column=“id”:是根据用户的id去查,也就是上面的resultMap中的。
在IAccountDao.java中添加:
/**
* 根据用户id查账户信息
* @param uid
* @return
*/
List<Account> findaccountByUid(Integer uid);
在IAccountDao.xml添加:
<!--根据id查-->
<select id="findaccountByUid" resultType="account">
select * from account where uid=#{uid}
</select>
什么是缓存:存在于内存中的临时数据。
为什么使用缓存:减少和数据库的交互次数,提高执行效率。
什么样的数据可以使用缓存:经常查询且不经常改变的;数据的正确与否对最终结果影响不大的
不适用于缓存:经常改变的数据;数据的正确与否对最终结果影响很大的;如:银行的汇率,商品的库存
一级缓存:它指的是Mybatis中的SqlSession对象的缓存
当我们执行查询之后,查询的结果会同时存入到SqlSession为我们提供一块区域中。该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有的话直接拿出来用。
当sqlsession对象消失时,mybatis的一级缓存也就消失了。
直接在UserTest.java中添加
/**
* 测试一级缓存
*/
@Test
public void testFirstLeveCache(){
user user1=userDao.findById(41);
System.out.println(user1);
user user2=userDao.findById(41);
System.out.println(user2);
System.out.println(user1==user2);
}
运行后,就可以看出来,上面使用了sqlsession,故而其本身就是一级缓存
假如其清空缓存,这样就会两次查询,而且最后输出来的就是false,如:
/**
* 测试一级缓存
*/
@Test
public void testFirstLeveCache(){
user user1=userDao.findById(41);
System.out.println(user1);
sqlSession.clearCache();//清空缓存
userDao=sqlSession.getMapper(ZDao.class);
user user2=userDao.findById(41);
System.out.println(user2);
System.out.println(user1==user2);
}
一级缓存:当调用sqlSession的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存.
如果数据库中的文件和一级缓存不一致了
在ZDao.java中添加:
/**
* 更新用户信息
* @param userhuan
*/
void updateUser(user userhuan);
再书写其配置文件ZDao.xml
<!--更新用户信息-->
<update id="updateUser" parameterType="user">
update user set username=#{username},address=#{address} where id=#{id}
</update>
在UserTest.java中
/**
* 测试缓存同步
*/
@Test
public void testClearlCache(){
//根据id查询用户
user user1=userDao.findById(41);
System.out.println(user1);
//更新用户信息
user1.setUsername("ao li gei");
user1.setAddress("西安市");
userDao.updateUser(user1);
//再次查询id为41
user user2=userDao.findById(41);
System.out.println(user2);
System.out.println(user1==user2);
}
运行后即可发现,更新后,是重新发起了一次新的查询
它指的是Mybatis中的SqlSessionFavtory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享其缓存。
二级缓存使用的三个步骤:
第一:让Mybatis框架支持二级缓存(在zpcad.xml中配配置)
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
第二:让当前的映射文件支持二级缓存(在ZDao.xml中配置)
<!--开启user支持二级缓存-->
<cache/>
第三:让当前的操作支持二级缓存(在ZDao.xml中的select标签中配置)
useCache=“true”
<!--根据id查询用户-->
<select id="findById" parameterType="TNT" resultType="com.zpc.user" useCache="true">
select * from user where id=#{uid}
</select>
创建一个新的测试类SecondLevelCacheTest.java,并对其进行配置
/**
* 测试二级缓存
*/
@Test
public void testFirstLeveCache(){
SqlSession sqlSession1=factary.openSession();
ZDao dao1=sqlSession1.getMapper(ZDao.class);
user user1=dao1.findById(41);
System.out.println(user1);
sqlSession1.close();//一级缓存消失
SqlSession sqlSession2=factary.openSession();
ZDao dao2=sqlSession2.getMapper(ZDao.class);
user user2=dao2.findById(41);
System.out.println(user2);
System.out.println(user1==user2);
}
注:输出的内容时false。因为在二级缓存中,存放的东西时数据,而不是对象。
因为在调用其内的数据时,是重新创建一个对象来调用。故而不同
主要就是没了那个IUserDao.xml的配置文件,在IUserDao.java中添加了注解,更加方便。且,注解和xml不能同时存在。
首先创建一个工程,并对pom.xml进行配置添加
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
再在main,java下创建一个class,User.java
写入这个,并弄出其Getter and Setter和toString()方法
package com.zpc.domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
再创建一个dao接口IUserDao.java
package com.zpc.dao;
import com.zpc.domain.User;
import java.util.List;
public interface IUserDao {
/**
* 查询所有用户
* @return
*/
List<User> findAll();
}
先在resources导入jdbcConfig.properties和loglj.properties,这个代码下面有
再在resources创建主配置文件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.zpc.dao"/>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境,上下二者必须相同(myaql)-->
<environment id="mysql">
<!--配置事务类型(JDBC)-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)(POOLED)-->
<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.zpc.domain"></package>
</mappers>
</configuration>
接下来开始写注解在IUserDao.java中,只需添加一行:
注:其本来是@Select(value = “select * from user”);但由于只有一个value,故而可以省略。 在其内只需加入sql语句就行。
注:在mybatis中针对CRUD一共有四个注解:@Select @Insert @Update @Delete
/**
* 查询所有用户
* @return
*/
@Select("select * from user")
List<User> findAll();
弄一个测试类:MybatisAnnoTest.java
public class MybatisAnnoTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void TestfindAll(){
//5:使用代理对象执行方法
List<User> users= userDao.findAll();
for(User usernew:users){
System.out.println(usernew);
}
}
}
即可测出来和以前并没有差别
保存@insert:在IUserDao.java中
/**
* 保存用户
* @param user
*/
@Insert("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
void savaUser(User user);
新建一个测试类AnnotationCRUDTest.java,这样就可以将其下那两个数据输入进库
package com.zpc;
import com.zpc.dao.IUserDao;
import com.zpc.domain.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 AnnotationCRUDTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
@Test
public void testSave(){
User user=new User();
user.setUsername("ao li gei le");
user.setAddress("西安市");
userDao.savaUser(user);
}
}
更新(修改)用户:@Update
在IUserDao.java中添加
/**
* 更新用户
* @param user
*/
@Update("update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address},where id=#{id}")
void updateUser(User user);
在测试类AnnotationCRUDTest.java中:
@Test
public void testUpdate(){
User user=new User();
user.setId(321);
user.setUsername("ao li gei le ha");
user.setAddress("西安市c");
user.setBirthday(new Date());
userDao.updateUser(user);
}
删除用户@Delete
在IUserDao.java中:
/**
* 删除用户
* @param userId
*/
@Delete("delete from user where id=#{id}")
void deleteUser(Integer userId);
在测试类AnnotationCRUDTest.java中:
/**
* 删除用户
*/
@Test
public void testDelete(){
userDao.deleteUser(32);
}
查询用户,@Select
在IUserDao.java中:
/**
* 根据id查询
* @param userId
* @return
*/
@Select("select * from user where id=#{id}")
User findById(Integer userId);
在测试类AnnotationCRUDTest.java中:
/**
* 查询用户
*/
@Test
public void testFindOne(){
User user=userDao.findById(32);
System.out.println(user);
}
模糊查询(名字)@Select
在IUserDao.java中:
/**
* 模糊查询
* @param username
* @return
*/
@Select("select * from user where username like #{username}")
List<User> findUserByName(String username);
在测试类AnnotationCRUDTest.java中:
/**
* 模糊查询
*/
public void testFindByName(){
List<User> users=userDao.findUserByName("%王%");
for(User user : users){
System.out.println(user);
}
}
同时,模糊查询还有另一种方式:
在IUserDao.java中:
/**
* 模糊查询
* @param username
* @return
*/
@Select("select * from user where username like '%${value}%')
List<User> findUserByName(String username);
同时,他在测试文件中,也会改变:将不用写%
/**
* 模糊查询
*/
public void testFindByName(){
List<User> users=userDao.findUserByName("王");
for(User user : users){
System.out.println(user);
}
}
查询总用户数量,在IUserDao.java中:
/**
* 查询总用户数量
* @return
*/
@Select("select count(*) from user")
int findTotalUser();
在测试类AnnotationCRUDTest.java中:
/**
* 查询所有用户总量
*/
public void testFindTotal(){
int t=userDao.findTotalUser();
System.out.println(t);
}
如将User.java中的那些个定义的东西,换成和数据表中不一样的分类,又不想一条一条的给别名,该如何解决?
如,使用@Results
在User.java中改变,并Getter and Setter和toString()方法:
public class User implements Serializable {
private Integer userId;
private String usernName;
private String userAddress;
private String userSex;
private Date userBirthday;
现在已经更改,要想其中的一个方法不收影响,在IUserDao.java中那个方法上添加,如:
/**
* 查询所有用户
* @return
*/
@Select("select * from user")
@Results(value = {
@Result(id=true,column="id",property="userId"),
@Result(id=true,column="username",property="userName"),
@Result(id=true,column="address",property="userAddress"),
@Result(id=true,column="sex",property="userSex"),
@Result(id=true,column="birthday",property="userBirthday"),
})
List<User> findAll();
在测试类AnnotationCRUDTest.java中:
/**
* 查询所有用户
*/
@Test
public void testFindAll() {
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
运行后,即可依然查询出来!且出来的是用自己所定义的那些表示的。
但是,当别的方法需要时,一次写一个太过于繁琐,故而,可以在@Results那块添加一个id,自己给其一个值,其余方法可直接使用@Results调用该id即可。如:
/**
* 查询所有用户
* @return
*/
@Select("select * from user")
@Results(id="userMap",value = {
@Result(id=true,column="id",property="userId"),
@Result(id=true,column="username",property="userName"),
@Result(id=true,column="address",property="userAddress"),
@Result(id=true,column="sex",property="userSex"),
@Result(id=true,column="birthday",property="userBirthday"),
})
List<User> findAll();
调用:注,要是@Result Map那里面只要一个元素,那其也可以写成:@ResultMap(“userMap”)
/**
* 根据id查询
* @param userId
* @return
*/
@Select("select * from user where id=#{id}")
@ResultMap(value={"userMap"})
User findById(Integer userId);
再创建一实体类Account.java,并Getter and Setter和toString()方法:
package com.zpc.domain;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
在Account.java中再弄一个user,并Getter and Setter
//多对一(mybatis中称为一对一)的映射:一个账户只能属于一个用户
private User user;
接下来,再写一dao,IAccountDao.java
property = “user”:要连接的是User的,这玩意在上面定义了,所以user
column = “uid”:是用uid这个字段去查用户的信息
select =“com.zpc.dao.IUserDao.findById”:指向实现功能的那个方法,一般都在对应的那个数据表定义的dao中
fetchType = FetchType.EAGER:这玩意是必须有的
public interface IAccountDao {
/**
* 查询所有账户,并且获取每个账户下所属的用户信息
* @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") , //account其本身的已经封装完成,接下来连接user
@Result(property = "user",column = "uid",one = @One(select ="com.zpc.dao.IUserDao.findById",fetchType = FetchType.EAGER))
})
List<Account> findAll();
}
创建测试类,AccountTest.java
public class AccountTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IAccountDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IAccountDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 查询所有用户
*/
@Test
public void testFindAll() {
List<Account> accounts = userDao.findAll();
for (Account account : accounts) {
System.out.println("---每个账户的信息---");
System.out.println(account);
System.out.println(account.getUser());
}
}
}
即可成功!
在User.java中添加:并Getter and Setter
//一对多关系映射,一个用户对应多个账户
private List<Account> accounts;
在IUserDao.java中完善配置:
property = “accounts”:要连接的是Account的,这玩意在上面定义了,所以accounts
column = “id”:根据id来查询账户
select = “com.zpc.dao.IAccountDao.findAccountByUid”:指向实现功能的那个方法,一般都在对应的那个数据表定义的dao中
/**
* 查询所有用户
* @return
*/
@Select("select * from user")
@Results(id="userMap",value = {
@Result(id=true,column="id",property="userId"),
@Result(id=true,column="username",property="userName"),
@Result(id=true,column="address",property="userAddress"),
@Result(id=true,column="sex",property="userSex"),
@Result(id=true,column="birthday",property="userBirthday"),
@Result(property = "accounts",column = "id",many = @Many(select = "com.zpc.dao.IAccountDao.findAccountByUid",fetchType = FetchType.LAZY))
})
List<User> findAll();
在IAccountDao.java中添加:
/**
* 根据用户id查询账户信息
* @param userId
* @return
*/
@Select("select * from account where uid=#{userId}")
List<Account> findAccountByUid(Integer userId);
再在测试类中:AnnotationCRUDTest.java更改
/**
* 查询所有用户
*/
@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());
}
}
在SqlMapConfig.xml中:让Mybatis框架支持二级缓存
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
在IUserDao.java中开启二级缓存的使用:@CacheNamespace(blocking = true)添加至头
package com.zpc.dao;
import com.zpc.domain.User;
import org.apache.ibatis.annotations.*;
import org.apache.ibatis.mapping.FetchType;
import java.util.List;
@CacheNamespace(blocking = true)
public interface IUserDao {
新创建一个测试类SecondLevelCatchTest.java
public class SecondLevelCatchTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
in.close();
}
/**
* 查询用户
*/
@Test
public void testFindOne(){
User user=userDao.findById(32);
System.out.println(user);
sqlSession.close();//释放一级缓存
SqlSession session2=factory.openSession();//再次打卡Session
IUserDao userDao1=session2.getMapper(IUserDao.class);
User user1=userDao.findById(32);
System.out.println(user1);
}
}
运行后即可看出其已经是二级缓存!
下一个项目中也许包含上一个项目中的内容
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KwK7qhR0-1588052911979)(C:\Users\16695\Pictures\Saved Pictures\aoliig.PNG)]
package com.zpc.Dao;
import com.zpc.QueryVo;
import com.zpc.user;
import org.apache.ibatis.annotations.Select;
import javax.management.Query;
import java.util.List;
public interface ZDao {
/**
* 查询所有操作
* @return
*/
// @Select("select * from user")
List<user> findAll();
/**
* 保存方法
* @param usernewf
*/
void saveUser(user usernewf);
/**
* 更新操作
* @param usernewf
*/
void updateUser(user usernewf);
/**
* 根据ID删除用户
* @param userId
*/
void deleteUser(Integer userId);
/**
* 根据id查询
* @param userId
* @return
*/
user findById(Integer userId);
/**
* 根据名字模糊查询
* @param username
* @return
*/
List<user> findByName(String username);
/**
* 查询总用户数
* @return
*/
int findTotal();
/**
* 根据QueryVo中的条件查询用户
* @param vo
* @return
*/
List<user> findUserByVo(QueryVo vo);
/**
* 根据传入参数条件查询
* @param userif 查询的条件,有可能是用户名,有可能是性别,有可能是地址,还有可能都有,也有可能都没有
* @return
*/
List<user> findUserByCondition(user userif);
/**
* 根据QueryVo中提供的id集合查询用户信息
* @param vo
* @return
*/
List<user> findUserInIds(QueryVo vo);
}
package com.zpc.mybatis.io;
//使用类加载器读取配置文件的类
import sun.security.util.Resources;
import java.io.InputStream;
public class Resource {
//根据传入的参数,获取一个字节输入流
public static InputStream getResourceAsStream(String filePath){
return Resources.class.getClassLoader().getResourceAsStream(filePath);
//获取字节码,获取类加载器,读取配置
}
}
package com.zpc.mybatis.sqlsession;
//自定义mybatis中和数据库交互的核心类,其里面可创建dao接口的代理对象
public interface SqlSession {
//根据参数创建一代理对象
<T> T getMapper(Class<T> daoInterfaceClass);
//释放资源
void close();
}
package com.zpc.mybatis.sqlsession;
public interface SqlSessionFactory {
//用于打开一个新的SqlSession对象
SqlSession openSession();
}
package com.zpc.mybatis.sqlsession;
//用于创建SqlSessionFactory对象
import java.io.InputStream;
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(InputStream config){
return null;
}
}
package com.zpc;
import java.util.List;
public class QueryVo {
private user uservo;
private List<Integer> ids;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
public user getUservo() {
return uservo;
}
public void setUservo(user uservo) {
this.uservo = uservo;
}
}
package com.zpc;
import java.io.Serializable;
import java.util.Date;
public class user implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
@Override
public String toString() {
return "user{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
<?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.zpc.Dao.ZDao">
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="com.zpc.user">
<include refid="defaultUser"></include>
<!--select * from user-->
</select>
<sql id="defaultUser">
select * from user
</sql>
<!--保存用户-->
<insert id="saveUser" parameterType="com.zpc.user">
<!--配置插入操作后,获取插入数据的id-->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user (username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
</insert>
<!--更新用户-->
<update id="updateUser" parameterType="com.zpc.user">
update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}
</update>
<!--删除用户-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{uid}
</delete>
<!--根据id查询用户-->
<select id="findById" parameterType="TNT" resultType="com.zpc.user">
select * from user where id=#{uid}
</select>
<!--根据名称模糊查询-->
<select id="findByName" parameterType="string" resultType="com.zpc.user">
select * from user where username like #{name}
</select>
<!--获取用户总记录条数-->
<select id="findTotal" resultType="int">
select count(id) from user;
</select>
<!--根据queryVo条件查询用户-->
<select id="findUserByVo" parameterType="com.zpc.QueryVo" resultType="com.zpc.user">
select * from user where username like #{uservo.username}
</select>
<!--根据条件查询-->
<select id="findUserByCondition" resultMap="uuserMap" parameterType="user">
select * from user where 1=1
<if test="username != NULL">
and username=#{username}
</if>
</select>
<select id="findUserByCondition" resultMap="uuserMap" parameterType="user">
select * from user where
<where>
<if test="username != NULL">
and username=#{username}
</if>
<if test="sex!=NULL">
and sexnew=#{sex}
</if>
</where>
</select>
<!--根据queryvo中的id集合实现查询用户列表-->
<select id="findUserInIds" resultMap="userMap" parameterType="queryvo">
select * from user
<where>
<if test="ids != null and ids.size()>0">
<foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
</mapper>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis
jdbc.username=root
jdbc.password=123456
# 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{IS08601} %-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{IS08601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
<?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">
<!--mybatis的主配置文件-->
<configuration>
<!--配置properties
可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件信息
resource:
用于指定配置文件的位置,是按照类路径的写法来写,且必须存在于类路经下
url属性:是按照url的写法来写地址
统一资源定位符,他是唯一标识一个资源的位置
其写法:http://zoda:8080/mybatis/demol
协议 主机 端口 uri
uri:统一资源标识符,他是在应用中可以唯一定位一个资源的
-->
<properties url="file:///D:/ideagongcheng/aoliig/src/main/resources">
<!--<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>-->
</properties>
<!--使用typeAliases配置别名,他只能配置domain中类的别名-->
<typeAliases>
<!--typeAlias用于配置别名,type属性指定的是实体类全限定类名,alias属性指定别名,当指定了别名就不再区分大小写-->
<!--<typeAlias type="com.zpc.user" alias="User"></typeAlias>-->
<package name="com.zpc"></package>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境,上下二者必须相同(myaql)-->
<environment id="mysql">
<!--配置事务类型(JDBC)-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)(POOLED)-->
<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>
<!--指定映射配置文件的位置(resource),映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<package name="com.zpc.Dao"/>
</mappers>
</configuration>
package com.zpc.test;
import com.zpc.Dao.ZDao;
import com.zpc.QueryVo;
import com.zpc.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.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
public class MybatisTest {
private InputStream in;
private SqlSession sqlSession;
private ZDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(ZDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void TestfindAll(){
//5:使用代理对象执行方法
List<user> users= userDao.findAll();
for(user usernew:users){
System.out.println(usernew);
}
}
/**
* 测试保存操作
*/
@Test
public void testSave(){
user usernew =new user();
usernew.setUsername("mybatis saveuser");
usernew.setAddress("北京市朝阳区");
usernew.setSex("男");
usernew.setBirthday(new Date());
//执行保存方法
userDao.saveUser(usernew);
// System.out.println(usernew);
}
/**
* 测试更新
*/
@Test
public void testUpdate(){
user usernew =new user();
usernew.setId(50);
usernew.setUsername("mybatis saveuser");
usernew.setAddress("北京市朝阳区");
usernew.setSex("女");
usernew.setBirthday(new Date());
//执行保存方法
userDao.saveUser(usernew);
}
/**
* 测试删除
*/
@Test
public void testDelete() {
//执行删除方法 删除id为48的
userDao.deleteUser(48);
}
/**
* 测试查找一个
*/
@Test
public void testFindOne() {
//执行删除方法 删除id为48的
user usernew=userDao.findById(50);
System.out.println(usernew);
}
/**
* 模糊查询
*/
@Test
public void testFindByName() {
//执行删除方法 删除id为48的
List<user> users=userDao.findByName("%王%");
for(user usersnew:users){
System.out.println(usersnew);
}
}
/**
* 测试查询总记录条数
*/
@Test
public void testFindTotal() {
//执行删除方法 删除id为48的
int count=userDao.findTotal();
System.out.println(count);
}
/**
* 测试使用QueryVo作为查询条件
*/
@Test
public void testFindByVo() {
//执行删除方法 删除id为48的
QueryVo vo=new QueryVo();
user userv=new user();
userv.setUsername("%王%");
vo.setUservo(userv); //setUservo方法位于QueryVo中
List<user> users=userDao.findUserByVo(vo);
for(user u:users){
System.out.println(u);
}
}
/**
* 测试查询所有
*/
@Test
public void testFindByCondition() {
user u=new user();
u.setUsername("老王");//查询老王的
u.setSex("女");
//执行查询所有方法
List<user> users=userDao.findUserByCondition(u);
for(user us:users){
System.out.println(us);
}
}
/**
* 使用foreach查询
*/
public void testFindInIds(){
QueryVo vo=new QueryVo();
List<Integer> list=new ArrayList<Integer>();
list.add(41);
list.add(42);
list.add(77);
vo.setIds(list);
//执行查询所有方法
List<user> us=userDao.findUserInIds(vo);
for(user usw:us){
System.out.println(usw);
}
}
}
<?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>org.example</groupId>
<artifactId>aoliig</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
</dependencies>
</project>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OrNSh9IF-1588052911984)(C:\Users\16695\Pictures\Saved Pictures\aoliigtow.PNG)]
package com.zpc.Dao;
import com.zpc.Account;
import com.zpc.AccountUser;
import java.util.List;
public interface IAccountDao {
/**
* 查询所有用户,同时希望获取到用户下所有账户的信息
* @return
*/
List<Account> findAll();
/**
* 查询所有账户,并且带有账户名称和地址信息
* @return
*/
List<AccountUser> findAllAccount();
}
package com.zpc.Dao;
import com.zpc.user;
import java.util.List;
public interface ZDao {
/**
* 查询所有操作
* @return
*/
// @Select("select * from user")
List<user> findAll();
/**
* 根据id查询
* @param userId
* @return
*/
user findById(Integer userId);
}
package com.zpc;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//从表实体应该包含的主表实体的对象引用
private user users;
public user getUsers() {
return users;
}
public void setUsers(user users) {
this.users = users;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer 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.zpc;
public class AccountUser extends Account{
private String username;
private String address;
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;
}
@Override
public String toString() {
return super.toString()+ " AccountUser{" +
"username='" + username + '\'' +
", address='" + address + '\'' +
'}';
}
}
package com.zpc;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class user implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//一对多关系映射,主表实体应包含从表实体的关系引用
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "user{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
<?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.zpc.Dao.IAccountDao">
<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--account的数据封装已完成-->
<!--一对一的关系映射,配置user内容-->
<association property="user" column="uid" javaType="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
</association>
</resultMap>
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultMap="accountUserMap">
select u.*,a.id as aid,a.uid.a.money from account a , user u where u.id=a.uid;
</select>
<!--查询所有账户同时包含用户名和地址信息-->
<select id="findAllAccount" resultType="accountuser">
select a.*,u.username,u.address from account a , user u where u.id=a.uid;
</select>
</mapper>
<?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.zpc.Dao.ZDao">
<!--定义user的userMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!--配置user对象中的accounts集合的映射-->
<collection property="accouts" ofType="accout">
<id property="aid" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
</collection>
</resultMap>
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="userAccountMap">
select * from user u left outer join account a on u.id=a.id
</select>
<!--根据id查询用户-->
<select id="findById" parameterType="TNT" resultType="com.zpc.user">
select * from user where id=#{uid}
</select>
</mapper>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis
jdbc.username=root
jdbc.password=123456
# 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{IS08601} %-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{IS08601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
<?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">
<!--mybatis的主配置文件-->
<configuration>
<!--配置properties
可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件信息
resource:
用于指定配置文件的位置,是按照类路径的写法来写,且必须存在于类路经下
url属性:是按照url的写法来写地址
统一资源定位符,他是唯一标识一个资源的位置
其写法:http://zoda:8080/mybatis/demol
协议 主机 端口 uri
uri:统一资源标识符,他是在应用中可以唯一定位一个资源的
-->
<properties url="file:///D:/ideagongcheng/aoliig/src/main/resources">
<!--<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>-->
</properties>
<!--使用typeAliases配置别名,他只能配置domain中类的别名-->
<typeAliases>
<!--typeAlias用于配置别名,type属性指定的是实体类全限定类名,alias属性指定别名,当指定了别名就不再区分大小写-->
<!--<typeAlias type="com.zpc.user" alias="User"></typeAlias>-->
<package name="com.zpc"></package>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境,上下二者必须相同(myaql)-->
<environment id="mysql">
<!--配置事务类型(JDBC)-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)(POOLED)-->
<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>
<!--指定映射配置文件的位置(resource),映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<package name="com.zpc.Dao"/>
</mappers>
</configuration>
package com.zpc.test;
import com.zpc.Account;
import com.zpc.AccountUser;
import com.zpc.Dao.IAccountDao;
import com.zpc.Dao.ZDao;
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 SqlSession sqlSession;
private IAccountDao accountDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
accountDao=sqlSession.getMapper(IAccountDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<Account> accounts=accountDao.findAll();
for(Account a:accounts){
System.out.println("---每个account的信息---");
System.out.println(a);
System.out.println(a.getUsers());
}
}
/**
* 测试查询查询所有账户,并且带有账户名称和地址信息
*/
@Test
public void testFindAllAccountUser(){
List<AccountUser> accounts=accountDao.findAllAccount();
for(AccountUser a:accounts){
System.out.println(a);
}
}
}
package com.zpc.test;
import com.zpc.Account;
import com.zpc.AccountUser;
import com.zpc.Dao.IAccountDao;
import com.zpc.Dao.ZDao;
import com.zpc.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 UserTest {
private InputStream in;
private SqlSession sqlSession;
private ZDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(ZDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<user> users=userDao.findAll();
for(user u:users){
System.out.println("---每个用户的信息---");
System.out.println(u);
System.out.println(u.getAccounts());
}
}
}
![aoliignew](C:\Users\16695\Pictures\Saved Pictures\aoliignew.PNG)<?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>org.example</groupId>
<artifactId>aoliigtow</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
</project>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qYMZbT77-1588052911988)(C:\Users\16695\Pictures\Saved Pictures\aoliignew.PNG)]
package com.zpc.Dao;
import com.zpc.Role;
import java.util.List;
public interface IRoleDao {
/**
* 查询所有角色
* @return
*/
List<Role> findAll();
}
package com.zpc.Dao;
import com.zpc.user;
import java.util.List;
public interface ZDao {
/**
* 查询所有操作
* @return
*/
// @Select("select * from user")
List<user> findAll();
/**
* 根据id查询
* @param userId
* @return
*/
user findById(Integer userId);
}
package com.zpc;
import java.io.Serializable;
import java.util.List;
public class Role implements Serializable {
private Integer roleId;
private String roleName;
private String roleDesc;
/**
* 多对多的关系映射,一个角色可以赋予多个用户
*/
private List<user> users;
public List<user> getUsers() {
return users;
}
public void setUsers(List<user> users) {
this.users = users;
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
@Override
public String toString() {
return "Role{" +
"roleId=" + roleId +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
'}';
}
}
package com.zpc;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class user implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
/**
* 多对多的关系映射,一个用户可以具备多个角色
*/
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "user{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
<?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.zpc.Dao.IRoleDao">
<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" ofType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="roleMap">
select u.*,r.id as rid,r.role_name,r.role_desc from role r
left outer join user_role ur on r.id=ur.id
left outer join user u on u.id=ur.uid
</select>
</mapper>
<?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.zpc.Dao.ZDao">
<!--定义user的userMap-->
<resultMap id="userMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!--配置角色集合的映射-->
<collection property="roles" ofType="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</collection>
</resultMap>
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="userMap">
select u.*,r.id as rid,r.role_name,r.role_desc from user u
left outer join user_role ur on u.id=ur.uid
left outer join role r on r.id=ur.rid
</select>
<!--根据id查询用户-->
<select id="findById" parameterType="TNT" resultType="com.zpc.user">
select * from user where id=#{uid}
</select>
</mapper>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis
jdbc.username=root
jdbc.password=123456
# 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{IS08601} %-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.loga4j.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{IS08601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
<?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">
<!--mybatis的主配置文件-->
<configuration>
<!--配置properties
可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件信息
resource:
用于指定配置文件的位置,是按照类路径的写法来写,且必须存在于类路经下
url属性:是按照url的写法来写地址
统一资源定位符,他是唯一标识一个资源的位置
其写法:http://zoda:8080/mybatis/demol
协议 主机 端口 uri
uri:统一资源标识符,他是在应用中可以唯一定位一个资源的
-->
<properties url="file:///D:/ideagongcheng/aoliignew/src/main/resources">
<!--<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>-->
</properties>
<!--使用typeAliases配置别名,他只能配置domain中类的别名-->
<typeAliases>
<!--typeAlias用于配置别名,type属性指定的是实体类全限定类名,alias属性指定别名,当指定了别名就不再区分大小写-->
<!--<typeAlias type="com.zpc.user" alias="User"></typeAlias>-->
<package name="com.zpc"></package>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境,上下二者必须相同(myaql)-->
<environment id="mysql">
<!--配置事务类型(JDBC)-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)(POOLED)-->
<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>
<!--指定映射配置文件的位置(resource),映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<package name="com.zpc.Dao"/>
</mappers>
</configuration>
package com.zpc.test;
import com.zpc.Dao.IRoleDao;
import com.zpc.Dao.ZDao;
import com.zpc.Role;
import com.zpc.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.sql.SQLOutput;
import java.util.List;
public class RoleTest {
private InputStream in;
private SqlSession sqlSession;
private IRoleDao roleDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
roleDao=sqlSession.getMapper(IRoleDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<Role> roles=roleDao.findAll();
for(Role role:roles){
System.out.println("---每个角色的信息---");
System.out.println(role);
System.out.println(role.getUsers());
}
}
}
package com.zpc.test;
import com.zpc.Dao.ZDao;
import com.zpc.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 UserTest {
private InputStream in;
private SqlSession sqlSession;
private ZDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(ZDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<user> users=userDao.findAll();
for(user u:users){
System.out.println("---每个用户的信息---");
System.out.println(u);
System.out.println(u.getRoles());
}
}
}
<?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>org.example</groupId>
<artifactId>aoliignew</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
</project>
package com.zpc.Dao;
import com.zpc.Account;
import java.util.List;
public interface IAccountDao {
/**
* 查询所有用户,同时希望获取到用户下所有账户的信息
* @return
*/
List<Account> findAll();
/**
* 根据用户id查账户信息
* @param uid
* @return
*/
List<Account> findaccountByUid(Integer uid);
}
package com.zpc.Dao;
import com.zpc.user;
import java.util.List;
public interface ZDao {
/**
* 查询所有操作
* @return
*/
// @Select("select * from user")
List<user> findAll();
/**
* 根据id查询
* @param userId
* @return
*/
user findById(Integer userId);
}
package com.zpc;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//从表实体应该包含的主表实体的对象引用
private user users;
public user getUsers() {
return users;
}
public void setUsers(user users) {
this.users = users;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer 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.zpc;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class user implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
//一对多关系映射,主表实体应包含从表实体的关系引用
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "user{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
<?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.zpc.Dao.IAccountDao">
<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="account">
<id property="id" column="id"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--account的数据封装已完成-->
<!--一对一关系映射,配置封装user的内容
select属性指定的:查询用户的唯一标识
column属性指定的:用户根据id查询时,所需要的参数的值
-->
<association property="user" column="uid" javaType="user" select="com.zpc.Dao.ZDao.findById">
</association>
</resultMap>
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultMap="accountUserMap">
select * from account
</select>
<!--根据id查-->
<select id="findaccountByUid" resultType="account">
select * from account where uid=#{uid}
</select>
</mapper>
<?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.zpc.Dao.ZDao">
<!--定义user的userMap-->
<resultMap id="userAccountMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<!--配置user对象中的accounts集合的映射-->
<collection property="accouts" ofType="accout" select="com.apc.Dao.IAccountDao.findaccountByUid" column="id"></collection>
</resultMap>
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="userAccountMap">
select * from user
</select>
<!--根据id查询用户-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findById" parameterType="TNT" resultType="com.zpc.user">
select * from user where id=#{uid}
</select>
</mapper>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis
jdbc.username=root
jdbc.password=123456
# 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{IS08601} %-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{IS08601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
<?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">
<!--mybatis的主配置文件-->
<configuration>
<!--配置properties
可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件信息
resource:
用于指定配置文件的位置,是按照类路径的写法来写,且必须存在于类路经下
url属性:是按照url的写法来写地址
统一资源定位符,他是唯一标识一个资源的位置
其写法:http://zoda:8080/mybatis/demol
协议 主机 端口 uri
uri:统一资源标识符,他是在应用中可以唯一定位一个资源的
-->
<properties resource="jdbcConfig.properties">
</properties>
<!--配置延迟加载参数-->
<settings>
<!--开启延迟-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--允许触发方法进行立即加载-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!--使用typeAliases配置别名,他只能配置domain中类的别名-->
<typeAliases>
<!--typeAlias用于配置别名,type属性指定的是实体类全限定类名,alias属性指定别名,当指定了别名就不再区分大小写-->
<!--<typeAlias type="com.zpc.user" alias="User"></typeAlias>-->
<package name="com.zpc"></package>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境,上下二者必须相同(myaql)-->
<environment id="mysql">
<!--配置事务类型(JDBC)-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)(POOLED)-->
<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>
<!--指定映射配置文件的位置(resource),映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<package name="com.zpc.Dao"/>
</mappers>
</configuration>
package com.zpc.test;
import com.zpc.Account;
import com.zpc.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 SqlSession sqlSession;
private IAccountDao accountDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
accountDao=sqlSession.getMapper(IAccountDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<Account> accounts=accountDao.findAll();
for(Account a:accounts){
// System.out.println("---每个account的信息---");
// System.out.println(a);
// System.out.println(a.getUsers());
}
}
}
package com.zpc.test;
import com.zpc.Dao.ZDao;
import com.zpc.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 UserTest {
private InputStream in;
private SqlSession sqlSession;
private ZDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(ZDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
List<user> users=userDao.findAll();
for(user u:users){
System.out.println("---每个用户的信息---");
System.out.println(u);
System.out.println(u.getAccounts());
}
}
}
pom.xml和以前都一样
package com.zpc.Dao;
import com.zpc.user;
import java.util.List;
public interface ZDao {
/**
* 查询所有操作
* @return
*/
// @Select("select * from user")
List<user> findAll();
/**
* 根据id查询
* @param userId
* @return
*/
user findById(Integer userId);
/**
* 更新用户信息
* @param userhuan
*/
void updateUser(user userhuan);
}
package com.zpc;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class user implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "user{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
<?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.zpc.Dao.ZDao">
<!--开启user支持二级缓存-->
<cache/>
<!--配置查询所有-->
<!--该id必须是在ZDao所定义的那个-->
<select id="findAll" resultType="user">
select * from user
</select>
<!--根据id查询用户-->
<select id="findById" parameterType="TNT" resultType="com.zpc.user" useCache="true">
select * from user where id=#{uid}
</select>
<!--更新用户信息-->
<update id="updateUser" parameterType="user">
update user set username=#{username},address=#{address} where id=#{id}
</update>
</mapper>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis
jdbc.username=root
jdbc.password=123456
# 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{IS08601} %-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{IS08601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
<?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">
<!--mybatis的主配置文件-->
<configuration>
<!--配置properties
可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置文件信息
resource:
用于指定配置文件的位置,是按照类路径的写法来写,且必须存在于类路经下
url属性:是按照url的写法来写地址
统一资源定位符,他是唯一标识一个资源的位置
其写法:http://zoda:8080/mybatis/demol
协议 主机 端口 uri
uri:统一资源标识符,他是在应用中可以唯一定位一个资源的
-->
<properties url="file:///D:/ideagongcheng/aoliig/src/main/resources">
<!--<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>-->
</properties>
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!--使用typeAliases配置别名,他只能配置domain中类的别名-->
<typeAliases>
<!--typeAlias用于配置别名,type属性指定的是实体类全限定类名,alias属性指定别名,当指定了别名就不再区分大小写-->
<!--<typeAlias type="com.zpc.user" alias="User"></typeAlias>-->
<package name="com.zpc"></package>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境,上下二者必须相同(myaql)-->
<environment id="mysql">
<!--配置事务类型(JDBC)-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)(POOLED)-->
<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>
<!--指定映射配置文件的位置(resource),映射配置文件指的是每个dao独立的配置文件-->
<mappers>
<package name="com.zpc.Dao"/>
</mappers>
</configuration>
package com.zpc.test;
import com.zpc.Dao.ZDao;
import com.zpc.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;
public class SecondLevelCacheTest {
private InputStream in;
private SqlSessionFactory factary;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
in.close();
}
/**
* 测试二级缓存
*/
@Test
public void testFirstLeveCache(){
SqlSession sqlSession1=factary.openSession();
ZDao dao1=sqlSession1.getMapper(ZDao.class);
user user1=dao1.findById(41);
System.out.println(user1);
sqlSession1.close();//一级缓存消失
SqlSession sqlSession2=factary.openSession();
ZDao dao2=sqlSession2.getMapper(ZDao.class);
user user2=dao2.findById(41);
System.out.println(user2);
System.out.println(user1==user2);
}
}
package com.zpc.test;
import com.zpc.Dao.ZDao;
import com.zpc.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 UserTest {
private InputStream in;
private SqlSession sqlSession;
private ZDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(ZDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试一级缓存
*/
@Test
public void testFirstLeveCache(){
user user1=userDao.findById(41);
System.out.println(user1);
sqlSession.clearCache();//清空缓存
userDao=sqlSession.getMapper(ZDao.class);
user user2=userDao.findById(41);
System.out.println(user2);
System.out.println(user1==user2);
}
/**
* 测试缓存同步
*/
@Test
public void testClearlCache(){
//根据id查询用户
user user1=userDao.findById(41);
System.out.println(user1);
//更新用户信息
user1.setUsername("ao li gei");
user1.setAddress("西安市");
userDao.updateUser(user1);
//再次查询id为41
user user2=userDao.findById(41);
System.out.println(user2);
System.out.println(user1==user2);
}
}
pom.xml照常
package com.zpc.dao;
import com.zpc.domain.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();
/**
* 保存用户
* @param user
*/
@Insert("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
void savaUser(User user);
/**
* 更新用户
* @param user
*/
@Update("update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address},where id=#{id}")
void updateUser(User user);
/**
* 删除用户
* @param userId
*/
@Delete("delete from user where id=#{id}")
void deleteUser(Integer userId);
/**
* 根据id查询
* @param userId
* @return
*/
@Select("select * from user where id=#{id}")
User findById(Integer userId);
/**
* 模糊查询
* @param username
* @return
*/
@Select("select * from user where username like #{username}")
List<User> findUserByName(String username);
/**
* 查询总用户数量
* @return
*/
@Select("select count(*) from user")
int findTotalUser();
}
package com.zpc.domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
public Integer getId() {
return id;
}
public void setId(Integer 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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
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 + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
'}';
}
}
<?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.zpc.dao"/>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境,上下二者必须相同(myaql)-->
<environment id="mysql">
<!--配置事务类型(JDBC)-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)(POOLED)-->
<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.zpc.domain"></package>
</mappers>
</configuration>
package com.zpc;
import com.zpc.dao.IUserDao;
import com.zpc.domain.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.Date;
import java.util.List;
public class AnnotationCRUDTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 保存用户
*/
@Test
public void testSave(){
User user=new User();
user.setUsername("ao li gei le");
user.setAddress("西安市");
userDao.savaUser(user);
}
/**
* 修改用户
*/
@Test
public void testUpdate(){
User user=new User();
user.setId(321);
user.setUsername("ao li gei le ha");
user.setAddress("西安市c");
user.setBirthday(new Date());
userDao.updateUser(user);
}
/**
* 删除用户
*/
@Test
public void testDelete(){
userDao.deleteUser(32);
}
/**
* 查询用户
*/
@Test
public void testFindOne(){
User user=userDao.findById(32);
System.out.println(user);
}
/**
* 模糊查询
*/
public void testFindByName(){
List<User> users=userDao.findUserByName("%王%");
for(User user : users){
System.out.println(user);
}
}
/**
* 查询所有用户总量
*/
public void testFindTotal(){
int t=userDao.findTotalUser();
System.out.println(t);
}
}
package com.zpc;
import com.zpc.dao.IUserDao;
import com.zpc.domain.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 MybatisAnnoTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void TestfindAll(){
//5:使用代理对象执行方法
List<User> users= userDao.findAll();
for(User usernew:users){
System.out.println(usernew);
}
}
}
pom.xml没变
package com.zpc.dao;
import com.zpc.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;
public interface IAccountDao {
/**
* 查询所有账户,并且获取每个账户下所属的用户信息
* @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") , //account其本身的已经封装完成,接下来连接user
@Result(property = "user",column = "uid",one = @One(select ="com.zpc.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.zpc.dao;
import com.zpc.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,column="id",property="userId"),
@Result(id=true,column="username",property="userName"),
@Result(id=true,column="address",property="userAddress"),
@Result(id=true,column="sex",property="userSex"),
@Result(id=true,column="birthday",property="userBirthday"),
@Result(property = "accounts",column = "id",many = @Many(select = "com.zpc.dao.IAccountDao.findAccountByUid",fetchType = FetchType.LAZY))
})
List<User> findAll();
/**
* 根据id查询
* @param userId
* @return
*/
@Select("select * from user where id=#{id}")
@ResultMap(value={"userMap"})
User findById(Integer userId);
/**
* 模糊查询
* @param username
* @return
*/
@Select("select * from user where username like #{username}")
@ResultMap(value={"userMap"})
List<User> findUserByName(String username);
}
package com.zpc.domain;
import java.io.Serializable;
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//多对一(mybatis中称为一对一)的映射:一个账户只能属于一个用户
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer 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.zpc.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class User implements Serializable {
private Integer userId;
private String usernName;
private String userAddress;
private String userSex;
private Date userBirthday;
//一对多关系映射,一个用户对应多个账户
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUsernName() {
return usernName;
}
public void setUsernName(String usernName) {
this.usernName = usernName;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
public String getUserSex() {
return userSex;
}
public void setUserSex(String userSex) {
this.userSex = userSex;
}
public Date getUserBirthday() {
return userBirthday;
}
public void setUserBirthday(Date userBirthday) {
this.userBirthday = userBirthday;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", usernName='" + usernName + '\'' +
", userAddress='" + userAddress + '\'' +
", userSex='" + userSex + '\'' +
", userBirthday=" + userBirthday +
'}';
}
}
<?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.zpc.dao"/>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境,上下二者必须相同(myaql)-->
<environment id="mysql">
<!--配置事务类型(JDBC)-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)(POOLED)-->
<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.zpc.domain"></package>
</mappers>
</configuration>
package com.zpc;
import com.zpc.dao.IAccountDao;
import com.zpc.dao.IUserDao;
import com.zpc.domain.Account;
import com.zpc.domain.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 AccountTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IAccountDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IAccountDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 查询所有用户
*/
@Test
public void testFindAll() {
List<Account> accounts = userDao.findAll();
for (Account account : accounts) {
System.out.println("---每个账户的信息---");
System.out.println(account);
System.out.println(account.getUser());
}
}
}
package com.zpc;
import com.zpc.dao.IUserDao;
import com.zpc.domain.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.Date;
import java.util.List;
public class AnnotationCRUDTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 查询所有用户
*/
@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 testFindOne(){
User user=userDao.findById(32);
System.out.println(user);
}
/**
* 模糊查询
*/
public void testFindByName(){
List<User> users=userDao.findUserByName("%王%");
for(User user : users){
System.out.println(user);
}
}
}
package com.zpc;
import com.zpc.dao.IUserDao;
import com.zpc.domain.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;
public class SecondLevelCatchTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
in.close();
}
/**
* 查询用户
*/
@Test
public void testFindOne(){
User user=userDao.findById(32);
System.out.println(user);
sqlSession.close();//释放一级缓存
SqlSession session2=factory.openSession();//再次打卡Session
IUserDao userDao1=session2.getMapper(IUserDao.class);
User user1=userDao.findById(32);
System.out.println(user1);
}
}
}
public Date getUserBirthday() {
return userBirthday;
}
public void setUserBirthday(Date userBirthday) {
this.userBirthday = userBirthday;
}
@Override
public String toString() {
return "User{" +
"userId=" + userId +
", usernName='" + usernName + '\'' +
", userAddress='" + userAddress + '\'' +
", userSex='" + userSex + '\'' +
", userBirthday=" + userBirthday +
'}';
}
}
#### jdbcConfig.properties和loglj.properties依然那样
#### SqlMapConfig.xml(zpcad.xml)
```java
package com.zpc;
import com.zpc.dao.IAccountDao;
import com.zpc.dao.IUserDao;
import com.zpc.domain.Account;
import com.zpc.domain.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 AccountTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IAccountDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IAccountDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 查询所有用户
*/
@Test
public void testFindAll() {
List<Account> accounts = userDao.findAll();
for (Account account : accounts) {
System.out.println("---每个账户的信息---");
System.out.println(account);
System.out.println(account.getUser());
}
}
}
package com.zpc;
import com.zpc.dao.IUserDao;
import com.zpc.domain.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.Date;
import java.util.List;
public class AnnotationCRUDTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
//提交事务
sqlSession.commit();
//6:释放资源
sqlSession.close();
in.close();
}
/**
* 查询所有用户
*/
@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 testFindOne(){
User user=userDao.findById(32);
System.out.println(user);
}
/**
* 模糊查询
*/
public void testFindByName(){
List<User> users=userDao.findUserByName("%王%");
for(User user : users){
System.out.println(user);
}
}
}
package com.zpc;
import com.zpc.dao.IUserDao;
import com.zpc.domain.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;
public class SecondLevelCatchTest {
private InputStream in;
private SqlSessionFactory factory;
private SqlSession sqlSession;
private IUserDao userDao;
@Before //用于在测试方法执行之前执行
public void init()throws Exception{
//1:读取配置文件
in= Resources.getResourceAsStream("zpcad.xml");
//2:创建SqlSessionFactory工厂
factory=new SqlSessionFactoryBuilder().build(in);
//3:使用工厂生产SqlSession对象
sqlSession=factory.openSession(true);
//4:使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(IUserDao.class);
}
@After //用于测试方法执行后执行
public void destory()throws Exception{
in.close();
}
/**
* 查询用户
*/
@Test
public void testFindOne(){
User user=userDao.findById(32);
System.out.println(user);
sqlSession.close();//释放一级缓存
SqlSession session2=factory.openSession();//再次打卡Session
IUserDao userDao1=session2.getMapper(IUserDao.class);
User user1=userDao.findById(32);
System.out.println(user1);
}
}