mybatis

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

*/

List<User> findAll();

}

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

 

default="mysql">

id="mysql">

type="jdbc">

type="pooled">

name="driver" value="com.mysql.jdbc.Driver"/>

name="url" value="jdbc:mysql://localhost:3306/mybatis"/>

name="username" value="root"/>

name="password" value="78910J"/>

 

resource="com/itheima/dao/IUserDao.xml">

5.注意事项

6.测试类中测试方法编写

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

namespace="com.itheima.dao.IUserDao">//namespace:接口的路径 定位类中方法的具体位置

id="findAll" resultType="com.itheima.domain.User"> SELECT * FROM USER

1.resource中创建IUserDao.xml时,文件的位置必须和IUserDao包结构相同,创建IUserDao.xml所在目录结

构时要一级一级创建。

2.映射配置文件中的mappernamespace属性值必须是IUserDao的全类名

3.执行sql操作的配置id属性必须是执行方法的名词,例如 <select id="findAll"

@Test

public void testFindAll() throws IOException {

//1.读取SqlMapConfig.xml配置文件

InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

//2.创建SqlSessionFactory工厂类

SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();

SqlSessionFactory factory = builder.build(is);

//3.使用SqlSessionFactory工厂创建SqlSession核心对象

/*SqlSessionFactoryMyBatis的关键对象,它是个单个数据库映射

关系经过编译后的内存镜像.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.执行查询方法

List<User> 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 class="com.itheima.dao.IUserMapper"/>

mappers>

2.定义接口和抽象方法,在抽象方法上添加对应的注解:

public interface IUserMapper {

/**

* 查询所有用户信息

*/

@Select("select * from user")

public List<User> findList();

}

3.进行测试:

@Test

public void testFindList() throws IOException {

//1.读取核心配置文件

InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

//2.创建SqlSessionFactory工厂类

SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();

SqlSessionFactory factory = builder.build(is);

//3.创建SqlSession核心对象

SqlSession session = factory.openSession();

//4.获取dao代理对象

IUserMapper mapper = session.getMapper(IUserMapper.class);

//5.执行查询操作

List<User> 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 List<User> 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

List<User> 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 builder=new SqlSessionFactoryBuilder();

SqlSessionFactory factory = builder.build(is);

//3.创建实现类对象并调用实现类方法查询所有用户信息

UserDaoImpl dao=new UserDaoImpl(factory);

List<User> users = dao.findAll();

//4.遍历输出

for (User user : users) {

System.out.println(user);

}

//4.释放资源

is.close();

}

 

resource="com/itheima/dao/IUserDao.xml"/>

class="com.itheima.dao.IUserDao"/>

完成SqlSessionFactoryBuilderSqlSessionFactory接口实现类、SqlSession接口实现类功能(实现类要自

己创建)

SqlSessionFactoryBuilder代码实现

1.添加依赖:

<dependency>

<groupId>dom4jgroupId>

<artifactId>dom4jartifactId>

<version>1.6.1version>

dependency>

<dependency>

<groupId>jaxengroupId>

<artifactId>jaxenartifactId>

<version>1.1.6version>

dependency>

2.创建ConfigurationMapper两个javabean对象

