使用什么工具什么步骤完成网站的设计与建设,做微信图文推送的网站,淄博网站开发找网泰,做的比较漂亮的中国网站参考链接#xff1a; 在Java中使用_(下划线)作为变量名
mybatis第一天
1.mybatis概述和环境搭建
mybatis概述
mybatis环境搭建
1. 创建maven工程、添加开发依赖、创建数据库和表#xff1b;
2. 创建domain实体类和dao
mybatis是一门java语言编写持久层框架…参考链接 在Java中使用_(下划线)作为变量名
mybatis第一天
1.mybatis概述和环境搭建
mybatis概述
mybatis环境搭建
1. 创建maven工程、添加开发依赖、创建数据库和表
2. 创建domain实体类和dao
mybatis是一门java语言编写持久层框架大大简化了jdbc操作省去了我们注册驱动获取连接等细节操作。 org.mybatis
mybatis
3.4.5 mysql
mysql-connector-java
8.0.11 junit
junit
4.11
test log4j
log4j
1.2.12
3. 在resource中编写mybatis主配置文件
4. 编写每个dao接口的映射配置文件
/**
* 用户的持久层接口
*/
public interface IUserDao {
/**
* 查询所有操作
* return
*/
ListUser findAll();
}
PUBLIC -//mybatis.org//DTD Config 3.0//EN
http://mybatis.org/dtd/mybatis-3-config.dtd defaultmysql
idmysql
typejdbc
typepooled
namedriver valuecom.mysql.jdbc.Driver/
nameurl valuejdbc:mysql://localhost:3306/mybatis/
nameusername valueroot/
namepassword value78910J/ resourcecom/itheima/dao/IUserDao.xml
5.注意事项
6.测试类中测试方法编写
PUBLIC -//mybatis.org//DTD Mapper 3.0//EN
http://mybatis.org/dtd/mybatis-3-mapper.dtd
namespacecom.itheima.dao.IUserDao//namespace:接口的路径 定位类中方法的具体位置
idfindAll resultTypecom.itheima.domain.User SELECT * FROM USER
1.在resource中创建IUserDao.xml时文件的位置必须和IUserDao包结构相同创建IUserDao.xml所在目录结
构时要一级一级创建。
2.映射配置文件中的mapper的namespace属性值必须是IUserDao的全类名
3.执行sql操作的配置id属性必须是执行方法的名词例如 select idfindAll
Test
public void testFindAll() throws IOException {
//1.读取SqlMapConfig.xml配置文件
InputStream is Resources.getResourceAsStream(SqlMapConfig.xml);
//2.创建SqlSessionFactory工厂类
SqlSessionFactoryBuilder buildernew SqlSessionFactoryBuilder();
SqlSessionFactory factory builder.build(is);
//3.使用SqlSessionFactory工厂创建SqlSession核心对象
/*SqlSessionFactory是MyBatis的关键对象,它是个单个数据库映射
关系经过编译后的内存镜像.SqlSessionFactory对象的实例可以通
过SqlSessionFactoryBuilder对象类获得,而SqlSessionFactoryBuilder
则可以从XML配置文件或一个预先定制的Configuration的实例构建出SqlSessionFactory
的实例.每一个MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心.
同时SqlSessionFactory也是线程安全的,SqlSessionFactory一旦被创建,应该在
应用执行期间都存在.在应用运行期间不要重复创建多次,建议使用单例模式.SqlSessionFactory
是创建SqlSession的工厂.*/
SqlSession session factory.openSession();//openSession方法默认手动提交 填写false就是自动
提交 当对表数据crud就需要提交事务
//4.使用SqlSession创建接口的代理对象
IUserDao userDao session.getMapper(IUserDao.class);
//5.执行查询方法
ListUser users userDao.findAll();
for (User user : users) {
System.out.println(user);
}
//6.释放资源
is.close();
session.close();
}2.mybatis注解开发和编写dao实体类方式
mybatis注解开发
编写dao实现类开发
1.在核心配置文件SqlMapConfig.xml的mappers中添加注解映射方式
mappers
mapper classcom.itheima.dao.IUserMapper/
mappers
2.定义接口和抽象方法在抽象方法上添加对应的注解
public interface IUserMapper {
/**
* 查询所有用户信息
*/
Select(select * from user)
public ListUser findList();
}
3.进行测试
Test
public void testFindList() throws IOException {
//1.读取核心配置文件
InputStream is Resources.getResourceAsStream(SqlMapConfig.xml);
//2.创建SqlSessionFactory工厂类
SqlSessionFactoryBuilder buildernew SqlSessionFactoryBuilder();
SqlSessionFactory factory builder.build(is);
//3.创建SqlSession核心对象
SqlSession session factory.openSession();
//4.获取dao代理对象
IUserMapper mapper session.getMapper(IUserMapper.class);
//5.执行查询操作
ListUser users mapper.findList();
for (User user : users) {
System.out.println(user);
}
//6.释放资源
is.close();
session.close();
}
1.编写实现类
public class UserDaoImpl implements IUserDao{
//1.声明SqlSessionFactory工厂类
private SqlSessionFactory factory;
//2.构造赋值
public UserDaoImpl(SqlSessionFactory factory) {
this.factory factory;
}
Override
public ListUser findAll() {注意同一个dao接口不允许配置两种映射方式例如下列写法是错误的
3.自定义mybatis框架
流程分析
自定义mybatis流程分析.png
alt text
Alt text
alt text
新建module根据入门案例测试方法创建缺少的接口和类
导入资料中utils目录中的XMLConfifigBuilder.java文件并修改错误
//1.创建核心的SqlSession对象
SqlSession session factory.openSession();
//2.调用查询的相关方法哪个namespace中的哪个id方法对应的sql
ListUser users session.selectList(com.itheima.dao.IUserDao.findAll);
//3.释放资源
session.close();
return users;
}
}
2.进行测试
Test
public void testFindAllImpl() throws IOException {
//1.读取核心配置文件
InputStream is Resources.getResourceAsStream(SqlMapConfig.xml);
//2.创建SqlSessionFactory工厂类
SqlSessionFactoryBuilder buildernew SqlSessionFactoryBuilder();
SqlSessionFactory factory builder.build(is);
//3.创建实现类对象并调用实现类方法查询所有用户信息
UserDaoImpl daonew UserDaoImpl(factory);
ListUser users dao.findAll();
//4.遍历输出
for (User user : users) {
System.out.println(user);
}
//4.释放资源
is.close();
} resourcecom/itheima/dao/IUserDao.xml/
classcom.itheima.dao.IUserDao/
完成SqlSessionFactoryBuilder、SqlSessionFactory接口实现类、SqlSession接口实现类功能实现类要自
己创建
SqlSessionFactoryBuilder代码实现
1.添加依赖
dependency
groupIddom4jgroupId
artifactIddom4jartifactId
version1.6.1version
dependency
dependency
groupIdjaxengroupId
artifactIdjaxenartifactId
version1.1.6version
dependency
2.创建Configuration和Mapper两个javabean对象
public class Configuration {
private String driver;
private String url;
private String username;
private String password;
private MapString,Mapper mappersnew HashMapString, Mapper();//保存多组映射信息的map集
合
// getter/setter方法省略
public void setMappers(MapString, Mapper mappers) {
this.mappers.putAll(mappers);
}
}
public class Mapper {
private String queryString;
private String resultType;
// getter/setter方法省略
}
/**
* 构建者对象
*/
public class SqlSessionFactoryBuilder {
/**
* 根据配置文件输入流对象创建工厂对象
* param configStream 配置文件输入流
* return
*/
public SqlSessionFactory build(InputStream configStream) {
//1.使用XMLConfigBuilder解析配置文件
Configuration configuration XMLConfigBuilder.loadConfiguration(configStream);
System.out.println(configuration configuration);
//2.创建工厂实现类对象并返回
return new DefaultSqlSessionFactory(configuration);DefaultSqlSessionFactory代码实现
DefaultSqlSession代码实现
}
}
/**
* SqlSessionFactory接口的实现类
*/
public class DefaultSqlSessionFactory implements SqlSessionFactory {
//声明封装主配置文件对象
private Configuration configuration;
public DefaultSqlSessionFactory(Configuration configuration) {
this.configurationconfiguration;
}
/**
* 生产操作数据库的核心SqlSession对象
* return
*/
public SqlSession openSession() {
//创建SqlSession实现类对象并返回
return new DefaultSqlSession(configuration);
}
}
/**
* 操作数据库核心SqlSession接口的实现类
*/
public class DefaultSqlSession implements SqlSession {
//声明封装主配置文件对象,因为getMapper需要连接和映射信息所以需要这个配置对象
private Configuration configuration;
private Connection conn;
public DefaultSqlSession(Configuration configuration) {
this.configurationconfiguration;
//从连接池工具类中获取连接对象
conn DataSourceUtils.getConnection(configuration);
}
/**
* 通过动态代理的方式创建接口的实现类对象
* param daoClass 接口的Class对象
* param 返回接口实现类对象
* return
*/
public T T getMapper(ClassT daoClass) {
//创建dao代理对象并返回
T t (T) Proxy.newProxyInstance(daoClass.getClassLoader(),
new Class[]{daoClass},
new MapperProxy(configuration.getMappers(),conn));
return t;DataSourceUtils工具类获取连接
InvocationHandler实现类MapperProxy的代码实现
}
/**
* 释放资源
*/
public void close() {
try {
if (conn!null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
/**
* 将来封装连接池的工具类目前不使用连接池
*/
public class DataSourceUtils {
public static Connection getConnection(Configuration cfg) {
//1.注册驱动
try {
Class.forName(cfg.getDriver());
//2.获取连接
return
DriverManager.getConnection(cfg.getUrl(),cfg.getUsername(),cfg.getPassword());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
/**
* 当dao代理对象的方法被调用时该监听类的invoke方法就会执行
*/
public class MapperProxy implements InvocationHandler {
//map集合的key全类名方法名
private MapString, Mapper mappers;//封装了sql语句和结果类型
private Connection conn;//连接对象
public MapperProxy(MapString, Mapper mappers,Connection conn) {
this.mappersmappers;
this.connconn;
}
//当dao代理对象的方法被调用时invoke方法就会执行参数method表示代理对象调用的方法
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//1.根据执行的method方法从mappers集合中找到对应的mapper对象
//1.1.获取方法名将MapperProxy中需要的Executor类从资料中复制到项目的utils包下该Executor类的selectList方法帮
我们查询所有信息并封装到List中
注意在没网的情况下需要删除SqlMapConfifig和映射文件的约束信息
mybatis第二天
1.mybatis的CRUD操作
1.1.映射配置文件IUserDao.xml信息
String methodName method.getName();
//1.2.获取全类名
String className method.getDeclaringClass().getName();
//1.3.拼接map集合的key找到对应的mapper对象
String keyclassName.methodName;
System.out.println(key key);
//1.4.找到要的Mapper对象
Mapper mapper mappers.get(key);
if (mappernull) {
//没找到配置的全类名有误或者方法有误
throw new IllegalStateException(在className类中没有methodName方法);
}
//2.调用Executor工具类的selectList方法执行查询操作
return new Executor().selectList(mapper,conn);
}
}
PUBLIC -//mybatis.org//DTD Mapper 3.0//EN
http://mybatis.org/dtd/mybatis-3-mapper.dtd
namespacecom.itheima.dao.IUserDao
idfindAll resultTypecom.itheima.domain.User SELECT * from user
idsaveUser parameterTypecom.itheima.domain.User
/*添加用户信息之后查询新用户的id keyProperty对应的是user的id属性*/
keyColumnid keyPropertyid resultTypeint orderAFTER
select last_insert_id();
/*selectKey是后来加的在添加用户信息时可以先忽略*/
insert into user values (null,#{username},#{birthday},#{sex},#{address})
idupdateUser parameterTypecom.itheima.domain.User1.2.封装数据的User类省略
1.3.测试类代码
update user set username#{username},birthday#{birthday},sex#{sex},address#{address}
where id#{id}
iddeleteUser parameterTypeInteger
delete from user where id#{id}
idfindById resultTypecom.itheima.domain.User parameterTypeint select * FROM user where id#{id}
idfindByName parameterTypeString resultTypecom.itheima.domain.User select * from user where username like #{username}
idfindTotal resultTypeint select count(*) from user
public class MybatisTest {
private InputStream is;
private SqlSession session;
private IUserDao userDao;
/**
* 初始化mybatis
*/
Before
public void init() throws IOException {
//1.加载核心配置文件SqlMapConfig.xml
is Resources.getResourceAsStream(SqlMapConfig.xml);
//2.创建SqlSessionFactory工厂对象
SqlSessionFactoryBuilder buildernew SqlSessionFactoryBuilder();
SqlSessionFactory factory builder.build(is);
//3.创建核心SqlSession对象
session factory.openSession();
//4.创建IUserDao对象
userDao session.getMapper(IUserDao.class);
}
/**
* 测试查询所有用户信息的findAll()方法
*/
Test
public void testFindAll(){
ListUser users userDao.findAll();
//遍历打印
for (User user : users) {System.out.println(user);
}
}
/**
* 测试保存用户信息的saveUser()方法
*/
Test
public void testSaveUser(){
//创建用户信息
User usernew User();
user.setUsername(老周);
user.setBirthday(new Date());
user.setAddress(武汉);
user.setSex(男);
System.out.println(添加前user user);
//添加到数据
int row userDao.saveUser(user);
System.out.println(影响的行数row row);
//在IUserDao.xml配置了selectKey后添加完user就会查询到新用户的id并封装到user的id属性上。
System.out.println(添加后user user);
}
/**
* 测试更新用户信息的updateUser()方法
*/
Test
public void testUpdateUser(){
//准备要修改用户的信息信息
User usernew User();
user.setId(52);
user.setUsername(老李);
user.setBirthday(new Date());
user.setAddress(孝感);
user.setSex(女);
//修改用户
int row userDao.updateUser(user);
System.out.println(row row);
}
/**
* 测试更加用户id删除用户信息的deleteUser()方法
*/
Test
public void testDeleteUser(){
//根据id删除用户信息
int row userDao.deleteUser(52);
System.out.println(row row);
}
/**
* 测试根据id查询用户信息的findById()方法
*/
Test
public void testFindById(){
User user userDao.findById(50);
System.out.println(user);2.mybatis映射配置参数和返回值类型深入学习
2.1.parameterType传递pojo包装对象
QueryVo实体类
映射文件配置
}
/**
* 测试根据用户名称模糊查询的findByName()方法
*/
Test
public void testFindByName(){
ListUser users userDao.findByName(%王%);
for (User user : users) {
System.out.println(user);
}
}
/**
* 测试查询总记录条数的findTotal()方法
*/
Test
public void testFindTotal(){
int total userDao.findTotal();
System.out.println(total total);
}
/**
* 释放资源
*/
After
public void destory() throws IOException {
//提交事务
session.commit();
//6.释放资源
session.close();
is.close();
}
}
public class QueryVo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user user;
}
}测试类测试方法编写
mybatis的dao层开发模式
返回值类型-javabean的属性和表字段名一致情况了解
javabean实体类
idfindByVo parameterTypecom.itheima.domain.QueryVo resultTypecom.itheima.domain.User /*username是user的属性user是QueryVo的属性*/ select * from user where username like #{user.username}
/**
* 测试根据 QueryVo 中的条件查询用户的findByVo()方法
*/
Test
public void testFindByVo(){
//创建QueryVo对象
QueryVo queryVonew QueryVo();
//创建模糊查询条件封装到user对象中
User usernew User();
user.setUsername(%王%);
queryVo.setUser(user);
//执行查询
ListUser users userDao.findByVo(queryVo);
//遍历打印
for (User u : users) {
System.out.println(u);
}
}
* 基于DAO代理方式(推荐使用)
* CRUD操作(保存操作|修改操作|删除操作|查询一个|模糊查询|单值查询|获取保存对象的id)
* 模糊查询需要注意
* 获取保存对象的id
* 输入参数 parameterType属性
* 输入参数的类型int、string、User、plain old java object、包装类型ValueObject
* 输出参数 resultType属性、
* 输入参数的类型User、int、string
* 解决实体类属性和数据库列名不对应
* 在sql语句上取别名 对应 简单
* 通过resultMap属性来映射java对象和数据库列名之间的关系
* result propertyuserName columnusernameresult
property 遵循的是驼峰规则; column 单词下划线隔开解决办法1sql的结果集使用别名别名和javabean的属性一致
好处查询效率高弊端书写麻烦开发效率低。
解决办法2使用mybatis给我们提供的配置结果集映射
好处idUMap的可以重复使用开发效率高弊端查询效率略低。
编写测试类测试方法
public class U {
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
//自动生成setter、getter、toString省略此时属性和表的字段名不一致
}
idfindAllU resultTypecom.itheima.domain.U select id userId,username userName,birthday userBirthday,sex userSex,address userAddress from user;
idUMap typecom.itheima.domain.U
columnid propertyuserId/
columnusername propertyuserName/
columnbirthday propertyuserBirthday/
columnsex propertyuserSex/
columnaddress propertyuserAddress/
idfindAllU resultMapUMap select * from user; 3.mybatis中编写dao实现类的使用(了解)
UserDaoImpl实现类代码
/**
* 测试使用别名查询所有用户信息的findAllU()方法
*/
Test
public void testFindAllU(){
ListU us userDao.findAllU();
//遍历打印
for (U u : us) {
System.out.println(u);
}
}
public class UserDaoImpl implements IUserDao {
private SqlSessionFactory factory;
//接收工厂对象用于创建SqlSession对象
public UserDaoImpl(SqlSessionFactory factory) {
this.factory factory;
}
Override
public ListUser findAll() {
//1.创建核心的SqlSession对象
SqlSession session factory.openSession();
//2.调用selectList方法查询所有用户信息
ListUser users session.selectList(com.itheima.dao.IUserDao.findAll);
//3.释放资源
session.close();
return users;
}
Override
public int saveUser(User user) {
//1.创建核心的SqlSession对象
SqlSession session factory.openSession();
//2.调用insert方法添加一条用户信息
int row session.insert(com.itheima.dao.IUserDao.saveUser, user);
//3.提交并释放资源
session.commit();
session.close();
//返回影响的函数
return row;
}
Override
public int updateUser(User user) {
//1.创建核心的SqlSession对象
SqlSession session factory.openSession();
//2.调用update方法修改一条用户信息
int row session.update(com.itheima.dao.IUserDao.updateUser, user);
//3.提交并释放资源session.commit();
session.close();
//返回影响的函数
return row;
}
Override
public int deleteUser(int id) {
//1.创建核心的SqlSession对象
SqlSession session factory.openSession();
//2.调用delete方法删除一条用户信息
int row session.delete(com.itheima.dao.IUserDao.deleteUser, id);
//3.提交并释放资源
session.commit();
session.close();
//返回影响的函数
return row;
}
Override
public User findById(Integer id) {
//1.创建核心的SqlSession对象
SqlSession session factory.openSession();
//2.调用selectList方法查询所有用户信息
User user session.selectOne(com.itheima.dao.IUserDao.findById,id);
//3.释放资源
session.close();
return user;
}
Override
public ListUser findByName(String username) {
//1.创建核心的SqlSession对象
SqlSession session factory.openSession();
//2.调用selectList方法根据username模糊查询所有用户信息
ListUser users session.selectList(com.itheima.dao.IUserDao.findByName,username);
//3.释放资源
session.close();
return users;
}
Override
public int findTotal() {
//1.创建核心的SqlSession对象
SqlSession session factory.openSession();
//2.调用delete方法删除一条用户信息
int total session.selectOne(com.itheima.dao.IUserDao.findTotal);
//3.释放资源
session.close();
//返回总记录数
return total;
}
Override
public ListUser findByVo(QueryVo vo) {
//1.创建核心的SqlSession对象
SqlSession session factory.openSession();
//2.调用selectList方法根据vo.user.username模糊查询所有用户信息修改测试类init方法和destory方法即可,其他测试方法都不需要改
4.mybatis中编写dao实现类的使用过程分析
5.properties标签、typeAliases标签、package标签使用
5.1.properties标签的作用
ListUser users
session.selectList(com.itheima.dao.IUserDao.findByName,vo.getUser().getUsername());
//3.释放资源
session.close();
return users;
}
Override
public ListU findAllU() {
//1.创建核心的SqlSession对象
SqlSession session factory.openSession();
//2.调用selectList方法查询所有用户信息
ListU us session.selectList(com.itheima.dao.IUserDao.findAllU);
//3.释放资源
session.close();
return us;
}
}
Before
public void init() throws IOException {
//1.加载核心配置文件SqlMapConfig.xml
is Resources.getResourceAsStream(SqlMapConfig.xml);
//2.创建SqlSessionFactory工厂对象
SqlSessionFactoryBuilder buildernew SqlSessionFactoryBuilder();
SqlSessionFactory factory builder.build(is);
/*如果是使用dao代理方式则需要创建SqlSession对象并获取dao的代理对象*/
/*//3.创建核心SqlSession对象
session factory.openSession();
//4.创建IUserDao对象
userDao session.getMapper(IUserDao.class);*/
/*如果使用的是自定义dao实现类方法则需要创建dao实现类对象并传递factory工厂对象*/
userDaonew UserDaoImpl(factory);
}
After
public void destory() throws IOException {
//提交事务,如果是自定义dao实现类就不需要在实现类内部提交
//session.commit();
//6.释放资源,如果是自定义dao实现类就不需要在实现类内部关闭
//session.close();
is.close();
}作用将连接数据库的信息单独配置到一个properties属性文件中配置方式如下
外部jdbcConfifig.properties配置文件
在SqlMapConfifig.xml跟标签下使用properties标签引入jdbcConfifig.properties
在dataSource中引入外部properties的各个属性
5.2.typeAliases标签、package标签使用作用
SqlMapConfifig.xml跟标签下使用typeAliases标签作用 javabean取别名(了解)
jdbc.drivercom.mysql.jdbc.Driver
jdbc.urljdbc:mysql://localhost:3306/mybatis?serverTimezoneAsia/Shanghai
jdbc.usernameroot
jdbc.password78910J namedriver valuecom.mysql.jdbc.Driver/
nameurl valuejdbc:mysql://localhost:3306/mybatis?
serverTimezoneAsia/Shanghai/
nameusername valueroot/
namepassword value78910J/
或者
resourcejdbcConfig.properties
或者
url
file:///D:/IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.prop
erties
typepooled
namedriver value${jdbc.driver}/
nameurl value${jdbc.url}/
nameusername value${jdbc.username}/
namepassword value${jdbc.password}/
typeAliases标签下使用package标签作用 指定包下的所有javabean的类名就是其别名不区分大小写
(实用)
Mappers标签下使用package标签作用 不用写mapper标签,resources或class指定包下所有dao对应的
映射文件都不用引入了,并且可以找到dao的接口或者dao接口对应的配置。(实用)
mybatis第三天
1.mybatis中连接池以及事务管理
1.1 mybatis连接池
mybatis中三种数据源介绍
在sqlMapConfifig.xml中配置 typecom.itheima.domain.User aliasuser/ namecom.itheima.dao/
UNPOOLED 不使用连接池的数据源需要连接对象就使用DriverManager创建获取一个使用完成就直接销毁
POOLED 使用连接池的数据源 (很常用)
JNDI 使用 JNDI 实现的数据源最后讲解了解1.2 mybatis事务管理
mybatis中默认是开启也是也就是增删改之后需要手动session.commit()方法手动提交事务但是我们也可以设
置自动提交在增删改完成之后不需要手动调用session.commit()提交事务。只需要在session
factory.openSession(true);参数true表示自动提交。
2.mybatis中动态SQL
使用场景如果条件存在就带条件查询如果条件不存在就不带条件查询适用于搜索等场景。
2.1 if标签 - 动态添加条件
在IUserDao.xml中配置查询语句
2.2 where 标签 - 代替where 11
在IUserDao.xml中修改之前配置的查询语句
在sqlMapConfig.xml中配置如下
typepooled
namedriver value${jdbc.driver}/
nameurl value${jdbc.url}/
nameusername value${jdbc.username}/
namepassword value${jdbc.password}/
MyBatis 在初始化时根据的 type 属性来创建相应类型的的数据源 DataSource即
typePOOLED MyBatis 会创建 PooledDataSource 实例
typeUNPOOLED MyBatis 会创建 UnpooledDataSource 实例
typeJNDI MyBatis 会从 JNDI 服务上查找 DataSource 实例然后返回使用
idfindUserByCondition1 parameterTypeuser resultTypeuser select * from user where 11 testusername!null and username!//连接判断条件不能为和|| and username #{username} testsex!null and sex #{sex} 2.3 foreach标签 - 遍历适用于in的条件
foreach元素的属性主要有 itemindexcollectionopenseparatorclose。
item 循环体中的具体对象。支持属性的点路径访问如 item.age,item.info.details。具体说明在 list 和数
组中是其中的对象在 map 中是 value该参数为必选。它是每一个元素进行迭代时的别名
index在 list 和数组中,index 是元素的序号在 map 中index 是元素的 key。
open 表示该语句以什么开始
separator 表示在每次进行迭代之间以什么符号作为分隔符
close 表示以什么结束
_parameter :不只是方法传递过来的参数可以被用来判断取值
_parameter:代表整个参数
单个参数_parameter就是这个参数
多个参数 1.参数会被封装为一个map:_parameter就是代表这个map
2._parameter 可以get(0)得到第一个参数。
在使用foreach的时候最关键的也是最容易出错的就是collection属性该属性是必须指定的但是在不同情况 下该
属性的值是不一样的主要有一下3种情况
1.如果传入的是单参数且参数类型是一个List的时候collection属性值为list
2.如果传入的是单参数且参数类型是一个array数组的时候collection的属性值为array
3.如果传入的参数是多个的时候我们就需要把它们封装成一个Map了当然单参数也可以封装成map
遍历map集合
idfindUserByCondition1 parameterTypeuser resultTypeuser select * from user testusername!null and username! and username #{username} testsex!null and sex #{sex} 需求根据qv中list集合查询用户信息-
在IUserDao.xml中配置查询语句
测试类中测试- QueryVo中添加ids属性省略了
idfindByMap parameterTypemap resultTypecn.itcast.mybatis.pojo.Product select * from user collection_parameter indexkey itemvalue separatorand testvalue !null ${key} #{value}
idfindUserByCondition2 parameterTypeQueryVo resultTypeuser select * from user testids!null and ids.size0 idfindUserByCondition2 parameterTypeQueryVo resultTypeuser
select * from user testids!null and ids.size0
and id in(
collectionids itemuid separator,
#{uid}
)
Test
public void testFindUserByCondition2(){
QueryVo qvnew QueryVo();
ListInteger idsnew ArrayListInteger();
ids.add(41);2.4 补充1抽取公共的sql语句
在IUserDao.xml中跟标签中使用sql标签定义公共sql语句
在中使用标签引入公共sql 3.mybatis多表之间关系 3.1 一对一关系 需求一个账户只属于一个用户查询账户信息的同时查询用户信息 实现步骤 一对一映射 代码示例 1.创建Account实体类以及IAccountDao接口 ids.add(45); ids.add(46); ids.add(48); qv.setIds(ids); ListUser list userDao.findUserByCondition2(qv); //变量展示 for (User u : list) { System.out.println(u u); } } idselectTemplate select * from user idfindAll resultTypecom.itheima.domain.User
refidselectTemplate/
1.创建Account实体类以及IAccountDao接口
2.创建IAccountDao.xml映射问题
3.创建AccountDaoTest测试类进行测试
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//封装对应的user对象2.创建IAccountDao.xml映射文件
3.创建AccountTest测试类进行测试
private User user;
//setter、getter、toString方法省略
}
public interface IAccountDao {
/**
* 查询所有账号信息同时查询对应用户信息
* return
*/
ListAccount findAll();
}
namespacecom.itheima.dao.IAccountDao
idaccountUserMap typeaccount
columnaid propertyid/
columnuid propertyuid/
columnmoney propertymoney/
propertyuser javaTypeuser columnuid
columnid propertyid/
columnusername propertyusername/
columnbirthday propertybirthday/
columnsex propertysex/
columnaddress propertyaddress/
idfindAll resultMapaccountUserMap /*注意当多表查询结果有相同字段名时我们需要取别名区分*/ SELECT u.*,a.id aid,a.UID,a.MONEY FROM user u,account a where u.ida.UID;
Test
public void testFindAll(){
//1.调用findAll方法
ListAccount list accountDao.findAll();
//2.遍历打印结果
for (Account account : list) {
System.out.println(account);
}
}注意当多表查询结果有相同字段名时我们需要取别名区分
3.2 一对多关系
需求一个用户有多个账户查询用户信息的同时查询其所有账户信息
实现步骤
一对多映射
代码示例
在IUserDao中添加新的查询方法
在IUserDao.xml中重新配置查询语句
编写UserTest测试类进行测试
1.在user中添加ListAccount accounts属性在IUserDao中添加新的查询方法
2.在IUserDao.xml中重新配置查询语句
3.在AccountDaoTest测试类进行测试
/**
* 多表查询查询用户信息的同时查询其所有账户信息
* return
*/
ListUser findAllUserAndAccount();
iduserAccountMap typeuser
columnid propertyid/
columnusername propertyusername/
columnbirthday propertybirthday/
columnsex propertysex/
columnaddress propertyaddress/
propertyaccounts javaTypejava.util.List ofTypeaccount
columnid propertyid/
columnuid propertyuid/
columnmoney propertymoney/
idfindAllUserAndAccount resultMapuserAccountMap SELECT * FROM user u LEFT OUTER JOIN account a ON u.id a.UID; 3.3 多对多关系
3.3.1 需求1查询角色信息以及该角色对应的所有用户信息
实现步骤
代码示例
1.创建实体类Role以及IRoleDao接口
/**
* 多表查询查询用户信息的同时查询其所有账户信息
*/
Test
public void testFindAllUserAndAccount(){
ListUser users userDao.findAllUserAndAccount();
for (User user : users) {
System.out.println(user);
}
}
1.创建实体类Role以及IRoleDao接口
2.创建IRoleDao.xml映射文件并配置查询信息
3.创建RoleDaoTest测试类并测试查询方法
public class Role {
private Integer id;
private String roleName;
private String roleDesc;
//封装该角色对应的所有用户信息
private ListUser users;
//setter、getter、toString方法省略
}
public interface IRoleDao {2.创建IRoleDao.xml映射文件并配置查询信息
3.创建RoleDaoTest测试类并测试查询方法
3.3.2 需求2查询用户信息以及该用户对应的所有角色信息
实现步骤
代码示例
/**
* 需求1查询角色信息以及该角色对应的所有用户信息
*/
ListRole findAll();
}
namespacecom.itheima.dao.IRoleDao
idroleMap typerole
columnrid propertyid/
columnROLE_NAME propertyroleName/
columnROLE_DESC propertyroleDesc/
propertyusers javaTypejava.util.List ofTypeuser
columnid propertyid/
columnusername propertyusername/
columnbirthday propertybirthday/
columnsex propertysex/
columnaddress propertyaddress/
idfindAll resultMaproleMap SELECT r.ID rid,r.ROLE_NAME,r.ROLE_DESC,u.* FROM role r LEFT JOIN user_role ur ON r.ID ur.RID LEFT JOIN user u ON ur.UID u.id
Test
public void testFindAll(){
ListRole roles roleDao.findAll();
for (Role role : roles) {
System.out.println(role);
}
}
1.在实体类User中添加ListRole roles属性并在IUserDao中添加新的查询方法
2.在IUserDao.xml中重新配置查询语句
3.在UserDaoTest测试类进行测试1.在IUserDao中添加新的查询方法
2.在IUserDao.xml中重新配置查询语句
3.在UserDaoTest测试类进行测试
4.补充JNDI
mybatis第四天
1.mybatis延迟加载
1.1 概念
/**
* 需求2查询用户信息以及该用户对应的所有角色信息
*/
ListUser findAllUserAndRole();
iduserRoleMap typeuser
columnid propertyid/
columnusername propertyusername/
columnbirthday propertybirthday/
columnsex propertysex/
columnaddress propertyaddress/
propertyroles javaTypejava.util.List ofTyperole
columnrid propertyid/
columnROLE_NAME propertyroleName/
columnROLE_DESC propertyroleDesc/
idfindAllUserAndRole resultMapuserRoleMap SELECT u.*,r.ID rid,r.ROLE_NAME,r.ROLE_DESC FROM user u LEFT JOIN user_role ur ON u.id ur.UID LEFT JOIN role r ON ur.RID r.ID;
Test
public void testFindAllUserAndRole(){
ListUser users userDao.findAllUserAndRole();
for (User user : users) {
System.out.println(user);
}
}1.2 一对一实现延迟加载
1.2.1 在主配置文件SqlMapConfifig.xml中开启全局延迟加载
1.2.2 在映射配置文件IAccountDao.xml中配置延迟加载查询
1.2.3 在AccountDaoTest测试类中进行测试
1.3 一对多实现延迟加载
1.3.1 在映射配置文件IUserDao.xml中配置延迟加载查询
1.立即加载只要一调用方法不管用不用的到数据都立马去关联查询
2.延迟加载只有再用到数据时才去关联查询不用就不关联查询好处先从单表查询需要时再从关联表去关联查
询大大提高数据库性能延迟加载也叫按需加载或懒加载 namelazyLoadingEnabled valuetrue/
nameaggressiveLazyLoading valuefalse/
idaccountMap typeaccount
columnid propertyid/
columnuid propertyuid/
columnmoney propertymoney/
propertyuser javaTypeuser columnuid
selectcom.itheima.dao.IUserDao.findById/
idfindAll resultMapaccountMap select * FROM account
/**
* 延迟加载查询所有账号信息同时查询对应用户信息
*/
Test
public void testFindAll() {
ListAccount accounts accountDao.findAll();
/*只要不调用和user相关的方法就不会查关联表中的数据*/
for (Account account : accounts) {
System.out.println(account.getId(),account.getUid(),account.getMoney());
}
}1.3.2 在IAccountDao中添加fifindAccountById方法并在IAccountDao.xml配置
1.3.3 在UserDaoTest测试类中进行测试
2.mybatis中的一级缓存和二级缓存
2.1 缓存的概念
2.2 一级缓存
概念
iduserMap typeuser
columnid propertyid/
columnusername propertyusername/
columnbirthday propertybirthday/
columnsex propertysex/
columnaddress propertyaddress/
propertyaccounts ofTypeaccount
selectcom.itheima.dao.IAccountDao.findAccountById columnid/
idfindAll resultMapuserMap SELECT * FROM USER ;
idfindAccountById parameterTypeint resultTypeaccount SELECT * FROM account where uid#{uid};
Test
public void testFindAll() {
ListUser list userDao.findAll();
for (User u : list) {
System.out.println(u.getId(),u.getUsername(),u.getBirthday(),u.getSex(),u.getAd
dress());
/*只要不调用和account相关的方法就不会查关联表中的数据*/
/*System.out.println(u.getAccounts());*/
}
}
存在内存中的临时数据就是缓存代码演示
结果说明
2.3 二级缓存
概念
代码演示
它指的是Mybatis中SqlSession对象的缓存。当我们执行查询之后查询的结果会同时存入到SqlSession为我们
提供一块区域中。该区域的结构是一个Map。当我们再次查询同样的数据mybatis会先去sqlsession中查询是否有有
的话直接拿出来用。当SqlSession对象消失时close方法被调用mybatis的一级缓存也就消失了。
Test
public void testFirstLeverCache(){
User user1 userDao.findById(43);
System.out.println(user1 user1);
//测试一下关闭session
/*session.close();
sessionfactory.openSession(true);
userDaosession.getMapper(IUserDao.class);*/
//也可以清除缓存
//session.clearCache();
//再次执行相同的查询
User user2 userDao.findById(43);
System.out.println(user2 user2);
//判断user1和user2是不是同一个对象
System.out.println(user1user2 : (user1user2));
}
如果是同一个session对象那么第二次查询的user对象和第一次查询的user对象是同一个user对象最后打印的
结果是true通过控制台日志可以看出只执行了一次查询当中间关闭了session或者调用clearCache方法清除缓存之
后那两个user对象就不是同一个对象了控制台查看日志也会发现执行了两次查询。
它指的是Mybatis中SqlSessionFactory对象的缓存。由同一个SqlSessionFactory对象创建的SqlSession共享
其缓存。
二级缓存的使用步骤
第一步让Mybatis框架支持二级缓存在SqlMapConfig.xml中配置
第二步让当前的映射文件支持二级缓存在IUserDao.xml中配置
第三步让当前的操作支持二级缓存在select标签中配置
Test
public void testSecondLeverCache(){
//1.获取第一个sqlSession对象并查询user
SqlSession session1 factory.openSession(true);
IUserDao userDao1 session1.getMapper(IUserDao.class);
User user1 userDao1.findById(43);结果说明以及注意事项
3.mybatis注解开发
3.1 mybatis注解开发CRUD操作
3.1.1 SqlMapConfifig核心配置文件环境搭建
System.out.println(user1 user1);
//关闭session1
session1.close();
//2.获取第二个sqlSession对象并查询user
SqlSession session2 factory.openSession(true);
IUserDao userDao2 session2.getMapper(IUserDao.class);
User user2 userDao2.findById(43);
System.out.println(user2 user2);
session2.close();
//判断user1和user2是不是同一个对象
System.out.println(user1user2 : (user1user2));
}
两个对象虽然不是同一个对象但是通过控制台发现只执行了一次查询
注意一定要关闭之前的sqlSession对象
PUBLIC -//mybatis.org//DTD Config 3.0//EN
http://mybatis.org/dtd/mybatis-3-config.dtd resourcejdbcConfig.properties/ namecom.itheima.domain/
defaultmysql
idmysql
typejdbc
typepooled
namedriver value${jdbc.driver}/
nameurl value${jdbc.url}/
nameusername value${jdbc.username}/
namepassword value${jdbc.password}/ namecom.itheima.dao/
3.1.2 IUserDao中给方法添加注解
/**
* 查询所有操作
* return
*/
Select(select * from user)
ListUser findAll();
/**
* 保存用户
* param user
* return 影响数据库记录的行数
*/
Insert(insert into user values(null,#{username},#{birthday},#{sex},#{address}))
//配置SelectKey将新添加用户的id封装到user中
SelectKey(keyColumn id,keyProperty id,resultType int.class,before false, statement
select last_insert_id())
int saveUser(User user);
/**
* 更新用户
* param user
* return 影响数据库记录的行数
*/
Update(update user set username#{username},birthday#{birthday},sex#{sex},address#{address}
where id#{id})
int updateUser(User user);
/**
* 根据 id 删除用户
* param id
* return 影响数据库记录的行数
*/
Delete(delete from user where id#{id})
int deleteUser(int id);
/**
* 根据 id 查询
* param id
* return
*/
Select(select * from user where id#{id})
User findById(Integer id);
/**
* 根据名称模糊查询
* param username
* return
*/
Select(select * from user where username LIKE #{username};)
ListUser findByName(String username);
/**3.1.3 在测试类中测试
* 查询总记录条数
* return 总记录条数
*/
Select(select count(*) from user;)
int findTotal();
/**
* 根据 QueryVo 中的条件查询用户
* param vo
* return
*/
Select( select * from user where username like #{user.username})
ListUser findByVo(QueryVo vo);
private InputStream is;
private SqlSession session;
private IUserDao userDao;
private SqlSessionFactory factory;
Before
public void init() throws IOException {
//1.获取主配置文件输入流
is Resources.getResourceAsStream(SqlMapConfig.xml);
//2.创建SqlSessionFactory工厂对象
factory new SqlSessionFactoryBuilder().build(is);
//3.创建核心SqlSession对象
session factory.openSession(true);
//4.获取IAccountDao代理对象
userDao session.getMapper(IUserDao.class);
}
//查询所有操作
Test
public void findAll(){
ListUser users userDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
//保存用户
Test
public void saveUser(){
//创建用户信息
User usernew User();
user.setUsername(老周);
user.setBirthday(new Date());
user.setAddress(武汉);
user.setSex(男);
System.out.println(添加前user user);
//添加到数据
int row userDao.saveUser(user);
System.out.println(影响的行数row row);System.out.println(添加后user user);
}
//更新用户
Test
public void updateUser(){
//准备要修改用户的信息信息
User usernew User();
user.setId(55);
user.setUsername(老李);
user.setBirthday(new Date());
user.setAddress(孝感);
user.setSex(女);
//修改用户
int row userDao.updateUser(user);
System.out.println(row row);
}
//根据 id 删除用户
Test
public void deleteUser(){
//根据id删除用户信息
int row userDao.deleteUser(55);
System.out.println(row row);
}
//根据 id 查询
Test
public void findById(){
User user userDao.findById(50);
System.out.println(user);
}
//根据名称模糊查询
Test
public void findByName(){
ListUser users userDao.findByName(%王%);
for (User user : users) {
System.out.println(user);
}
}
//查询总记录条数
Test
public void findTotal(){
int total userDao.findTotal();
System.out.println(total total);
}
//根据 QueryVo 中的条件查询用户
Test
public void findByVo(){
//创建QueryVo对象
QueryVo queryVonew QueryVo();
//创建模糊查询条件封装到user对象中
User usernew User();
user.setUsername(%王%);
queryVo.setUser(user);
//执行查询3.2 mybatis注解开发实例类属性与表列名不一致
3.2.1 IUserDao中给方法添加注解
3.2.2 在测试类中测试
3.3 mybatis注解开发一对一/多查询
3.3.1 IUserDao中给方法添加注解
ListUser users userDao.findByVo(queryVo);
//遍历打印
for (User u : users) {
System.out.println(u);
}
}
After
public void destroy() throws IOException {
session.close();
is.close();
}
/**
* 使用别名查询所有用户信息;
* return 所有用户信息
*/
Select(select * from user)
//iduMap表示结果集映射的id将来可以给其他ResultMap复用
Results(iduMap,value {
//idtrue表示是主键默认值是false
Result(idtrue,column id,property userId),
Result(idfalse,column username,property userName),
Result(column birthday,property userBirthday),
Result(column sex,property userSex),
Result(column address,property userAddress)
}
)
ListU findAllU();
Test
public void findAllU(){
ListU us userDao.findAllU();
//遍历打印
for (U u : us) {
System.out.println(u);
}
}
/**3.3.2 IAccountDao中创建fifindAccountById方法并添加注解
3.3.3 在测试类中测试
* 立即查询查询账户信息的同时查询其用户信息
* return
*/
Select(select * from account)
Results(idaccountMap,value {
Result(id true,column id,property id),
Result(column uid,property uid),
Result(column money,property money),
Result(column uid,property user,one One(
selectcom.itheima.dao.IUserDao.findById,
fetchType FetchType.EAGER//立即查询
)),
})
ListAccount findAllAccountAndUser();
/**
* 延时查询查询用户信息的同时查询其所有账户信息
*/
Select(select * from user)
Results(iduserMap,value {
Result(idtrue,column id,property id),
Result(column username,property username),
Result(column birthday,property birthday),
Result(column sex,property sex),
Result(column address,property address),
Result(column id,property accounts,many Many(
selectcom.itheima.dao.IAccountDao.findAccountById,
fetchType FetchType.LAZY//延时查询
)),
})
ListUser findAllUserAndAccount();
public interface IAccountDao {
/**
* 根据uid查询对应的所有账户信息
* param uid
* return
*/
Select(select * from account where uid#{uid})
ListAccount findAccountById(int uid);
}
//立即查询查询账户信息的同时查询其用户信息
Test
public void findAllAccountAndUser(){
ListAccount accounts userDao.findAllAccountAndUser();
//变量打印3.4 mybatis注解开发使用二级缓存
3.4.1 在被测试的dao类上添加注解开启二级缓存即可
注意SqlMapConfifig.xml中的中的
cacheEnabled默认值就是true可以不用配置。
3.4.2 代码测试
mybatis扩展内容
for (Account account : accounts) {
System.out.println(account.getId()-account.getUid()-account.getMoney());
System.out.println(account.getUser());
}
}
//延时查询查询用户信息的同时查询其所有账户信息
Test
public void findAllUserAndAccount(){
ListUser users userDao.findAllUserAndAccount();
for (User u : users) {
System.out.println(u.getId()-u.getUsername()-u.getBirthday()-u.getSex()-
u.getAddress());
// System.out.println(u.getAccounts());
}
}
//该接口查询开启二级缓存
CacheNamespace(blocking true)
public interface IUserDao {}
//测试二级缓存
Test
public void testSecondLeverCache(){
//1.获取第一个sqlSession对象并查询user
SqlSession session1 factory.openSession(true);
IUserDao userDao1 session1.getMapper(IUserDao.class);
User user1 userDao1.findById(43);
System.out.println(user1 user1);
//关闭session1
session1.close();
//2.获取第二个sqlSession对象并查询user
SqlSession session2 factory.openSession(true);
IUserDao userDao2 session2.getMapper(IUserDao.class);
User user2 userDao2.findById(43);
System.out.println(user2 user2);
session2.close();
//判断user1和user2是不是同一个对象
System.out.println(user1user2 : (user1user2));
}1.mybatis使用第三方连接池
1.1 mybatis中连接池原理
1.2 使用第三方连接池步骤
1.2.1 自定义工厂类实现mybatis的DataSourceFactory接口
MyBatis 在初始化时根据dataSource的 type 属性来创建相应类型的的数据源 DataSource即
typePOOLED MyBatis 会创建 PooledDataSource 实例
typeUNPOOLED MyBatis 会创建 UnpooledDataSource 实例
typeJNDI MyBatis 会从 JNDI 服务上查找 DataSource 实例然后返回使用
当我们在dataSource typePOOLED配置POOLED时mybatis就会为我们创建PooledDataSource对象这个对象是
通过连接池工程创建出来的
public class PooledDataSourceFactory extends UnpooledDataSourceFactory {
public PooledDataSourceFactory() {
this.dataSource new PooledDataSource();
}
}
public class UnpooledDataSourceFactory implements DataSourceFactory {
//代码省略
}
public interface DataSourceFactory {
void setProperties(Properties props);
DataSource getDataSource();
}
mybatis创建PooledDataSourceFactory工厂对象的同时会创建一个PooledDataSource连接池对象然后调用工
厂对象的setProperties(Properties props)方法将SqlMapConfig.xml中的连接池配置信息通过props传递进来当
进行CRUD操作时就调用getDataSource()方法获取连接池对象。
也就是说要想让mybatis使用第三方连接池我们就得自己定义一个工厂类在工厂来中创建第三方连接池对象并
在setProperties(Properties props)方法中设置连接参数在getDataSource()方法中返回连接池对象
package com.itheima.factory;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.datasource.DataSourceFactory;
import javax.sql.DataSource;
import java.util.Properties;
//DruidDataSourceFactory不是alibaba的DruidDataSourceFactory
public class DruidDataSourceFactory implements DataSourceFactory {
//声明连接池对象
private DruidDataSource dataSource;
public DruidDataSourceFactory() {
//创建连接池对象
this.dataSource new DruidDataSource();
}
Override
public void setProperties(Properties props) {
//将SqlMapConfig.xml中的连接池配置信息设置给druid连接池对象
dataSource.setDriverClassName(props.getProperty(driver));1.2.2 在SqlMapConfifig.xml中使用第三方连接池
1.2.3 在测试类中进行测试
dataSource.setUrl(props.getProperty(url));
dataSource.setUsername(props.getProperty(username));
dataSource.setPassword(props.getProperty(password));
}
Override
public DataSource getDataSource() {
return dataSource;
}
}
PUBLIC -//mybatis.org//DTD Config 3.0//EN
http://mybatis.org/dtd/mybatis-3-config.dtd resourcejdbcConfig.properties/ namecom.itheima.domain/
defaultmysql
idmysql
typejdbc
typecom.itheima.factory.DruidDataSourceFactory
namedriver value${jdbc.driver}/
nameurl value${jdbc.url}/
nameusername value${jdbc.username}/
namepassword value${jdbc.password}/ namecom.itheima.dao/
2.mybatis查询传递其他类型参数
2.1 参数是Map集合
在IUserDao.xml中配置查询信息
在测试类中测试
//查询所有操作
Test
public void findAll(){
//获取连接池对象的名称
DataSource dataSource session.getConfiguration().getEnvironment().getDataSource();
System.out.println(dataSource dataSource.getClass());//dataSource class
com.alibaba.druid.pool.DruidDataSource
//查询所有用户信息
ListUser users userDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
idfindUserByMap resultTypeuser select * from USER testusername!null and username! and username like #{username} testsex!null and username! and sex #{sex}
//动态sql根据map集合中的条件查询用户信息
Test
public void testFindUserByMap(){
//创建Map集合并封装查询参数
MapString,Object mapnew HashMapString,Object();
map.put(username,%王%);
map.put(sex,女);
//查询符合条件的用户信息
ListUser users userDao.findUserByMap(map);
for (User user : users) {
System.out.println(user);
}
}结论使用map集合或者javabean对象作为参数其实是一样的map集合对应的就是javabean的属性。
2.2 参数是List集合
在IUserDao.xml中配置查询信息
在测试类中测试
结论mybatis其实是将参数list集合先存到map中key为list(即map.pust(list,list集合对象))所以
collectionlist中的属性值必须是list,就相当于从map中取出list遍历
2.3 参数是数组- 和参数是list几乎一样
在IUserDao.xml中配置查询信息
idfindUserByList resultTypeuser SELECT * FROM USER and id in( collectionlist itemid separator, #{id} )
//动态sql查询list集合中指定id的user信息
Test
public void testFindUserByList(){
//创建list集合并存储要查的用户id
ListInteger idsnew ArrayListInteger();
ids.add(41);
ids.add(43);
ids.add(48);
ids.add(50);
//查询符合条件的用户信息
ListUser users userDao.findUserByList(ids);
for (User user : users) {
System.out.println(user);
}
}在测试类中测试
结论查询参数是Array与查询参数是list集合的原理是一样的都是现将对象存到map集合中只不过参数
为Array时存到map集合中的key叫array所以collectionarray的值必须是array
2.4 多个参数情况以及Param注解
在IUserDao中定义查询方法
在IUserDao.xml中配置查询信息
idfindUserByArray resultTypeuser SELECT * FROM USER and id in( collectionarray itemid separator, #{id} )
//动态sql查询数组中指定id的user信息
Test
public void testFindUserByArray(){
//创建list集合并存储要查的用户id
Integer[] ids{41,43,48,50};
//查询符合条件的用户信息
ListUser users userDao.findUserByArray(ids);
for (User user : users) {
System.out.println(user);
}
}
/**
* 多个参数根据用户名和性别查询用户信息
* Param(username) :定义参数的别名将来在映射文件中使用
*/
public ListUser findUserByUsernameAndSex(Param(username) String username,Param(sex)
String sex);
}
idfindUserByUsernameAndSex resultTypeuser SELECT * FROM USER where username like #{username} and sex #{sex} 在测试类中测试
结论最好是结果Param注解一起使用映射文件中#{username}使用的变量名就是 Param(username)注解的参数值 3.mybatis注解开发-动态sql 3.1 方式1在select注解中添加script脚本 在在IUserMapper方法上定义注解 测试类测试 /** * 多个参数根据用户名和性别查询用户信息 */ Test public void testFindUserByUsernameAndSex(){ ListUser users userDao.findUserByUsernameAndSex(%王%, 女); for (User user : users) { System.out.println(user); } } /** * 动态sql查询list集合中指定id的user信息 */ Select({}) public ListUser findUserByList(ListInteger ids); //动态sql查询list集合中指定id的user信息 Test public void testFindUserByList(){ //创建list集合并存储要查的用户id ListInteger idsnew ArrayListInteger(); ids.add(41); ids.add(43); ids.add(48); ids.add(50);总结其实就是将xml映射文件中的配置拿过来用了也是支持的。适用于带in的查询 3.1 方式2字符串拼接了解 定义sql提供者UserMapperProvider类 在IUserMapper方法上定义注解 测试类测试 //查询符合条件的用户信息 ListUser users userMapper.findUserByList(ids); for (User user : users) { System.out.println(user); } } /** * 为注解开发动态sql查询提供sql */ public class UserMapperProvider { /** * 动态sql根据map集合中的条件查询用户信息 * param map 查询条件 * return 根据条件返回sql */ public String findUserByMap(MapString,Object map){ StringBuilder sbnew StringBuilder(select * from user where 11 ); if(map.get(username)!null){ sb.append( and username like #{username}); } if(map.get(sex)!null){ sb.append( and sex #{sex}); } return sb.toString(); } } public interface IUserMapper { /** * 动态sql根据map集合中的条件查询用户信息 */ SelectProvider(typeUserMapperProvider.class,method findUserByMap) public ListUser findUserByMap(MapString,Object map); }3.2 方式3使用mybatis中提供的SQL对象动态构建sql语句 修改UserMapperProvider提供者中的fifindUserByMap方法 4.mybatis使用Redis做二级缓存 总结 使用xml配置完成CURD操作 环境 jar包坐标 //动态sql根据map集合中的条件查询用户信息 Test public void testFindUserByMap(){ //创建Map集合并封装查询参数 MapString,Object mapnew HashMapString,Object(); map.put(username,%王%); map.put(sex,女); //查询符合条件的用户信息 ListUser users userMapper.findUserByMap(map); for (User user : users) { System.out.println(user); } } public String findUserByMap(MapString,Object map){ return new SQL(){ //静态代码块 { SELECT(*); FROM(user); if (map.get(username)!null) { WHERE(username like #{username}); } if (map.get(sex)!null) { AND(); WHERE(sex #{sex}); } } }.toString(); } 配置文件 单表查询 org.mybatis mybatis 3.4.5 mysql mysql-connector-java 5.1.38 junit junit 4.10 log4j log4j 1.2.12 测试多表查询 一对多 多表查询 多对多 使用annotation完成CURD操作 环境 与xml相同 单表查询多表查询 一对多