[Renpy] Connect to MySQL with Spring Boot

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Post Reply
Message
Author
Love&Peace
Regular
Posts: 52
Joined: Wed Dec 17, 2014 8:19 pm
Contact:

[Renpy] Connect to MySQL with Spring Boot

#1 Post by Love&Peace »

Hi.

This topic shows how to connect mysql database in your renpy project.
Sorry for poor eng. :P

0. Structure

Renpy Project -> Spring Boot Web Service -> Database -> Spring Boot Web Service -> Renpy Project

1. What we need are Eclipse(or STS4), MySQL, Ren'py.

First. Install MySQL and set root account and password.

Second. Install STS 4 or Eclipse. If you want to use Eclipse, then you must install Spring 4 plugin to make Spring Boot Project.

Third. Install Ren'py.

2. Let's make Spring Boot Project.

Run Eclipse or STS4, right click on Project Explorer, click project, search Spring Starter Project.
스크린샷 2020-01-23 오전 9.35.23.png


And add dependencies MySQL, Web, MyBatis, JDBC.
스크린샷 2020-01-23 오전 9.36.48.png



3. Create Database and Table

Run mysql server and connect to the server with database client. I recommend DBeaver.

And create database and make table.

Code: Select all

CREATE DATABASE renpy;

USE renpy;

CREATE TABLE renpy_char
(
	char_id INT not null auto_increment primary key,
	char_name VARCHAR(250) not null,
	char_sex ENUM('F', 'M') not null,
	char_height INT,
	char_weight INT,
	char_phone VARCHAR(250),
	char_age INT not null,
	char_strength INT not null,
	char_intelligence INT not null,
	char_dexterity INT not null
) engine=MyISAM auto_increment=1 default charset=utf8;


INSERT INTO 
	renpy_char
VALUES
	(
		1,				/* char_id* /
		'정재헌',			/* char_name */
		'M',				/* char_sex */
		174,				/* char_height */
		62,				/* char_weight */
		'010-1234-1234',	/* char_phone */
		21,				/* char_age */
		5,				/* char_strength */
		10,				/* char_intelligence */
		7				/* char_dexterity */
	);

/* same as the first insert */
INSERT INTO
	renpy_char
VALUES
	(
		2,
		'송아라',
		'F',
		168,
		52,
		'010-5678-5678',
		21,
		8,
		4,
		7
	);

/* multiple insert */
INSERT INTO
	renpy_char(char_name, char_sex, char_height, char_weight, char_phone, char_age, char_strength, char_intelligence, char_dexterity)
VALUES
	('조수하', 'F', 153, 41, '010-1010-1010', 15, 3, 5, 4),
	('최배근', 'M', 178, 83, '010-1111-2222', 55, 10, 4, 8),
	('강형민', 'M', 183, 78, '010-2222-3333', 27, 9, 7, 9),
	('유시우', 'F', 164, 48, '010-1112-2221', 21, 4, 7, 10);
	
Then check table.

Code: Select all


SELECT * FROM renpy_char;

스크린샷 2020-01-23 오전 10.35.26.png



4. Write application.properties and do test.

You can find application.properties in src/main/resources

Code: Select all

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/renpy?serverTimeZone=Asia/Seoul
spring.datasource.username=root
spring.datasource.password=password
Then, let's test.
You can fine RenpyApplicationTest.java in src/test/java.

Write test code.

Code: Select all

package me.renpy.demo;

import java.sql.Connection;

import javax.sql.DataSource;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class RenpyApplicationTests {

	@Autowired
	private DataSource ds;
	
	@Test
	void contextLoads() {
	}

	@Test
	public void testCon() throws Exception {
		Connection con = ds.getConnection();
		System.out.println("Datasource = " + ds);
		System.out.println("Connection = " + con);
		con.close();
	}
}

Right click on RenpyApplicationTest.java -> run as -> JUnit Test.

And you'll see.

Code: Select all

Datasource = HikariDataSource (HikariPool-1)
Connection = HikariProxyConnection@1624510452 wrapping com.mysql.cj.jdbc.ConnectionImpl@2e5b7fba
If you get timeZoneError, then fix spring.datasource.url in application.properties.

5. Set DBConfig, Mapper, Service, Model, Controller