public class Configuration {

private String driver;

private String url;

private String username;

private String password;

private Map<String,Mapper> mappers=new HashMap<String, Mapper>();//保存多组映射信息的map

// getter/setter方法省略

public void setMappers(Map<String, 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.configuration=configuration;

}

/**

* 生产操作数据库的核心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.configuration=configuration;

//从连接池工具类中获取连接对象

conn= DataSourceUtils.getConnection(configuration);

}

/**

* 通过动态代理的方式创建接口的实现类对象

* @param daoClass 接口的Class对象

* @param 返回接口实现类对象

* @return

*/

public <T> T getMapper(Class<T> 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 Map<String, Mapper> mappers;//封装了sql语句和结果类型

private Connection conn;//连接对象

public MapperProxy(Map<String, Mapper> mappers,Connection conn) {

this.mappers=mappers;

this.conn=conn;

}

//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.mybatisCRUD操作

1.1.映射配置文件IUserDao.xml信息

String methodName = method.getName();

//1.2.获取全类名

String className = method.getDeclaringClass().getName();

//1.3.拼接map集合的key,找到对应的mapper对象

String key=className+"."+methodName;

System.out.println("key = " + key);

//1.4.找到要的Mapper对象

Mapper mapper = mappers.get(key);

if (mapper==null) {

//没找到,配置的全类名有误或者方法有误

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">

namespace="com.itheima.dao.IUserDao">

id="findAll" resultType="com.itheima.domain.User"> SELECT * from user

id="saveUser" parameterType="com.itheima.domain.User">

/*添加用户信息之后查询新用户的id keyProperty对应的是userid属性*/

keyColumn="id" keyProperty="id" resultType="int" order="AFTER">

select last_insert_id();

/*selectKey是后来加的,在添加用户信息时可以先忽略*/

insert into user values (null,#{username},#{birthday},#{sex},#{address})

id="updateUser" parameterType="com.itheima.domain.User">1.2.封装数据的User类省略

1.3.测试类代码

update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}

where id=#{id}

id="deleteUser" parameterType="Integer">

delete from user where id=#{id}

id="findById" resultType="com.itheima.domain.User" parameterType="int"> select * FROM user where id=#{id}

id="findByName" parameterType="String" resultType="com.itheima.domain.User"> select * from user where username like #{username}

id="findTotal" resultType="int"> 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 builder=new SqlSessionFactoryBuilder();

SqlSessionFactory factory = builder.build(is);

//3.创建核心SqlSession对象

session = factory.openSession();

//4.创建IUserDao对象

userDao = session.getMapper(IUserDao.class);

}

/**

* 测试查询所有用户信息的findAll()方法

*/

@Test

public void testFindAll(){

List<User> users = userDao.findAll();

//遍历打印

for (User user : users) {System.out.println(user);

}

}

/**

* 测试保存用户信息的saveUser()方法

*/

@Test

public void testSaveUser(){

//创建用户信息

User user=new 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并封装到userid属性上。

System.out.println("添加后user = " + user);

}

/**

* 测试更新用户信息的updateUser()方法

*/

@Test

public void testUpdateUser(){

//准备要修改用户的信息信息

User user=new 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(){

List<User> 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;

}

}测试类测试方法编写

mybatisdao层开发模式

返回值类型-javabean的属性和表字段名一致情况(了解)

javabean实体类

id="findByVo" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User"> /*username是user的属性,user是QueryVo的属性*/ select * from user where username like #{user.username}

/**

* 测试根据 QueryVo 中的条件查询用户的findByVo()方法

*/

@Test

public void testFindByVo(){

//创建QueryVo对象

QueryVo queryVo=new QueryVo();

//创建模糊查询条件封装到user对象中

User user=new User();

user.setUsername("%%");

queryVo.setUser(user);

//执行查询

List<User> users = userDao.findByVo(queryVo);

//遍历打印

for (User u : users) {

System.out.println(u);

}

}

* 基于DAO代理方式(推荐使用)

* CRUD操作(保存操作|修改操作|删除操作|查询一个|模糊查询|单值查询|获取保存对象的id)

* 模糊查询需要注意

* 获取保存对象的id

* 输入参数 parameterType属性

* 输入参数的类型:intstringUserplain old java object、包装类型ValueObject

* 输出参数 resultType属性、

* 输入参数的类型:Userintstring

* 解决实体类属性和数据库列名不对应

* sql语句上取别名, 对应, 简单

* 通过resultMap属性来映射java对象和数据库列名之间的关系

* <result property="userName" column="username">result>

property 遵循的是驼峰规则; column 单词下划线隔开解决办法1sql的结果集使用别名,别名和javabean的属性一致

好处:查询效率高;弊端:书写麻烦,开发效率低。

解决办法2:使用mybatis给我们提供的配置结果集映射

好处:id="UMap"可以重复使用,开发效率高;弊端:查询效率略低。

编写测试类测试方法

public class U {

private Integer userId;

private String userName;

private Date userBirthday;

private String userSex;

private String userAddress;

//自动生成settergettertoString省略,此时属性和表的字段名不一致

}

id="findAllU" resultType="com.itheima.domain.U"> select id userId,username userName,birthday userBirthday,sex userSex,address userAddress from user;

id="UMap" type="com.itheima.domain.U">

column="id" property="userId"/>

column="username" property="userName"/>

column="birthday" property="userBirthday"/>

column="sex" property="userSex"/>

column="address" property="userAddress"/>

id="findAllU" resultMap="UMap"> select * from user; 3.mybatis中编写dao实现类的使用(了解)

UserDaoImpl实现类代码

/**

* 测试使用别名,查询所有用户信息的findAllU()方法

*/

@Test

public void testFindAllU(){

List<U> 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 List<User> findAll() {

//1.创建核心的SqlSession对象

SqlSession session = factory.openSession();

//2.调用selectList方法查询所有用户信息

List<User> 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 List<User> findByName(String username) {

//1.创建核心的SqlSession对象

SqlSession session = factory.openSession();

//2.调用selectList方法根据username模糊查询所有用户信息

List<User> 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 List<User> 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标签的作用

List<User> users =

session.selectList("com.itheima.dao.IUserDao.findByName",vo.getUser().getUsername());

//3.释放资源

session.close();

return users;

}

@Override

public List<U> findAllU() {

//1.创建核心的SqlSession对象

SqlSession session = factory.openSession();

//2.调用selectList方法查询所有用户信息

List<U> 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 builder=new SqlSessionFactoryBuilder();

SqlSessionFactory factory = builder.build(is);

/*如果是使用dao代理方式,则需要创建SqlSession对象,并获取dao的代理对象*/

/*//3.创建核心SqlSession对象

session = factory.openSession();

//4.创建IUserDao对象

userDao = session.getMapper(IUserDao.class);*/

/*如果使用的是自定义dao实现类方法,则需要创建dao实现类对象,并传递factory工厂对象*/

userDao=new 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.driver=com.mysql.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=Asia/Shanghai

jdbc.username=root

jdbc.password=78910J

 

name="driver" value="com.mysql.jdbc.Driver"/>

name="url" value="jdbc:mysql://localhost:3306/mybatis?

serverTimezone=Asia/Shanghai"/>

name="username" value="root"/>

name="password" value="78910J"/>

或者

resource="jdbcConfig.properties">

或者

url="

file:///D:/IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.prop

erties">

type="pooled">

name="driver" value="${jdbc.driver}"/>

name="url" value="${jdbc.url}"/>

name="username" value="${jdbc.username}"/>

name="password" value="${jdbc.password}"/>

typeAliases标签下使用package标签作用 :指定包下的所有javabean的类名就是其别名,不区分大小写

(实用)

Mappers标签下使用package标签作用 :不用写mapper标签,resourcesclass指定包下所有dao对应的

映射文件都不用引入了,并且可以找到dao的接口或者dao接口对应的配置。(实用)

mybatis第三天

1.mybatis中连接池以及事务管理

1.1 mybatis连接池

mybatis中三种数据源介绍

sqlMapConfifig.xml中配置

 

type="com.itheima.domain.User" alias="user"/>

 

 

name="com.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 1=1

IUserDao.xml中修改之前配置的查询语句

sqlMapConfig.xml中配置如下

type="pooled">

name="driver" value="${jdbc.driver}"/>

name="url" value="${jdbc.url}"/>

name="username" value="${jdbc.username}"/>

name="password" value="${jdbc.password}"/>

MyBatis 在初始化时,根据type 属性来创建相应类型的的数据源 DataSource,即:

type="POOLED"MyBatis 会创建 PooledDataSource 实例

type="UNPOOLED"MyBatis 会创建 UnpooledDataSource 实例

type="JNDI"MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用

id="findUserByCondition1" parameterType="user" resultType="user"> select * from user where 1=1 test="username!=null and username!=''">//连接判断条件不能为&&和|| and username = #{username} test="sex!=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集合

id="findUserByCondition1" parameterType="user" resultType="user"> select * from user test="username!=null and username!=''"> and username = #{username} test="sex!=null"> and sex = #{sex} 需求:根据qvlist集合查询用户信息-

IUserDao.xml中配置查询语句

测试类中测试- QueryVo中添加ids属性省略了

id="findByMap" parameterType="map" resultType="cn.itcast.mybatis.pojo.Product"> select * from user collection="_parameter" index="key" item="value" separator="and"> test="value !=null"> ${key} = #{value}

id="findUserByCondition2" parameterType="QueryVo" resultType="user"> select * from user test="ids!=null and ids.size>0"> id="findUserByCondition2" parameterType="QueryVo" resultType="user">

select * from user

 

test="ids!=null and ids.size>0">

and id in(

collection="ids" item="uid" separator=",">

#{uid}

)

@Test

public void testFindUserByCondition2(){

QueryVo qv=new QueryVo();

List<Integer> ids=new ArrayList<Integer>();

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); List<User> list = userDao.findUserByCondition2(qv); //变量展示 for (User u : list) { System.out.println("u = " + u); } } id="selectTemplate"> select * from user id="findAll" resultType="com.itheima.domain.User">

refid="selectTemplate"/>

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;

//settergettertoString方法省略

}

public interface IAccountDao {

/**

* 查询所有账号信息同时查询对应用户信息

* @return

*/

List<Account> findAll();

}

namespace="com.itheima.dao.IAccountDao">

id="accountUserMap" type="account">

column="aid" property="id"/>

column="uid" property="uid"/>

column="money" property="money"/>

property="user" javaType="user" column="uid">

column="id" property="id"/>

column="username" property="username"/>

column="birthday" property="birthday"/>

column="sex" property="sex"/>

column="address" property="address"/>

id="findAll" resultMap="accountUserMap"> /*注意:当多表查询结果有相同字段名时,我们需要取别名区分*/ SELECT u.*,a.id aid,a.UID,a.MONEY FROM user u,account a where u.id=a.UID;

@Test

public void testFindAll(){

//1.调用findAll方法

List<Account> list = accountDao.findAll();

//2.遍历打印结果

for (Account account : list) {

System.out.println(account);

}

}注意:当多表查询结果有相同字段名时,我们需要取别名区分

3.2 一对多关系

需求:一个用户有多个账户,查询用户信息的同时查询其所有账户信息

实现步骤

一对多映射

代码示例

IUserDao中添加新的查询方法

IUserDao.xml中重新配置查询语句

编写UserTest测试类进行测试

1.user中添加List<Account> accounts属性,在IUserDao中添加新的查询方法

2.IUserDao.xml中重新配置查询语句

3.AccountDaoTest测试类进行测试

/**

* 多表查询:查询用户信息的同时查询其所有账户信息

* @return

*/

List<User> findAllUserAndAccount();

id="userAccountMap" type="user">

column="id" property="id"/>

column="username" property="username"/>

column="birthday" property="birthday"/>

column="sex" property="sex"/>

column="address" property="address"/>

property="accounts" javaType="java.util.List" ofType="account">

column="id" property="id"/>

column="uid" property="uid"/>

column="money" property="money"/>

id="findAllUserAndAccount" resultMap="userAccountMap"> 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(){

List<User> 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 List<User> users;

//settergettertoString方法省略

}

public interface IRoleDao {2.创建IRoleDao.xml映射文件,并配置查询信息

3.创建RoleDaoTest测试类,并测试查询方法

3.3.2 需求2:查询用户信息以及该用户对应的所有角色信息

实现步骤

代码示例

/**

* 需求1:查询角色信息以及该角色对应的所有用户信息

*/

List<Role> findAll();

}

namespace="com.itheima.dao.IRoleDao">

id="roleMap" type="role">

column="rid" property="id"/>

column="ROLE_NAME" property="roleName"/>

column="ROLE_DESC" property="roleDesc"/>

property="users" javaType="java.util.List" ofType="user">

column="id" property="id"/>

column="username" property="username"/>

column="birthday" property="birthday"/>

column="sex" property="sex"/>

column="address" property="address"/>

id="findAll" resultMap="roleMap"> 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(){

List<Role> roles = roleDao.findAll();

for (Role role : roles) {

System.out.println(role);

}

}

1.在实体类User中添加List<Role> roles属性,并在IUserDao中添加新的查询方法

2.IUserDao.xml中重新配置查询语句

3.UserDaoTest测试类进行测试1.IUserDao中添加新的查询方法

2.IUserDao.xml中重新配置查询语句

3.UserDaoTest测试类进行测试

4.补充:JNDI

mybatis第四天

1.mybatis延迟加载

1.1 概念

/**

* 需求2:查询用户信息以及该用户对应的所有角色信息

*/

List<User> findAllUserAndRole();

id="userRoleMap" type="user">

column="id" property="id"/>

column="username" property="username"/>

column="birthday" property="birthday"/>

column="sex" property="sex"/>

column="address" property="address"/>

property="roles" javaType="java.util.List" ofType="role">

column="rid" property="id"/>

column="ROLE_NAME" property="roleName"/>

column="ROLE_DESC" property="roleDesc"/>

id="findAllUserAndRole" resultMap="userRoleMap"> 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(){

List<User> 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.延迟加载:只有再用到数据时才去关联查询,不用就不关联查询,好处:先从单表查询,需要时再从关联表去关联查

询,大大提高数据库性能;延迟加载也叫按需加载或懒加载

 

name="lazyLoadingEnabled" value="true"/>

name="aggressiveLazyLoading" value="false"/>

id="accountMap" type="account">

column="id" property="id"/>

column="uid" property="uid"/>

column="money" property="money"/>

property="user" javaType="user" column="uid"

select="com.itheima.dao.IUserDao.findById"/>

id="findAll" resultMap="accountMap"> select * FROM account

/**

* 延迟加载:查询所有账号信息同时查询对应用户信息

*/

@Test

public void testFindAll() {

List<Account> 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 一级缓存

概念

id="userMap" type="user">

column="id" property="id"/>

column="username" property="username"/>

column="birthday" property="birthday"/>

column="sex" property="sex"/>

column="address" property="address"/>

property="accounts" ofType="account"

select="com.itheima.dao.IAccountDao.findAccountById" column="id"/>

id="findAll" resultMap="userMap"> SELECT * FROM USER ;

id="findAccountById" parameterType="int" resultType="account"> SELECT * FROM account where uid=#{uid};

@Test

public void testFindAll() {

List<User> 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 二级缓存

概念

代码演示

它指的是MybatisSqlSession对象的缓存。当我们执行查询之后,查询的结果会同时存入到SqlSession为我们

提供一块区域中。该区域的结构是一个Map。当我们再次查询同样的数据,mybatis会先去sqlsession中查询是否有,有

的话直接拿出来用。当SqlSession对象消失时(close方法被调用),mybatis的一级缓存也就消失了。

@Test

public void testFirstLeverCache(){

User user1 = userDao.findById(43);

System.out.println("user1 = " + user1);

//测试一下关闭session

/*session.close();

session=factory.openSession(true);

userDao=session.getMapper(IUserDao.class);*/

//也可以清除缓存

//session.clearCache();

//再次执行相同的查询

User user2 = userDao.findById(43);

System.out.println("user2 = " + user2);

//判断user1user2是不是同一个对象

System.out.println("user1==user2 : " + (user1==user2));

}

如果是同一个session对象,那么第二次查询的user对象和第一次查询的user对象是同一个user对象,最后打印的

结果是true,通过控制台日志可以看出只执行了一次查询;当中间关闭了session或者调用clearCache方法清除缓存之

后,那两个user对象就不是同一个对象了,控制台查看日志也会发现执行了两次查询。

它指的是MybatisSqlSessionFactory对象的缓存。由同一个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();

//判断user1user2是不是同一个对象

System.out.println("user1==user2 : " + (user1==user2));

}

两个对象虽然不是同一个对象,但是通过控制台发现只执行了一次查询

注意:一定要关闭之前的sqlSession对象

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

 

resource="jdbcConfig.properties"/>

 

name="com.itheima.domain"/>

default="mysql">

id="mysql">

type="jdbc">

type="pooled">

name="driver" value="${jdbc.driver}"/>

name="url" value="${jdbc.url}"/>

name="username" value="${jdbc.username}"/>

name="password" value="${jdbc.password}"/>

 

name="com.itheima.dao"/>

3.1.2 IUserDao中给方法添加注解

/**

* 查询所有操作

* @return

*/

@Select("select * from user")

List<User> 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};")

List<User> 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}")

List<User> 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(){

List<User> users = userDao.findAll();

for (User user : users) {

System.out.println(user);

}

}

//保存用户

@Test

public void saveUser(){

//创建用户信息

User user=new 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 user=new 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(){

List<User> 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 queryVo=new QueryVo();

//创建模糊查询条件封装到user对象中

User user=new User();

user.setUsername("%%");

queryVo.setUser(user);

//执行查询3.2 mybatis注解开发实例类属性与表列名不一致

3.2.1 IUserDao中给方法添加注解

3.2.2 在测试类中测试

3.3 mybatis注解开发一对一/多查询

3.3.1 IUserDao中给方法添加注解

List<User> 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")

//id="uMap"表示结果集映射的id,将来可以给其他@ResultMap复用

@Results(id="uMap",value = {

//id=true表示是主键,默认值是false

@Result(id=true,column = "id",property = "userId"),

@Result(id=false,column = "username",property = "userName"),

@Result(column = "birthday",property = "userBirthday"),

@Result(column = "sex",property = "userSex"),

@Result(column = "address",property = "userAddress")

}

)

List<U> findAllU();

@Test

public void findAllU(){

List<U> 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(id="accountMap",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(

select="com.itheima.dao.IUserDao.findById",

fetchType = FetchType.EAGER//立即查询

)),

})

List<Account> findAllAccountAndUser();

/**

* 延时查询:查询用户信息的同时查询其所有账户信息

*/

@Select("select * from user")

@Results(id="userMap",value = {

@Result(id=true,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(

select="com.itheima.dao.IAccountDao.findAccountById",

fetchType = FetchType.LAZY//延时查询

)),

})

List<User> findAllUserAndAccount();

public interface IAccountDao {

/**

* 根据uid查询对应的所有账户信息

* @param uid

* @return

*/

@Select("select * from account where uid=#{uid}")

List<Account> findAccountById(int uid);

}

//立即查询:查询账户信息的同时查询其用户信息

@Test

public void findAllAccountAndUser(){

List<Account> 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(){

List<User> 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();

//判断user1user2是不是同一个对象

System.out.println("user1==user2 : " + (user1==user2));

}1.mybatis使用第三方连接池

1.1 mybatis中连接池原理

1.2 使用第三方连接池步骤

1.2.1 自定义工厂类实现mybatisDataSourceFactory接口

MyBatis 在初始化时,根据<dataSource>type 属性来创建相应类型的的数据源 DataSource,即:

type="POOLED"MyBatis 会创建 PooledDataSource 实例

type="UNPOOLED"MyBatis 会创建 UnpooledDataSource 实例

type="JNDI"MyBatis 会从 JNDI 服务上查找 DataSource 实例,然后返回使用

当我们在<dataSource type="POOLED">配置POOLEDmybatis就会为我们创建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不是alibabaDruidDataSourceFactory

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">

 

resource="jdbcConfig.properties"/>

 

name="com.itheima.domain"/>

default="mysql">

id="mysql">

type="jdbc">

type="com.itheima.factory.DruidDataSourceFactory">

name="driver" value="${jdbc.driver}"/>

name="url" value="${jdbc.url}"/>

name="username" value="${jdbc.username}"/>

name="password" value="${jdbc.password}"/>

 

name="com.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

//查询所有用户信息

List<User> users = userDao.findAll();

for (User user : users) {

System.out.println(user);

}

}

id="findUserByMap" resultType="user"> select * from USER test="username!=null and username!=''"> and username like #{username} test="sex!=null and username!=''"> and sex = #{sex}

//动态sql:根据map集合中的条件,查询用户信息

@Test

public void testFindUserByMap(){

//创建Map集合并封装查询参数

Map<String,Object> map=new HashMap<String,Object>();

map.put("username","%%");

map.put("sex","");

//查询符合条件的用户信息

List<User> users = userDao.findUserByMap(map);

for (User user : users) {

System.out.println(user);

}

}结论:使用map集合或者javabean对象作为参数,其实是一样的,map集合对应的就是javabean的属性。

2.2 参数是List集合

IUserDao.xml中配置查询信息

在测试类中测试

结论:mybatis其实是将参数list集合先存到map中,keylist(map.pust("list",list集合对象)),所以

collection="list"中的属性值必须是list,就相当于从map中取出list遍历

2.3 参数是数组- 和参数是list几乎一样

IUserDao.xml中配置查询信息

id="findUserByList" resultType="user"> SELECT * FROM USER and id in( collection="list" item="id" separator=","> #{id} )

//动态sql:查询list集合中指定iduser信息

@Test

public void testFindUserByList(){

//创建list集合并存储要查的用户id

List<Integer> ids=new ArrayList<Integer>();

ids.add(41);

ids.add(43);

ids.add(48);

ids.add(50);

//查询符合条件的用户信息

List<User> users = userDao.findUserByList(ids);

for (User user : users) {

System.out.println(user);

}

}在测试类中测试

结论:查询参数是Array与查询参数是list集合的原理是一样的,都是现将对象存到map集合中,只不过参数

Array时,存到map集合中的keyarray,所以collection="array"的值必须是array

2.4 多个参数情况以及@Param注解

IUserDao中定义查询方法

IUserDao.xml中配置查询信息

id="findUserByArray" resultType="user"> SELECT * FROM USER and id in( collection="array" item="id" separator=","> #{id} )

//动态sql:查询数组中指定iduser信息

@Test

public void testFindUserByArray(){

//创建list集合并存储要查的用户id

Integer[] ids={41,43,48,50};

//查询符合条件的用户信息

List<User> users = userDao.findUserByArray(ids);

for (User user : users) {

System.out.println(user);

}

}

/**

* 多个参数:根据用户名和性别查询用户信息

* @Param("username") :定义参数的别名,将来在映射文件中使用

*/

public List<User> findUserByUsernameAndSex(@Param("username") String username,@Param("sex")

String sex);

}

id="findUserByUsernameAndSex" resultType="user"> 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(){ List<User> users = userDao.findUserByUsernameAndSex("%王%", "女"); for (User user : users) { System.out.println(user); } } /** * 动态sql:查询list集合中指定id的user信息 */ @Select({""}) public List<User> findUserByList(List<Integer> ids); //动态sql:查询list集合中指定id的user信息 @Test public void testFindUserByList(){ //创建list集合并存储要查的用户id List<Integer> ids=new ArrayList<Integer>(); ids.add(41); ids.add(43); ids.add(48); ids.add(50);总结:其实就是将xml映射文件中的配置拿过来用了,也是支持的。适用于带in的查询 3.1 方式2:字符串拼接(了解) 定义sql提供者UserMapperProvider类 在IUserMapper方法上定义注解 测试类测试 //查询符合条件的用户信息 List<User> 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(Map<String,Object> map){ StringBuilder sb=new StringBuilder("select * from user where 1=1 "); 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(type=UserMapperProvider.class,method = "findUserByMap") public List<User> findUserByMap(Map<String,Object> map); }3.2 方式3:使用mybatis中提供的SQL对象动态构建sql语句 修改UserMapperProvider提供者中的fifindUserByMap方法 4.mybatis使用Redis做二级缓存 总结 使用xml配置完成CURD操作 环境 jar包坐标 //动态sql:根据map集合中的条件,查询用户信息 @Test public void testFindUserByMap(){ //创建Map集合并封装查询参数 Map<String,Object> map=new HashMap<String,Object>(); map.put("username","%王%"); map.put("sex","女"); //查询符合条件的用户信息 List<User> users = userMapper.findUserByMap(map); for (User user : users) { System.out.println(user); } } public String findUserByMap(Map<String,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相同 单表查询多表查询 一对多

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值