接口类代码
public interface IUserDao {
// 查询所有
List<User> findAll();
//保存用户
void saveUser(User user);
//更新用户
void updataUser(User user);
//删除用户
void deleteUser(int id);
//根据id找到用户
User findById(int id);
//模糊查询用户信息
List<User> findByName(String username);
获取用户的总记录条数
int findTotal();
}
完整mapper代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace指的是你的dao接口-->
<mapper namespace="com.daniel.dao.IUserDao">
<!--配置查询所有 其中id不能乱写必须是dao接口中的方法 resultType写的是实体类的全路径-->
<select id="findAll" resultType="com.daniel.domain.User">
select * from user;
</select>
<!--保存用户 parameterType 说明带参-->
<!-- <insert id="saveUser" parameterType="com.daniel.domain.User">
insert into user(username,address,sex,birthday)
value(#{username},#{address},#{sex},#{birthday});
</insert>-->
<!--保存用户 parameterType 说明带参 同时获取用户的id-->
<insert id="saveUser" parameterType="com.daniel.domain.User">
<!-- keyProperty id的属性名称 keyColumn id的列名 order 执行的顺序-->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,address,sex,birthday)
value(#{username},#{address},#{sex},#{birthday});
</insert>
<!--更新用户 parameterType 说明带参-->
<update id="updataUser" parameterType="com.daniel.domain.User">
update user set
username=#{username},address=#{address},sex=#{sex},birthday=#{birthday}
where id = #{id};
</update>
<!--删除用户-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{uid};
</delete>
<!--模糊查询用户-->
<select id="findByName" resultType="com.daniel.domain.User" parameterType="String">
<!-- select * from user where username like #{username};--> <!--由于是PreparStatemen类型!占位符安全! 推荐使用这种-->
select * from user where username like '%${value}%'<!--由于是statemen类型的不安全开发不用 字符串拼接-->
</select>
<!--获取用户的总记录条数-->
<select id="findTotal" resultType="int" >
select count(id) from user ;
</select>
<!--根据queryVo的条件查询用户 使用了OGNL表达式 object graphic navigation language 对象图导航语言 外层对象.内层对象 -->
<select id="findUserByVo" parameterType="com.daniel.domain.QueryVo" resultType="com.daniel.domain.User" >
select * from user where username like #{user.username} ;
</select>
</mapper>
完整测试类代码
public class MybatisTest {
private InputStream inputStream;
private SqlSession sqlSession;
private IUserDao userDao;
@Before
public void init() throws Exception{
//1.读取配置文件
inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
//3.使用工厂创建SqlSession(真正操作数据库的对象!)
sqlSession = factory.openSession();
//4.使用SqlSession创建dao接口的代理对象
userDao = sqlSession.getMapper(IUserDao.class);
}
@After
public void destory() throws Exception{
sqlSession.close();
inputStream.close();
}
//查询所有
@Test
public void findAll( ) throws Exception {
List<User> users = userDao.findAll();
for (User user:users
) {
System.out.println(user);
}
}
//添加+查询添加以后的id
@Test
public void testSave() {
User user = new User();
user.setUsername("yrq");
user.setAddress("长沙");
user.setSex("男");
user.setBirthday(new Date());
System.out.println("before :"+user);
userDao.saveUser(user);
sqlSession.commit();
System.out.println(user);
}
//更新
@Test
public void updataUser(){
User user = new User();
user.setId(49);
user.setUsername("yrqqqq");
user.setAddress("长沙");
user.setSex("男");
user.setBirthday(new Date());
userDao.updataUser(user);
sqlSession.commit();
}
//根据id删除
@Test
public void deleteUser(){
userDao.deleteUser(49);
sqlSession.commit();
}
//根据id查询
@Test
public void findById(){
User user = userDao.findById(48);
System.out.println(user);
sqlSession.commit();
}
//模糊查询用户信息
@Test
public void findByName(){
List<User> users = userDao.findByName("王");
for (User user:users
) {
System.out.println(user);
}
sqlSession.commit();
}
//获取用户的总记录条数
@Test
public void findTotal(){
int count = userDao.findTotal();
System.out.println(count);
}
//pojo包装类的测试 (其中的mapper使用了ognl表达式)
@Test
public void findByVo(){
QueryVo vo = new QueryVo();
User user = new User();
user.setUsername("%王%");
vo.setUser(user);
List<User> users = userDao.findUserByVo(vo);
for (User u:users
) {
System.out.println(u);
}
sqlSession.commit();
}
}
模糊查询相关:
使用Dao实现类的执行过程分析
DaoImpl例子:
@Override
public void saveUser(User user) {
//1.根据factory获取SqlSession对象
SqlSession session = factory.openSession();
//2.调用方法实现保存
session.insert("com.itheima.dao.IUserDao.saveUser",user);
//3.提交事务
session.commit();
//4.释放资源
session.close();
}
Test中做修改:使用工厂对象
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.使用工厂对象,创建dao对象
userDao = new UserDaoImpl(factory);
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
//6.释放资源
in.close();
}
编写DaoImpl,MyBatis的执行过程源码分析图:
使用代理DAO的源码分析图
一些配置xml中的属性标签
1.properties
使用外部配置有两种
第一种url属性
<properties url="file:///G:/idea_workspace/Mybatis/yrq_02MybatisDao/src/main/resources/jdbcConfig.properties">
</properties>
第二种resource属性(常用)
<properties resource="jdbcConfig.properties">
</properties>
详细配置
<?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">
<!--mybaits的主配置文件-->
<configuration>
<!--注意各个标签之间有顺序-->
<properties resource="jdbcConfig.properties"></properties>
<typeAliases>
<!--type只能指定实体类全类名 alias属性指定别名 区分大小写-->
<!--<typeAlias type="com.daniel.domain.User" alias="user"> </typeAlias>-->
<!--现在就不区分大小写了-->
<package name="com.daniel.domain"></package>
</typeAliases>
<!--配置properties
可以在标签内部配置信息 也可以通过外部文件来配置信息
resource 属性:
用于指定配置文件的位置,是按照类路径来写的
URL属性 Uniform Resource Locator 统一资源定位符 可以唯一标志一个资源的位置
写法必须是
协议 主机 端口 URI
URL > URI(精准性)
URI属性 Uniform Resource Identifier 统一资源标识符 是在应用中可以可以唯一标志一个资源的位置-->
<!--配置环境-->
<environments default="mysql">
<!--配置mysql环境-->
<environment id="mysql">
<!--配置事务类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--配置数据源(连接池)的基本信息-->
<!-- <property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>-->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--指定映射配置文件的位置,映射配置文件指的是每个dao配置的文件-->
<mappers>
<package name="com.daniel.dao"></package>
</mappers>
</configuration>
2.package
目的:提高开发效率
1.实体类
<!--配置别名 只能配置domain中的类 -->
<typeAliases>
<!--type只能指定实体类全类名 alias属性指定别名 区分大小写-->
<!--<typeAlias type="com.daniel.domain.User" alias="user"> </typeAlias>-->
<!--现在就不区分大小写了-->
<package name="com.daniel.domain"></package>
</typeAliases>
2.接口
<!--指定映射配置文件的位置,映射配置文件指的是每个dao配置的文件-->
<mappers>
<package name="com.daniel.dao"></package>
<!--<mapper resource="com/daniel/dao/IUserDao.xml"/> -->
</mappers>
当数据库中的列名与实体类中的属性名对应不上的时候
- 起别名
select id as userId - resultmap 结果集映射
<resultMap id="userMap" type="com.daniel.domain.User">
<!--主键字段的对应 property实体属性的id(严格区分大小写) column数据库列表中的id-->
<id property="userId" column="id"></id>
<!--非主键字段的对应-->
<result property="userName" column="username"></result>
<result property="userAddress" column="address"></result>
<result property="userSex" column="sex"></result>
<result property="userBirthday" column="birthday"></result>
</resultMap>
<!--配置查询所有 使用resultMap的时候 这样写开发效率快!!但是运行效率慢-->
<select id="findAll" resultMap="userMap">
<!--select id as userId 这样起别名的方法 运行效率快-->
select * from user;
</select>