Mybatis动态代理开发目录
1. 项目开发前期准备
1.1 新建项目添加依赖
新建项目以及添加依赖可以参考此链接中的内容,实现的步骤无变化
1.2 新建属性文件db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf8
username=root
password=111111
1.3 新建环境配置文件(SqlMapConfig.xml)
SQL环境变量的配置主要包括以下几点:
- 读取配置文件
- 设置输出日志
- 注册实体类名称
- 环境配置
- 注册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="jdbc.properties"></properties>
<!--设置日志输出-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--注册实体类别名-->
<typeAliases>
<package name="com.lcl.pojo"/>
</typeAliases>
<!--配置环境变量-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--注册xml文件-->
<mappers>
<!--单个注册-->
<!-- <mapper class="com.lcl.mapper.UsersMapper"></mapper>-->
<package name="com.lcl.mapper"/>
</mappers>
</configuration>
1.4 新建可视化窗口
可视化窗口也就是数据库中的数据,可以在开发工具中进行查看,并且操作数据
具体的操作过程,参考以下连接中的内容:
新建可视化窗口操作步骤
1.5 新建实体类
自动生成实体类
public class Users {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
public Users() {
}
public Users(Integer id, String username, Date birthday, String sex, String address) {
this.id = id;
this.username = username;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
public Users(String username, Date birthday, String sex, String address) {
this.username = username;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Users{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
2. 动态代理实现【主要更新内容】
实现动态代理:
具体的含义就是说在接口中创建相应的方法,之后再相同全类名的xml文件中编写具体的实现增删改查代码;
通过Java代码在对数据库中的数据进行增删改查时,只需要读取配置文件,创建动态代理的对象,调用接口中的方法【实际上执行的时xml文件中操作】,实现对数据的修改
创建动态代理对象的步骤:
- 读取配置文件
- 创建SqlSessionFactory工厂
- 通过SqlSessionFactory工厂获取SqlSession对象
- 通过调用SqlSession对象的getMapper方法获得动态代理对象
- 之后就可以使用动态代理对象来调用接口中的各个方法
//读取配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//读取SqlSession对象
SqlSession sqlSession = factory.openSession();
//取出动态代理的对象,完成接口中方法的调用,实则是完成调用xml文件中相应的标签功能
UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
2.1 用户接口的创建
这里的代码比较简单,就是提供一些接口
public interface UsersMapper {
//查询全部用户
List<Users> getAll();
//根据用户主键查询用户
Users getUsers(Integer id);
//根据用户名实现模糊查询
List<Users> getUsersByName(String username);
//用户的更新
void updateUsers(Users users);
//根据用户主键删除用户
int deleteUsers(Integer id);
//添加用户
void InsertUsers(Users users);
//优化模糊查询
List<Users> getUsersGood(String name);
//使用用户名和地址进行模糊查询
/*使用注解,方便在xml文件中可以使用${}取到数据*/
List<Users> getUsersByNameOrAddress(
@Param("columnName") String columnName,
@Param("columnValue") String columnValue);
}
2.2 新建(接口实现类)同名的的xml文件,完成数据库表的增删改查
这里面主要就是SQL语句,需要注意以下几点:
- mapper标签中namespace属性值是与xml文件相同名称接口的全类名
- 每个语句需要注意它的resultType属性:返回值类型【实际上也就在执行查询语句时会遇到返回值】,返回的可能是一个实体类对象【极大可能是返回多个对象,但是属性值一依然是实体类对象】< select id=“getByBirthday” resultType=“users”>,也有可能是一个map集合实例:< select id=“returnMapOne” parameterType=“int” resultType=“map”>
- parameterType:传入参数的类型:只有在基本数据类型和传入实体对象时需要写,反之如果传入多个参数就不需要写
- 使用concat的方式拼接在查询过程中的字符串:concat(‘%’,#{name},‘%’),主要是想使用#{}作为占位符,避免使用${}带来SQL注入的风险
<?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">
<mapper namespace="com.lcl.mapper.UsersMapper">
<!--查询所有用户
List<Users> getAll -->
<select id="getAll" resultType="users">
select id,username,birthday,sex,address
from users
</select>
<!--根据用户主键查询用户-->
<select id="getUsers" resultType="users" parameterType="int">
select id,username,birthday,sex,address
from users where id = #{id}
</select>
<!--根据用户姓名进行模糊查询-->
<select id="getUsersByName" parameterType="string" resultType="users">
select id,username,birthday,sex,address
from users where username like '%${name}%'
</select>
<!--用户的更新-->
<update id="updateUsers" parameterType="users">
update users set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id=#{id}
</update>
<!--添加用户-->
<insert id="InsertUsers" parameterType="users">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id()
</selectKey>
insert into users(username,birthday,sex,address) values
(#{username},#{birthday},#{sex},#{address})
</insert>
<!--根据用户id删除用户-->
<delete id="deleteUsers" parameterType="int">
delete from users where id=#{id}
</delete>
<!--优化模糊查询,使用${}可能会有sql注入的风险
List<Users> getUsersGood(String name);
-->
<select id="getUsersGood" parameterType="string" resultType="users">
select id,username,birthday,sex,address
from users where username like concat('%',#{name},'%')
</select>
<!--使用用户名和地址进行模糊查询
List<Users> getUsersByNameOrAddress(
@Param("columnName") String columnName,
@Param("columnValue") String columnValue);-->
<select id="getUsersByNameOrAddress" resultType="users">
select id,username,birthday,sex,address
from users where ${columnName} like concat('%',#{columnValue},'%')
</select>
</mapper>
3. 优化测试
- 通过创建动态代理对象执行接口中的方法【实际执行xml文件中的SQL语句】,实现对数据的增删改查功能
public class Mytest {
SqlSession sqlSession;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
@Before
public void getSqlSession() throws IOException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
sqlSession = factory.openSession();
}
@After
public void closeSqlSession(){
sqlSession.close();
}
@Test
public void testGetAll(){
//取出动态代理的对象,完成接口中方法的调用,实则是完成调用xml文件中相应的标签功能
UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
// System.out.println(usersMapper.getClass());
//sqlSession.selectList("com.lcl.mapper.UsersMapper")
//下面的方法就是在调用接口中的方法,mybatis已经为我们把功能代理出来了
List<Users> usersList = usersMapper.getAll();
usersList.forEach(users -> System.out.println(users));
}
//根据用户主键查询用户
@Test
public void testGetUsers(){
//取出代理对象,完成接口中方法的调用,实际上执行的是xml文件中的查询方法
UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
Users users = usersMapper.getUsers(4);
System.out.println(users);
}
//通过用户的姓名进行模糊查询
@Test
public void testGetUsersByName(){
UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
List<Users> usersList = usersMapper.getUsersByName("小");
usersList.forEach(users -> System.out.println(users));
}
//根据用户id更新用户数据
@Test
public void testUpdateUsers() throws ParseException {
//获取代理代理对象,完成接口中方法的调用,实际上执行xml文件中的更新操作
UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
usersMapper.updateUsers(new Users(7, "李华", sdf.parse("1999-05-25"), "2", "南阳市"));
sqlSession.commit();
}
//测试添加用户
@Test
public void testInsertUsres() throws ParseException {
//获取代理对象
Users users = new Users("翠花",sdf.parse("2006-05-14"), "1", "郑州市");
UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
usersMapper.InsertUsers(users);
sqlSession.commit();
System.out.println(users);
}
//根据用户id删除用户
@Test
public void testDeleteUsers(){
//获取代理对象,完成接口中删除放的的调用,实际上执行的是xml中的方法
UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
int deleteUsers = usersMapper.deleteUsers(5);
System.out.println(deleteUsers);
sqlSession.commit();
}
@Test
public void testGetUsersByNameOrAddress() throws IOException {
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = factory.openSession();
//获取代理对象,完结接口中查询语句的调用没实际上执行的是xml中方法的调用
UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
List<Users> usersByNameOrAddress = usersMapper.getUsersByNameOrAddress("address", "市");
usersByNameOrAddress.forEach(users -> System.out.println(users));
sqlSession.close();
}
//获取全球唯一标识符
@Test
public void testUUID(){
UUID uuid = UUID.randomUUID();
System.out.println(uuid);
}
}