Before we set, make packages and .java files like below.

me.renpy.demo.config -> DBConfig.java
me.renpy.demo.controller -> RenpyController.java
me.renpy.demo.mapper -> RenpyCharacterMapper.java
me.renpy.demo.model -> RenpyChar.java
me.renpy.demo.service -> RenpyCharService.java

src/main/resource/mapper -> charSql.xml


Write DBConfig.java

Code: Select all

package me.renpy.demo.config;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@Configuration
@MapperScan(basePackages="me.renpy.demo.mapper")
@EnableTransactionManagement
public class DBConfig {

	@Bean
	public SqlSessionFactory sqlSessionFactory(DataSource ds) throws Exception {
		final SqlSessionFactoryBean sqlBean = new SqlSessionFactoryBean();
		sqlBean.setDataSource(ds);
		PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
		sqlBean.setMapperLocations(resolver.getResources("classpath:/mapper/*.xml"));
		return sqlBean.getObject();
	}
	
	@Bean
	public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) throws Exception {
		final SqlSessionTemplate sqlTemplate = new SqlSessionTemplate(sqlSessionFactory);
		return sqlTemplate;
	}
}

Write charSql.xml.

Code: Select all

<?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="me.renpy.demo.mapper.RenpyCharMapper">
    <select id="showAll" resultType="me.renpy.demo.model.RenpyChar">
        SELECT
            char_id             charId,
            char_name           charName,
            char_sex            charSex,
            char_height         charHeight,
            char_weight         charWeight,
            char_phone          charPhone,
            char_age            charAge,
            char_strength       charStrength,
            char_intelligence   charIntelligence,
            char_dexterity      charDexterity
        FROM
            renpy_char        
    </select>
    
    <select id="getRenpyCharByCharId" parameterType="int" resultType="me.renpy.demo.model.RenpyChar">
        SELECT
            char_id             charId,
            char_name           charName,
            char_sex            charSex,
            char_height         charHeight,
            char_weight         charWeight,
            char_phone          charPhone,
            char_age            charAge,
            char_strength       charStrength,
            char_intelligence   charIntelligence,
            char_dexterity      charDexterity
        FROM
            renpy_char
        WHERE
            char_id = #{charId}     
    </select>
</mapper>

Write RenpyChar.java

Code: Select all

package me.renpy.demo.model;

public class RenpyChar {
	private int charId;
	private String charName;
	private char charSex;
	private int charHeight;
	private int charWeight;
	private String charPhone;
	private int charAge;
	private int charStrength;
	private int charIntelligence;
	private int charDexterity;
	
	public int getCharId() {
		return charId;
	}
	public void setCharId(int charId) {
		this.charId = charId;
	}
	public String getCharName() {
		return charName;
	}
	public void setCharName(String charName) {
		this.charName = charName;
	}
	public char getCharSex() {
		return charSex;
	}
	public void setCharSex(char charSex) {
		this.charSex = charSex;
	}
	public int getCharHeight() {
		return charHeight;
	}
	public void setCharHeight(int charHeight) {
		this.charHeight = charHeight;
	}
	public int getCharWeight() {
		return charWeight;
	}
	public void setCharWeight(int charWeight) {
		this.charWeight = charWeight;
	}
	public String getCharPhone() {
		return charPhone;
	}
	public void setCharPhone(String charPhone) {
		this.charPhone = charPhone;
	}
	public int getCharAge() {
		return charAge;
	}
	public void setCharAge(int charAge) {
		this.charAge = charAge;
	}
	public int getCharStrength() {
		return charStrength;
	}
	public void setCharStrength(int charStrength) {
		this.charStrength = charStrength;
	}
	public int getCharIntelligence() {
		return charIntelligence;
	}
	public void setCharIntelligence(int charIntelligence) {
		this.charIntelligence = charIntelligence;
	}
	public int getCharDexterity() {
		return charDexterity;
	}
	public void setCharDexterity(int charDexterity) {
		this.charDexterity = charDexterity;
	}
}

Write RenpyCharMapper.java

Code: Select all

package me.renpy.demo.mapper;

import java.util.List;

import me.renpy.demo.model.RenpyChar;

public interface RenpyCharMapper {

	public List<RenpyChar> showAll() throws Exception;
	
