4.6.1 parameterType
在映射文件中通过parameterType指定输入 参数的类型。
4.6.2 resultType
在映射文件中通过resultType指定输出结果的类型。
4.6.3 #{}和${}
#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,#{}中可以写成value或其它名称。
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
{}。
{}中只能写成value。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
4.6.4 selectOne和selectList
selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。
selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne。
如果使用selectOne报错: org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4
mybatis开发dao的方式
##SqlSession ##
SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)、。
SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
SqlSession最佳应用场合在方法体内,定义成局部变量使用。
编写dao方法
-
程序员需要写dao接口和dao实现类。
-
需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession
package com.ljl.dao; import com.ljl.po.User; import java.util.List; public interface UserDao { //根据用户id查询数据 public User FindById(int id); //根据name查询一组数据 public List<User> findByName(); //添加数据到数据库 public int insert(User user); //根据id删除用户 public void delete(int id); //根据用户修改数据 public void update(User user) ; }
实现类
`
public class UserImp implements UserDao {
private SqlSessionFactory sqlSessionFactory;
public UserImp(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User FindById(int id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById", id);
return user;
}
@Override
public List<User> findByName() {
SqlSession session = sqlSessionFactory.openSession();
List<User> result= session.selectList("test.findUserByname","李家浪");
return result;
}
@Override
public int insert(User user) {
SqlSession session = sqlSessionFactory.openSession();
User user1=new User();
user1.setUsername("增加22");
user1.setBirthday(new java.sql.Date(20170128));
user1.setAddress("北京22");
user1.setSex("男222");
session.insert("test.addUser",user);
System.out.println(user.getId());
//需要手动提交事务
session.commit();
session.close();
return 0;
}
@Override
public void delete(int id) {
SqlSession session = sqlSessionFactory.openSession();
session.delete("test.deleteById",52);
//需要手动提交事务
session.commit();
session.close();
}
@Override
public void update(User user) {
SqlSession session = sqlSessionFactory.openSession();
User user1=new User();
user1.setId(52);
user1.setUsername("修改name");
user1.setAddress("西安啊啊啊啊啊");
session.update("test.updatById",user);
//需要手动提交事务
session.commit();
session.close();
}
}
`
编写单元测试类进行测试
-
使用dao接口实现类存在大量模板方法,代码重复太多
-
使用session的时候见statementId硬编码
-
session方法参数的类型是object,不利于发现错误
使用mapper代理的方法开发dao
-
程序员还需要编写mapper.xml映射文件
-
程序员只需要编写mapper接口(相当于dao接口)需遵循一些开发规范,mybatis可以自动生成mapper接口的实现类。
首先创建一个mapperJava文件
public interface UserDaoMapper {
}
其次创建一个mapper.xml文件
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace命名空间:使用mapper代理方式开发,namespace有特殊重要的作用,是mapper接口的全路径
-->
<mapper namespace="com.ljl.mapperDao.UserDaoMapper">
<select id="findUserById" parameterType="int" resultType="com.ljl.po.User">
select * from user where id=#{id};
</select>
</mapper>
在接口中写方法
/** 方法名对应mapper.xml里面的id="findUserById"
* 输入对象对于mapper.xml里面的parameterType="int"
* 返回值对象的mapper.xml里面的resultType="com.ljl.po.User"
* @param id
* @return
*/
public User findUserById(int id);
基于mapper代理的方式,基本完成编写测试代码
错误1 Type interface com.ljl.mapperDao.UserDaoMapper is not known to the MapperRegistry
这是因为我们新创建的usermapper.xml没有在batis-config中注册
<mappers>
<mapper resource="mapper/usermapper.xml"/>
</mappers>
测试代码
public class UserDaoMapperTest {
SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
InputStream inputStream= null;
try {
inputStream = Resources.getResourceAsStream("config/mybatis-config.xml");
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void findUserById() {
SqlSession session = sqlSessionFactory.openSession();
//使用mapper代理生成mapper代理接口的实现类的对象
UserDaoMapper usermaer = session.getMapper(UserDaoMapper.class);
//调用方法
User user = usermaer.findUserById(1);
System.out.println(user);
}
}
5.3.6.1 代理对象内部调用selectOne或selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。
SqlMapConfig.xml
mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:
- properties(属性)
- settings(全局配置参数)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境集合属性对象)
- environment(环境子属性对象)
- transactionManager(事务管理)
- dataSource(数据源)
- mappers(映射器)
properties属性
将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值。 在SqlMapConfig.xml中就不需要对数据库连接参数硬编码。
将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其它xml可以引用该db.properties。
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb1
jdbc.username=root
jdbc.password=ljl123456
在sqlMapConfig.xml加载属性文件:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="config/jdbc.properties"></properties>
<environments default="development">
<environment id="development">
<!-- 使用JDBC的事务管理,事务控制由mybatis -->
<transactionManager type="JDBC">
<property name="..." value="..."/>
<property name="" value=""/>
</transactionManager>
<!--数据库连接池,由mybatis控制-->
<dataSource type="POOLED">
<!--<property name="driver" value="com.mysql.jdbc.Driver"/>-->
<!--<property name="url" value="jdbc:mysql://localhost:3306/mydb1"/>-->
<!--<property name="username" value="root"/>-->
<!--<property name="password" value="ljl123456"/>-->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<mapper resource="config/sqlmap/user.xml"/>
<mapper resource="mapper/usermapper.xml"/>
</mappers>
</configuration>
properties特性:
注意: MyBatis 将按照下面的顺序来加载属性:
- 在 properties 元素体内定义的属性首先被读取。
- 然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。
- 最后读取parameterType传递的属性,它会覆盖已读取的同名属性。
建议: 不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。 在properties文件中定义属性名要有一定的特殊性,如:XXXXX.XXXXX.XXXX