参考链接: 在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

*/

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.映射配置文件中的mapper的namespace属性值必须是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核心对象

/*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.执行查询方法

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

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

己创建)

SqlSessionFactoryBuilder代码实现

1.添加依赖:

<dependency>

<groupId>dom4jgroupId>

<artifactId>dom4jartifactId>

<version>1.6.1version>

dependency>

<dependency>

<groupId>jaxengroupId>

<artifactId>jaxenartifactId>

<version>1.1.6version>

dependency>

2.创建Configuration和Mapper两个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.mybatis的CRUD操作

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对应的是user的id属性*/

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并封装到user的id属性上。

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;

}

}测试类测试方法编写

mybatis的dao层开发模式

返回值类型-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属性

* 输入参数的类型:int、string、User、plain old java object、包装类型ValueObject

* 输出参数 resultType属性、

* 输入参数的类型:User、int、string

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

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

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

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

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

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

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

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

编写测试类测试方法

public class U {

private Integer userId;

private String userName;

private Date userBirthday;

private String userSex;

private String userAddress;

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

}

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标签,resources或class指定包下所有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元素的属性主要有 item,index,collection,open,separator,close。

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} 需求:根据qv中list集合查询用户信息-

在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;

//setter、getter、toString方法省略

}

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;

//setter、getter、toString方法省略

}

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

概念

代码演示

它指的是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();

session=factory.openSession(true);

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

//也可以清除缓存

//session.clearCache();

//再次执行相同的查询

User user2 = userDao.findById(43);

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

//判断user1和user2是不是同一个对象

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

}

如果是同一个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("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();

//判断user1和user2是不是同一个对象

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

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

1.1 mybatis中连接池原理

1.2 使用第三方连接池步骤

1.2.1 自定义工厂类实现mybatis的DataSourceFactory接口

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

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

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

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

当我们在<dataSource type="POOLED">配置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">

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中,key为list(即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集合中指定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);

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

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

for (User user : users) {

System.out.println(user);

}

}在测试类中测试

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

为Array时,存到map集合中的key叫array,所以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:查询数组中指定id的user信息

@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相同 单表查询多表查询 一对多

[转载] mybatis相关推荐

  1. java mybatis狂神说sql_狂神说MyBatis01:第一个程序

    狂神说MyBatis系列连载课程,通俗易懂,基于MyBatis3.5.2版本,欢迎各位狂粉转发关注学习,视频同步文档.未经作者授权,禁止转载 MyBatis简介 环境说明: jdk 8 + MySQL ...

  2. windows上使用Git bash详细图文教程

    一:Git是什么? 查看全文 http://www.taodudu.cc/news/show-1347366.html 相关文章: Eclipse安装lombook pom文件报错,错误如下:(org ...

  3. 【Redis】redis-3.0.0安装以及集群的搭建

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/sds15732622190/artic ...

  4. clipse中运行maven提示org/apache/maven/cli/MavenCli : Unsupported major.minor version 51.0

    查看全文 http://www.taodudu.cc/news/show-1347374.html 相关文章: Mysql5.7.2安装教程+下载地址(windows) toadstool sql格式 ...

  5. 【转载】springboot:如何优雅的使用mybatis

    这两天启动了一个新项目因为项目组成员一直都使用的是mybatis,虽然个人比较喜欢jpa这种极简的模式,但是为了项目保持统一性技术选型还是定了 mybatis.到网上找了一下关于spring boot ...

  6. Mybatis like查询的写法--转载

    原文地址:http://lavasoft.blog.51cto.com/62575/1386870 Mybatis like查询官方文档没有明确的例子可循,网上搜索了很多,都不正确. Mybatis ...

  7. 【转载】MyBatis报错Invalid bound statement (not found)

    转载自: koal的博客 http://www.cnblogs.com/koal/p/5232388.html <!--IDEA需要添加一下内容,否则无法找到mapper --><b ...

  8. [转载]JDBC/Spring/MyBatis性能比较

    原文地址:JDBC/Spring/MyBatis性能比较作者:tom_lt 测试目的: 比较JDBC,SpringJdbc和MyBatis的性能. 测试用例: 1. 查询:查询一张10000条数据的表 ...

  9. Mybatis与Ibatis比较(转载)

    原文地址:Mybatis与Ibatis比较(转载)作者:JavaLeader 随着开发团队转投Google Code旗下,ibatis3.x正式更名为Mybatis  虽然从正式版发布至今也有近一年时 ...

最新文章

  1. ClientScriptManager.RegisterStartupScript.
  2. Unity3D架构之PureMVC
  3. 函数 —— strncpy() (内存重叠) memcpy() memmove() 一个字符串拷贝给另一个字符串
  4. 【lLinux驱动】linux内核源码目录结构
  5. 32/100. Binary Tree Inorder Traversal
  6. Ajax:异步js和xml
  7. 企业实战_23_MyCat SQL防火墙
  8. Mysql 启动失败没日志,MySQL Server 5.7将无法启动,并且未填充错误日志
  9. html柳树动画,3D教程-柳树生长动画
  10. vue全局变量的 定义与任意调用
  11. Unity 全面理解加载和内存管理
  12. 惠普服务器硬件检测软件吗,惠普硬件检测工具DST HP PC Hardware Diagnostics UEFI 6.8.0.0 Rev.A 使用方法...
  13. 微信模板消息的发送动态封装(Java完美封装)
  14. win10家庭版将中文用户名修改为英文
  15. MySQL中的BETWEEN...AND的用法
  16. 熟知四种常见的BIOS信息说明【7gyy】
  17. 锁屏状态可以远程连接服务器,锁屏状态下如何远程控制安卓手机? 向日葵远程控制完美诠释...
  18. 《天下无贼》经典台词与遗憾
  19. Ant Design vue 改变表格背景颜色
  20. 熬夜整理的vue面试题

热门文章

  1. 本博打开方式,请详读
  2. 零基础mysql项目实例_MySQL-零基础开发
  3. python如何删除对象属性_如何优雅的删除对象中的指定属性?
  4. java swing web_Java-JFrame-swing嵌套浏览器步骤
  5. 在linux下vcd光盘提取,linux下抓取Vcd的视频文件[Linux安全]
  6. docker run 挂载卷_docker mysql配置挂载到卷
  7. Java小魔女芭芭拉_沉迷蘑菇不可自拔,黏土人《小魔女学园》苏西·曼芭芭拉 图赏...
  8. android添加删除项目,编写android计算器添加删除按钮,出现很抱歉,XX项目已停止运行。...
  9. Pytorch 各种模块:降低学习率,
  10. 新版谷歌浏览器开启Flash支持