	public RenpyChar getRenpyCharByCharId(int charId) throws Exception;
}

Write RenpyCharService.java

Code: Select all

package me.renpy.demo.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import me.renpy.demo.mapper.RenpyCharMapper;
import me.renpy.demo.model.RenpyChar;

@Service
public class RenpyCharService {

	@Autowired
	RenpyCharMapper renpyMapper;
	
	public List<RenpyChar> showAll() throws Exception {
		return renpyMapper.showAll();
	}
	
	public RenpyChar getRenpyCharByCharId(int charId) throws Exception {
		return renpyMapper.getRenpyCharByCharId(charId);
	}
}

Write RenpyController.java

Code: Select all

package me.renpy.demo.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;

import me.renpy.demo.model.RenpyChar;
import me.renpy.demo.service.RenpyCharService;

@Controller
public class RenpyController {

	@Autowired
	RenpyCharService renpyCharService;

	@GetMapping("show")
	public @ResponseBody List<RenpyChar> showAll() throws Exception {
		return renpyCharService.showAll();
	}
	
	@GetMapping("show/{charId}")
	public @ResponseBody RenpyChar getRenpyCharByCharId(@PathVariable("charId") int charId) throws Exception {
		return renpyCharService.getRenpyCharByCharId(charId);
	}
}

6. Let's test on Browser.

Right click the root folder( renpy ) -> run as -> spring boot application.

Then open your browser.
If you want to get clean json file, you have to install json beautifier plugin. I recommend Opera or Chrome Browser.

And write url

localhost:8080/show

and you'll see the RenpyChar List.
Opera 스냅샷_2020-01-23_130838_localhost.png

or

localhost:8080/show/2
스크린샷 2020-01-23 오후 2.07.50.png


Final. Make Renpy Project and write script.rpy

Make Renpy Project.
스크린샷 2020-01-23 오후 1.28.39.png
Open script.rpy and write code.

Code: Select all

init python:
    import urllib2
    import json

    class Connection:
        url = "http://localhost:8080/show/"

        def __init__(self, char_id):
            self.response = urllib2.urlopen(Connection.url + str(char_id))
            self.json_data = self.response.read()
            self.py_data = json.loads(self.json_data)

        def close_connection(self):
            self.response.close()

    class TestCharacter:
        def __init__(self):
            self.__char_id = None
            self.__name = None
            self.__sex = None
            self.__height = None
            self.__weight = None
            self.__phone = None
            self.__age = None
            self.__strength = None
            self.__intelligence = None
            self.__dexterity = None

        @property
        def char_id(self):
            return self.__char_id
        
        @char_id.setter
        def char_id(self, char_id):
            self.__char_id = char_id
        
        @property
        def name(self):
            return self.__name
        
        @name.setter
        def name(self, name):
            self.__name = name
        
        @property
        def sex(self):
            return self.__sex
        
        @sex.setter
        def sex(self, sex):
            self.__sex = sex
            
        #####
        # too much getter, setter #
        # let's skip the rest.
        

define e = Character('아이린', color="#c8ffc8")


# 여기에서부터 게임이 시작합니다.
label start:

    python:
        test_sar = TestCharacter()
        sar_getter = Connection(2)
        test_sar.id = sar_getter.py_data['charId']
        test_sar.name = sar_getter.py_data['charName']
        test_sar.sex = sar_getter.py_data['charSex']

        sar_getter.close_connection()

    e "Let's check whether db connection is successful or not."

    $ name = test_sar.name
    $ char_id = test_sar.id
    $ sex = test_sar.sex

    e "이름 : [name] 아이디 : [char_id] 성별 : [sex]"

    e "Great!"

    return

screenshot0002.png
It works!

Thank you for paying attention!

I'm not sure database connection is necessary for renpy project. But in this way, we can avoid hard-coding, I guess.

Thank you.


Love&Peace
Regular
Posts: 52
Joined: Wed Dec 17, 2014 8:19 pm
Contact:

Re: [Renpy] Connect to MySQL with Spring Boot

#3 Post by Love&Peace »

Andredron wrote: Thu Jan 23, 2020 5:10 am Thank!

https://github.com/saiffyros/Renpy-MySQL
Oh, someone had already done lol

Post Reply

Who is online

Users browsing this forum: No registered users